vue3.0的setup函数以及解决其内的数据不是响应式数据的问题

相比于2.0,vue3.0在新增了一个setup函数,我们在setup中可以写数据也可以写方法,就像我们以前最开始学习js一样,在js文件中写代码。

如:

 setup() {
            let name1="张三"
            let age=20
            let fn=()=>{
                console.log("setup内的方法");
            }
        }

我们在setup内写的代码,想要在template模板中使用的话,就要return 我们写的数据。

如,我们要在模板中使用name1,fn时,首先就要将其放在对象中,然后return {name1,fn}

代码:

<template>
    <div id="box">
        <p>{
   
   {name1}}</p>
        <button @click="fn">点击打印</button>
    </div>
</template>
<script>
    export default{
        setup() {
            let name1="张三"
            let age=20
            let fn=()=>{
                console.log("setup内的方法");
            }
            return {name1,fn}
        }
    }
</script>

 页面效果:

 由此可以看出,我们不需要在data写数据也不用在methods内写方法了,都可以直接写在setup内。

总结一下:

1.这个函数内部的变量/函数是局部的;

 2.如果想要使用其的数据或函数,需要return出来,这个就好比我们学的闭包。这个函数的返回值 可以被当前组件的任意地方使用;

3、但是函数内不可以使用外部的数据或函数,即setup内不能使用this。

4、setup返回的对象中的数据和data中的数据同名了 setup优先级更高

5.setup在组件加载期间 只会运行一次

setup还有一个语法糖,直接在script标签行内写setup。整个script标签内就变成setup函数内的环境,在打包工具打包时  直接帮我们把标签内部声明的变量/函数return出来(我们就不需要手动return了),然后组件的任何地方就可以使用了。

改变代码:

<template>
    <div id="box">
        <p>{
   
   {name1}}</p>
        <button @click="fn">点击打印</button>
    </div>
</template>
<script  setup>
            let name1="张三"
            let age=20
            let fn=()=>{
                console.log("setup内的方法");
            }
</script>

但是有一个缺点,就是setup内的数据供页面使用时并不是响应式。当我们修改了数据后,setup的数据会发生改变,但是并不会渲染到页面上。

验证一下:设计一个函数修改年龄,当我们点击按钮后触发这个函数,看一下页面是否会被从新渲染。

代码:

<template>
    <div id="box">
        <p>{
   
   {name1}}--{
   
   {age}}</p>
        <button @click="changeage">修改年龄</button>
    </div>
</template>
<script setup>
    let name1="张三"
    let age=20
    console.log(age);//初始渲染到页面时打印年龄
    let changeage=()=>{
        age=30
        console.log("修改后的年龄",age);
    }
</script>

效果:

 

 可以看到修改年龄的函数已经触发了,并且age雀氏已经被修改了,但是页面还是显示20.

因此官方给我们提供了两个工具(ref和reactive)解决。

ref和reactive

这里的ref跟前面学习的$ref绑定组件或元素节点没有关系,它就是一个工具函数。

用法:首先导入这个函数import {ref} from "vue",然后把数据放在ref()内,即可实现响应式数据。ref()后返回的是一个对象,我们需要点value才能取到我们的数据。

但是在模板中,直接写变量名即可,不用点value

改进上述代码:

<template>
    <div id="box">
        <p>{
   
   {name1}}--{
   
   {age}}</p>
        <button @click="changeage">修改年龄</button>
    </div>
</template>
<script setup>
import {ref} from "vue"
    let name1="张三"
    let age=ref(20)
    console.log(age.value);//初始渲染到页面时打印年龄
    let changeage=()=>{
        age.value=30
        console.log("修改后的年龄",age.value);
    }
</script>

效果:

 reactive用法与与ref相似,但是reactive()后不用点value,一般用于嵌套层级很深的数组或者对象,虽然ref也可以但是不建议。

用reactive处理一个引用数据:


<template>
    <div id="box">
        <p>{
   
   {arr[1].content[0]}}</p>
        <button @click="changec">修改china</button>
    </div>
</template>
<script setup>
import {ref,reactive} from "vue"
    let arr=reactive([{title:"index"},{content:["china","english"]}])
    let changec=()=>{
        arr[1].content[0]="chinese"
        consol.log("修改成功")
    }
 
</script>

点击后的效果:

最后思考一下,ref和reactive的响应式设计是如何实现的?

 ref 就是监听了value的改变,劫持value属性的setter和getter。因此ref一般用在基本数据,或者引用数据的嵌套层级不深的数据上。

而reactive底层采用的是ES6的Proxy代理了整个引用数据.

猜你喜欢

转载自blog.csdn.net/m0_59345890/article/details/126896845