Vue入门——WebApi
- vue3项目搭建
- 组合式API
- 响应式API
- reactive()
- ref()
- 生命周期钩子
- computed计算属性函数
- watch监听函数
- 父子通信
- 模板引用
- 组合选项
vue3项目搭建
简单看下Vue3的优势吧
下载安装npm及node.js16.0以上版本(确保安装成功可用如下代码检查版本)
npm -v
node -v
下一步创建vue3项目,输入项目名字后并进行选择插件(可以直接回车全部no)
npm init vue@latest
然后找到项目用vsCode打开,并进行初始化
npm install
初始化完成后,把项目跑起来,可点击链接进行查看,看到如下画面就完成咯
npm run dev
组合式API
响应式API
reactive()
接收一个普通对象然后返回该普通对象的响应式代理(众所周知括号里的内容一般才是最重要的,没错,reactive只能封装对象类型的参数)
🍊个🌰:
<script setup>
//1、导入函数
import { reactive } from 'vue';
//2、执行函数,传入一个对象类型参数,用变量接收
const state = reactive({
count: 0 //参数是常规对象,不会引起视图更新
})
//使用reactive函数包装后,会变成响应式对象
const addCount = () => {
state.count++
}
const state2 = {
count2: 0 //参数是常规对象,不会引起视图更新
}
const addCount2 = () => {
state2.count2++
}
</script>
<template>
<div>
<button @click="addCount" id="btn1">{{ state.count }}</button>
<!--这个按钮中的参数被reactive包裹,会被视图响应-->
<button @click="addCount2" id="btn2">{{state2.count2}}</button>
<!--这个参数没有被包裹不会响应-->
<!--但是会累积点击,在下一次点击第一个按钮时会被响应,一次性累计添加-->
</div>
</template>
ref()
接受一个参数值并返回一个响应式且可改变的 ref 对象。(找不同咯,对没错,ref()支持任何类型的参数对其进行封装)
<script setup>
//1、导入函数
import { ref } from 'vue';
//2、执行函数,传入一个参数(简单类型与对象类型均可),用变量接收
const count = ref(0)
const addCount = () => {
//脚本区域修改ref产生的响应式对象,必须通过.value属性修改
count.value++
}
const person = ref({
name: '芋头'
})
const setPerson = () => {
person.value.name = '一哑7'
}
</script>
<template>
<div>
<button @click="addCount">{{ count }}</button>
<!--点击button数字添加-->
</div>
<div>
<button @click="setPerson">{{ "这个人是" + person.name }}</button>
<!--点击button修改人名-->
</div>
</template>
冷知识:ref函数内部实现时依赖reactive函数,一般使用ref更多
生命周期钩子
先来看一张图熟悉一下api
详细的生命周期API使用请参考Vue3官网API介绍
生命周期函数:引入函数后执行并传入回调,会自动执行回调 多次执行生命周期函数时,回调会依次执行
<script setup>
//引入函数
import { onMounted } from 'vue'
//执行函数并传入回调
onMounted( () => {
console.log('执行回调~')
console.log('执行回调~')
})
//多次执行函数时依次执行
onMounted( () => {
console.log('执行回调2~')
console.log('执行回调2~')
})
</script>
computed计算属性函数
<script setup>
//1、导入函数
import { ref , computed } from 'vue';
let list = ref([1 , 2 , 3 , 4 , 5 , 6 , 7 , 8])
//2、执行函数;return经过计算的值;用变量接受这个值
const computedList = computed(() => {
return list.value.filter(item => item > 2)
})
//计时器观察实时更新
setTimeout(() => {
list.value.push(-1 , 10 , 12 , 0)
} , 3000)
</script>
<template>
<div>
{{`原始数组是:[${list}]`}}
</div>
<div>
{{`新数组是:[${computedList}]`}}
</div>
</template>
watch监听函数
- 监听单个数据:
watch需要两个参数,第一个参数是需要监听的数据,第二个参数是在所需要监听的数据发生变化时所需要执行的回调函数。
<script setup>
//1、导入函数
import { ref , watch } from 'vue';
//2、设置需要监听的数据和回调函数
const count = ref(0)
const setCount = () => {
count.value++
}
//3、watch监听单个数据
watch(count , () => {
alert('哦豁,变了哦')
})
</script>
<template>
<div>
<button @click="setCount">{{count}}</button>
</div>
</template>
- 监听多个数据:
这时只需要用数组把需要监听的数据封装起来就好了
<script setup>
//1、导入函数
import { ref , watch } from 'vue';
//2、设置需要监听的数据和回调函数
const count = ref(0)
const setCount = () => {
count.value++
}
const name = ref('芋头')
const setName = () => {
name.value = '一哑7'
}
//3、watch监听多个数据,用数组把需要监听的数据封装起来就好了
watch([count , name] , ([newCount , newName] , [odlCount , oldName]) => {
alert('哦豁,变了哦' + [odlCount , oldName] + '变成了' + [newCount , newName] )
})
</script>
<template>
<div>
<button @click="setCount">{{count}}</button>
<button @click="setName">{{name}}</button>
</div>
</template>
不要忘了关于watch还有两个参数哦,immediate:立即执行;deep:深度监听
- immediate : 在第一次刚刚监听到的时候就先执行一次
<script setup>
watch(count , () => {
alert('变了哦')
} , {
immediate: true}
)
</script>
- deep :通过watch监听的ref对象默认浅层监听,直接修改嵌套对象都不会出发回调函数,此时便需要开启deep
没理解?把下面代码复制下来删掉deep对比一下就知道咯
<script setup>
watch(name , () => {
alert('变了哦')
} , {
deep: true
}
)
</script>
- 精确监听:监听多个属性中的一个属性(deep会有性能损耗建议不开启deep而是使用精确监听)
只需要把watch函数的参数变成两个回调函数,第一个是需要监听的东西,第二个是监听到之后需要执行的回调函数
🍊个🌰:
<script setup>
import { ref, watch } from 'vue'
const state = ref({
name: '芋头',
age: 22,
sex: '男'
})
const chanheName = () => {
//修改姓名
state.value.name = '一哑7'
}
const changeAge = () => {
//修改年龄~
state.value.age = 23
}
const changeSex = () => {
//去一趟泰国
state.value.sex = '女'
}
//精确侦听具体属性
watch(
() => state.value.age,
() => {
console.log('长大一岁了哦')
}
)
watch(
() => state.value.name,
() => {
console.log('还顺路改了个名字')
}
)
</script>
<template>
<div>
<div>这个人现在的名字:{{state.name}}</div>
<div>这个人现在的年龄:{{state.age}}</div>
</div>
<div>
<button @click="chanheName">修改姓名</button>
<button @click="changeAge">修改年领</button>
</div>
</template>
父子通信
父传子:在子组件中用defineProps接收父组件中绑定的数据就好了
//父亲页
<template>
<div>
I am dadTest
</div>
<div>
<sonTest />
</div>
<div>
父传子
<!-- 父亲上绑定属性 -->
<sonTest message="father Data" />
</div>
</template>
<script setup>
import sonTest from './views/sonTest.vue';
</script>
//儿子页
<template>
<div>
I am sonTest {{message}}
</div>
</template>
<script setup>
//用defineProps接收数据就好了
defineProps({
message: String
})
</script>
子传父:父组件通过@绑定事件,子组件内部通过defindEmits函数生成emit方法触发事件
defindEmits 传递参数是数组哦~,因为可传递所有绑定事件
//儿子页
<template>
<div>
<button @click="sendMsg">点击按钮查看来自子组件的信息</button>
</div>
</template>
<script setup>
//利用defindEmits函数生成emit方法
const emit = defineEmits(['giveMeMessqge'])
const sendMsg = () => {
//出发绑定事件
emit('giveMeMessqge' , '儿子消息')
}
</script>
//父亲页
<template>
<div>
<sonTest @giveMeMessqge="getMessage"/>
</div>
</template>
<script setup>
import sonTest from './views/sonTest.vue';
const getMessage = (msg) => {
alert(msg)
}
</script>
模板引用
默认情况下<script setup>语法糖下组件内部的属性与方法不对父组件开放,可以通过defineExpose编译宏指定哪些属性和方法允许访问
//子组件
<template>
<div>
Test 组件
</div>
</template>
<script setup>
import { ref } from 'vue';
const name = ref('nameTest')
const setName = () => {
name.value = 'newNameTest'
}
// defineExpose({
// name,
// setName
// })
</script>
//父组件
<template>
<div>
<!-- 用ref标识绑定ref对象 -->
<h1 ref="h1Ref">dom标签h1</h1>
<sonTest ref="sonRef"/>
</div>
</template>
<script setup>
import sonTest from './views/sonTest.vue';
import { ref , onMounted } from 'vue'
//调用ref函数生成ref对象当然组件也是可以的
const h1Ref = ref(null)
const sonRef = ref(null)
//不过要注意在获取对象时要等组件挂在完毕哦,可以使用
onMounted(() => {
alert(h1Ref.value)
alert(sonRef.value)
})
</script>
组合选项
顶层组件向任意底层组件传递参数和方法,实现跨层组件通信顶层组件通过provide函数提供数据,底层组件通过inject函数获取数据
跨层传递普通数据:
跨层传递响应式数据:
跨层传递方法:顶层组件可以向底层组件传递方法,底层组件调用方法修改顶层组件中的数据