Vue3学习第二天

84 阅读1分钟

五、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代码段"
    }
  }