Vue3新操作
computed:基本和Vue2没太大改变
computed
不再是对象,而是一个函数,需要导入才能用- 可以直接添加为
reactive
生成的对象中
import {reactive,computed} from 'vue'
setup(props,context) {
let person = reactive({
firstName:'连',
secondName:'颜少',
})
// 只读的写法,如果修改则会警告
person.fullName = computed( () => {
return person.firstName + person.secondName
})
// 完整写法
person.fullName = computed({
get: function() {
return person.firstName + person.secondName;
},
set: function(value) {
//value为获取到修改的新值
}
})
return {
person
}
}
watch
warch
不再是对象,而是一个函数,需要导入才能用- 可以直接添加为
ref
,reactive
生成的对象或者是数组
,而不监听对象内部的单独属性(person.money
这种写法在Vue2
中可以,在Vue3
中需要写成函数的返回值()=>person.money
) - 可以写多个
watch
- 一个
watch
监听多个,这样返回的newValue
和oldValue
都会返回数组· - 当监听
reactive
对象的时候,返回的oldValue===newValue
,获取不到真实的oldValue
watch
第三个参数是配置有immediately
,deep
,但是deep
不生效,强制开启,跟Proxy
的原理有关系
import {ref,reactive,watch} from 'vue'
setup(props,context) {
let person = reactive({
name:'连颜少',
money:1000000,
job:{
job1:{
salary:20
}
}
})
let num1 = ref(500)
let num2 = ref(600)
// 写法1
watch(num1,(newValue,oldValue) => {
console.log('num1',newValue,oldValue)
// result:num1 501 500
})
// 写法2:监听多个
watch([num1,num2],([newnum1,newnum2],[oldnum1,oldnum2]) => {
console.log('num1,num2',newValue,oldValue)
// result: num1,num2, [501, 600] ,[500, 600]
})
// 写法3:监听对象
watch(person,(newValue,oldValue) => {
console.log('person',newValue,oldValue)
// 这时候由于对象是引用类型数据,无法返回oldValue的值,newValue === oldValue
})
// 写法4:监听对象内的单独属性
watch(()=>person.money,(newValue,oldValue) => {
console.log('person.money',newValue,oldValue)
// result: 1000001 , 1000000
})
// 写法5:监听对象内的多个单独属性 和 ref的值 (这里的num1需要加上.value)
watch(()=>[person.money,person.name,num1.value],(newValue,oldValue) => {
console.log('person',newValue,oldValue)
})
// 写法6-1,兄弟们,最骚的地方来了:监听reactive里面的基本类型数据不行,监听对象却可以
watch(person.job,(newValue,oldValue) => {
console.log('person',newValue,oldValue)
// 这样写反而可以了
})
// 写法6-2,还有另外一种函数返回值的写法可以监听对象中的对象,但是需要用上第三个属性 deep
watch(()=>person.job,(newValue,oldValue) => {
console.log('person',newValue,oldValue)
// 这样写也可以
},{deep:true})
return {
person,num1,num2
}
}
总结的来说就是:
- 1.可以监听单个
ref
基本类型, - 2.可以监听多个
ref
基本类型, - 3.可以监听多个
reactive
对象(默认deep:true
), - 4.不可以直接监听
reactive
对象里面的基本类型需要转化为返回函数(()=>person.money
), - 5.可以直接监听
reactive
对象里面的 对象,好像有点绕? - 6.也可以用返回函数去监听对象里面的对象,但是这时候需要设置
deep:true
(这种写法多此一举) - 7.用返回函数的方法去监听
ref
的基本类型,需要.value
(但是这么写的多少脑子有点问题吧,除非和其他数据一起监听需要)
watchEffect(callback):监听回调函数内的所有属性,当一个发生变化,则重新执行回调函数
你可能会说,这特么不就是computed吗?还是有一点点区别:
computed
需要返回值,重点在最终返回的内容watchEffect
没有返回值,重点在执行的过程
生命周期:
- 可以但是不精确的描述就是:
-
- 删除了
beforeCreated
和created
(其实没删除,并且用Vue2
写法依然可以,只是整合到setup
里面了)
- 删除了
- -
beforeDestory
和destoryed
更名为beforeUnmount
和unmounted
- 笔者这边建议还是用
Vue2
的写法,写在setup
外面,分清每个生命周期,全写在setup
里面显得太臃肿
hook:类似mixins,封装数据的方法,返回需要的内容,在需要的页面按需引入~
toRef 和 toRefs
toRef
:把一个对象内的属性,变成ref
类型的值toRefs
:对象内的所有属性逐个解析,变成ref
的值(这个就好用了)
setup() {
let data = reactive({
person: {
name:'连颜少',
age:18,
job:{
name:'front-end',
salary:20
}
}
})
return {
...toRefs(data)
}
}
// 第一篇我们讲过,把整个数据用reactive封装成data,这样模板里直接就用data.xxx属性,但是这样还是得多写个data,不妨就用上toRefs,就可以省去data,直接使用内部的值了,看起来就跟Vue2一样了
shallowReactive 和 shallowRef
shallowReactive
:只监听对象的第一层,第一层实现响应式shallowRef
:判断是否为对象,如果是对象,则不监听。这边建议与Ref
相比,用shallowRef
更好,直接拒绝了实现Ref
传入对象的情况
readonly 和 shallowReadoly
readonly
将数据变为只可读(深层次都不允许修改)shallowReadoly
将数据的最外一层标记为只可读
toRow:顾名思义,就是把Vue封装的refImpl或者Proxy数据,返回为原生数据类型
markRow:将一个对象标记为原生,无法被ref和reactive给转化为响应式
customRef(callback(track,trigger)):自定义Ref,可以定义一些ref中的个性化操作
// 写个lazy绑定的例子:
setup() {
let name = selfRef('连颜少')
function selfRef(value) {
let timer
return customRef((track,trigger) => {
return {
// customRef需要返回值,并且一定要定义get和set方法
get() {
track() // 追踪值的变化
return value //返回获取到的值
},
set(newValue) {
clearTimeout(timer) // 个性化设置:防抖半秒,清除定时器
timer = setTimeout( ()=> {
value = newValue // 将设置的新值,赋值给返回值
trigger() // 触发模板重新解析
},500)
}
}
})
}
}
结语
下一篇会继续分析:Vue2
和Vue3
中 Fragment组件
,Teleport组件
和Suspense组件
等...
如果你觉得此文对你有一丁点帮助,点个赞,给我一点儿鼓励哈~
更多精彩: