在vue2中,data函数里返回的值直接为响应式的,但在vue3中我们需要使用一些函数才能达到这个效果。
setup函数中拿不到vue的this
1、ref?
本质为一个函数,输入参数为一个值(原始类型),返回响应式的对象
2、computed
本质为一个函数,输入参数是一个函数,可以将我们需要的值作为输入函数的返回值
例子:实现点击按钮,屏幕上的数加1
<template>
<div id='app'>
<img alt="vue logo" src="./assets/logo.png">
<!-- ref对象在模板中引用时,vue可以直接把内部的值展示出来,不需要写count.value -->
<h1>{{count}}</h1>
<h1>{{double}}</h1>
<button @click='increase'>点击</button>
</div>
</template>
<script lang='ts'>
//ref API:是一个函数,输入参数为一个值,返回一个响应式对象
//computed API:是一个函数,输入参数为函数类型,该输入函数中包含咱们需要的值
//reactive:将响应式变量包裹在一起,更加清晰
import {computed, ref,reactive} from 'vue'
export default({
name: 'App',
/*data(){
return{
count: 0
}
},
methods:{
increase(){
this.count++
}
}*/
// 注意:在vue3中不使用data和methods,可以使用ref函数,完成响应式
setup(){
const count = ref(0) //将0传入,返回一个对象
const double = computed(()=>{
return count.value*2
})
const increase = ()=>{
count.value++ //通过返回对象的value属性获得响应式的数据
}
return{ //要在外面使用的变量都要先通过return导出,才能使用
count,
increase,
double
}
}
});
</script>
3、reactive
本质为一个函数,接受一个object作为传入参数
上述代码在setup函数中,有很多响应式数据,它们都是分散的,我们可以使用reactive将它们都包裹起来。输出对象类型,模板中需要用data.属性取出来。
<template>
<div id='app'>
<img alt="vue logo" src="./assets/logo.png">
<h1>{{data.count}}</h1>
<h1>{{data.double}}</h1>
<button @click='data.increase'>点击</button>
</div>
</template>
<script lang='ts'>
import {computed, ref,reactive} from 'vue'
export default({
name: 'App',
// 注意:在vue3中不使用data和methods,可以使用ref函数,完成响应式
setup(){
const data = reactive({
count:0,
increase:()=>{
data.count++
},
double:computed(()=>
data.count*2
)
})
return{ //要在外面使用的变量都要先通过return导出,才能使用
data
}
}
});
</script>
上述代码在运行时会报错,data数据类型会出错,这是因为内部的computed函数造成的data类型推论循环,需要解决。可以手动设置一个数据类型赋给data。
interface dataProps{
count:number,
double:number,
increase:()=>void
}
继续修改上述代码,发现模板中每次使用数据都需要data.属性才能取出来,能不能直接用属性?这时我们想到了es6的...展开符,但是更改后发现点击按钮,屏幕上的数字不发生变化了,数据不是响应式的了。
这是因为这种方式返回的数据都是普通的js数据类型,并不是响应式的ref数据类型,因此我们需要新的方法。
4、toRefs
本质为一个函数,接受一个reactive函数作为输入参数,返回一个ref类型的对象。
<template>
<div id='app'>
<img alt="vue logo" src="./assets/logo.png">
<!-- ref对象在模板中引用时,vue可以直接把内部的值展示出来,不需要写count.value -->
<h1>{{count}}</h1>
<h1>{{double}}</h1>
<button @click='increase'>点击</button>
</div>
</template>
const refData = toRefs(data)
return{ //要在外面使用的变量都要先通过return导出,才能使用
...refData
}
这时,我们展开refData,就能实现响应式了。
|