五、ref方法的几种使用方式
5.1、ref方法(操作基本类型数据)
02-App.vue文件中:
<template>
<div>
<p>{{num}}</p>
<button @click="hdClick">按钮</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from "Vue"
export default defineComponent({
setup(){
// 什么时候执行,页面一刷新的时候
console.log("setup");
let num = 20;
const hdClick = ()=>{
num++
console.log(num);
}
// 数据和方法都需要导出才能实现
return {
num,
hdClick
}
}
})
</script>
但只是上面的写法并没有,num并不是响应式数据。Vue3提供了ref方法
<template>
<div>
<p>{{num}}</p>
<button @click="hdClick">按钮</button>
</div>
</template>
<script lang="ts">
import { defineComponent, ref} from "Vue"
export default defineComponent({
setup(){
let num = ref(20);
console.log(num); // 直接访问是一个被包装过的数据
const hdClick = ()=>{
num.value++; // 通过.value才能操作到数据。
// 但模板上只需要{{num}}不需要,因为Vue3在模板编译阶段会把响应式数据num直接通过.value去获取。所以模板不需要改变
}
return {
num,
hdClick
}
}
})
</script>
5.2、ref方法(操作复杂类型数据)
<template>
<div>
<p>{{obj.num}}</p>
<button @click="hdClick">按钮</button>
</div>
</template>
<script lang="ts">
import { defineComponent, ref} from "Vue"
export default defineComponent({
setup(){
let obj = ref({
num:30
});
const hdClick = ()=>{
obj.value.num++;
}
return {
obj,
hdClick
}
}
})
</script>
5.3、ref方法获取标签
在模板上通过ref绑定标签,setup中通过ref();来获取
<template>
<div>
<p ref="count">p标签</p>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted,nextTick } from "Vue"
export default defineComponent({
setup(){
let count = ref(); // 这里拿到的是ref绑定为count的节点数据
console.log(count.value); // setup生命周期还没有节点挂载
onMounted(()=>{
console.log("onMounted", count.value); // 挂载后就可以通过.value拿到节点
})
nextTick(()=>{
console.log("nextTick", count.value); // 下一次dom更新后会触发的回调(只会触发1次)
})
return {
count
}
}
})
</script>
六、reacttive方法和toRefs方法
reactive用来实现复杂数据类型的响应式
<script lang='ts'>
import { defineComponent , ref, reactive} from "Vue"
export default defineComponent({
setup () {
// 用ref实现基础数据类型的响应式,reactive实现复杂数据类型的响应式
// 如果ref传入的是一个复杂数据,那么最后ref方法内部会调用到reactive
//objRef.value和obj2Reactive一样
let obj = {
num:20
}
let objRef = ref(obj);
console.log(objRef.value);
let obj2 = {
num:20
}
let obj2Reactive = reactive(obj2);
console.log(obj2Reactive);
return {
}
}
})
</script>
toRefs方法用来把reactive()处理过的数据处理成响应式结构出来:
<template>
<!-- toRefs方法 -->
<div>
<p>{{num}}</p>
<button @click="num++">按钮</button>
</div>
</template>
<script lang='ts'>
import { defineComponent , ref, reactive, toRefs} from "Vue"
export default defineComponent({
setup () {
let obj2 = {
num:20
}
// 结构数据,需要通过toRefs方法处理,结构出来的数据出来的才是响应式数据
let {num} = toRefs(reactive(obj2));
console.log(num);
return {
num
}
}
})
</script>
七、setup语法糖
之前写的setup语法糖其实可以简写:
<template>
<div>
<p>{{num}}</p>
<button @click="num++">按钮</button>
</div>
</template>
<script lang='ts' setup>
import { reactive,toRefs } from "Vue"
let obj = reactive({
num:9
})
let {num} = toRefs(reactive(obj))
</script>
八、watch属性和watchEffect属性
watch属性和watchEffect属性都可以用于监听,watch写法上支持一个或者多个监听源,这些监听源必须只能是getter/effect函数,ref数据,reactive对象,或者是数组类型
<template>
<!-- watch 监听复杂类型数据 -->
<div>
<p>{{objRet.num}}</p>
<button @click="objRet.num++">按钮</button>
</div>
</template>
<script lang='ts' setup>
import { reactive,watch,watchEffect } from "Vue"
interface ObjItf{
num:number
}
let obj ={
num:50
}
let objRet = reactive<ObjItf>(obj);
// 监听的格式应该写成:()=>objRet.num
/* watch(()=>objRet.num,(newVal,oldVal)=>{
console.log(newVal,oldVal);
});
*/
/* 或者下面这种格式 */
watch([()=>objRet.num],(newVal,oldVal)=>{
console.log(newVal,oldVal);
})
/* watchEffect自带立即监听的效果 */
watchEffect(() => {
// 当这个函数里面用到的值发生变化的时候就会 自动执行这个函数
console.log(objRet.num);
});
</script>
九、Computed属性
计算属性作用和以前一样,格式也换成调用方法:
<template>
<!-- computed计算属性 -->
<div>
<p>{{dbnum}}</p>
<button @click="num++">按钮</button>
<p>{{dbnum2}}</p>
<button @click="objRet.num++">按钮2</button>
</div>
</template>
<script lang='ts' setup>
import { reactive,computed,ref } from "Vue"
let num = ref(20);
let dbnum = computed(()=>{
return num.value*2
})
// -------------------------------
let obj = {
num:10
}
let objRet = reactive(obj);
let dbnum2 = computed(()=>{
return objRet.num*3
})
</script>
代码片段设置
完整版:
{
"demo": {
"prefix": "v3",
"body": [
"<template>",
"\t<div>",
"\t\t",
"\t</div>",
"</template>",
"",
"<script lang='ts'>",
"import { defineComponent } from "Vue"",
"export default defineComponent({",
"\tsetup () {",
"\t\t$0",
"\t\treturn {\n",
" ",
"\t\t}",
"\t}",
"})",
"</script>",
" ",
"<style lang = "less" scoped>",
"\t",
"</style>"
],
"description": "自定义的一个vue代码段"
}
}
简写版:
{
"demo": {
"prefix": "v3",
"body": [
"<template>",
"\t<div>",
"\t\t",
"\t</div>",
"</template>",
"",
"<script lang='ts' setup>",
"import { } from "Vue"",
"\t$0",
"</script>",
" ",
"<style lang = "less" scoped>",
"\t",
"</style>"
],
"description": "自定义的一个vue代码段"
}
}