「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。
setup(props,context)中的参数
- setup执行时机,在beforeCreate()生命周期函数之前,并且this===undefined
- props接收父组件传递数据
如果父组件传递数据,子组件不定义props接收,则回报警告,反之,子组件定义props,父组件不传递,则子组件值为undefined;
子组件接收的值,则被加工成代理对象,即是响应式数据。 - context事件参数(上下文对象)
attrs:当父级传递数据,存放props中未声明接收的变量,相当于Vue2.x中的.emit(),不同之处在Vue3.x中需要emits:['事件名'] ,声明一下,和props声明变量功能类似,当然不声明也不影响使用,就是会出现警告!
slot:不陌生,就是插槽,存在一些小差异:
// 写法一:
<Demo>
<span>父级内容</span>
</Demo>
// 写法二:
<Demo>
<template slot="header">
<span>父级内容</span>
</template>
</Demo>
以上写法,context.slot都是默认插槽,看不到插槽名称为header的内容,与Vue2.x不同之处,或者说一些框架向下兼容问题。
<Demo>
<template v-slot:header>
<span>父级内容</span>
</template>
</Demo>
通过v-slot:header写法,则正常,推荐该写法。
计算属性computed
- Vue2.x中写法
computed: {
demo(){
return this.xxx*100
}
}
- 搬到Vue3.x也可以使用,但是不建议这样混合使用
在Vue3.x中,通过import {reactive,computed} from 'vue',接下来:
setup(){
let p = reactive({
xxx: 10
})
// computed默认写法
p.demo = computed(()=>{
return p.xxx*100
})
return {
p
}
}
- 在这里对computed扩展一下(完整写法),和Vue2.x其实一样的
p.demo = computed({
get(){
return p.xxx*100
},
当计算组合值被修改,则通过代理对象修改源数据
set(value){
// value接收修改的值,在这里可以干点啥
p.xxx = value/100
}
})
watch监听:watch(监听对象或者函数,fn,option)
- Vue3.x的监听属性用法有些不同,在使用之前肯定先引入
import { watch,ref,reactive } from 'vue'
setup(){
let sum = ref(100) // 基本类型
watch(sum,(newVal,oldVal)=>{
console.log(newVal,oldVal))
},{
// 第三个参数,配置项
// immediate: true,
// deep: true // 其实被强制开启,改成false也无效,下面会有两种情况可以起作用
})
return { sum }
}
- 可以写多个watch(sum1,()=>{}),但是Vue3.x提供数组写法
watch([sum,sum1],(newVal,oldVal)=>{
//newVal,oldVal 也是数组,值对应前面箭筒数组的值
})
通过reactive定义,存在坑,oldVal对象中的count是不正确的,目前无法解决
通过let p = ref({});watch(p.value,(n,o)=>{}),也是不能解决,要清楚ref()中传入一个对象,最后还是走reactive的,所以根源就在于reactive的实现上。
注:1、实在需要count的新旧数据,可以单独出来当做一个基本类型定义即可;
2、也可以通过函数的方式watch(()=>p.count,()=>{})的形式即可。
setup(){
let sum = reactive({
count: 100
}) // 基本类型
watch(sum,(newVal,oldVal)=>{
console.log(newVal,oldVal)) // newVal,oldVal这两对象中的count是相等的,目前无法解决
})
return { sum }
}
下面正式进入监听的一些实现方式
- 监听对象某一个属性,可以如下:
let p = reactive({count: 200})
watch(()=>p.count,(nVal,oVal)=>{
// 干点啥
})
- 监听对象多个个属性,可以如下:
let p = reactive({count: 200,total: 5000})
watch([()=>p.count,()=>p.total],(nVal,oVal)=>{
// 干点啥
})
- 监听相应数据对象中的对象,deep:true就起作用了,可以如下:
let p = reactive({
count: 200,
type:{ name: '张三' }
})
watch(()=>p.type,(nVal,oVal)=>{
// 干点啥
},{deep: true})
- 通过ref定义引用类型注意问题
通过ref定义引用类型,注意监听的是需要响应式对象数据的存放的容器,故兼容p.value或通过deep:true开启深度监听。
let p = ref({name: '张三',age: 18,job:{//...}})
console.log(p)
watch(p.vaule,(nVal,oVal)=>{})
watch(p,()=>{},{deep: true})
watch基本应该整理完成了。