ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## setup(props,context)中的参数 * setup执行时机,在beforeCreate()生命周期函数之前,并且this===undefined * props接收父组件传递数据 如果父组件传递数据,子组件不定义props接收,则回报警告,反之,子组件定义props,父组件不传递,则子组件值为undefined; 子组件接收的值,则被加工成代理对象,即是响应式数据。 * context事件参数(上下文对象) attrs:当父级传递数据,存放props中未声明接收的变量,相当于Vue2.x中的$attrs; emit:事件传递,相当于Vue2.x中的$.emit(),不同之处在**Vue3.x中需要emits:['事件名']**,声明一下,和props声明变量功能类似,当然不声明也不影响使用,就是会出现警告! slot:不陌生,就是插槽,存在一些小差异: ``` html // 写法一: <Demo> <span>父级内容</span> </Demo> // 写法二: <Demo> <template slot="header"> <span>父级内容</span> </template> </Demo> ``` 以上写法,context.slot都是默认插槽,看不到插槽名称为header的内容,与Vue2.x不同之处,或者说一些框架向下兼容问题。 ``` html <Demo> <template v-slot:header> <span>父级内容</span> </template> </Demo> ``` 通过`v-slot:header`写法,则正常,推荐该写法。 ## 计算属性computed * Vue2.x中写法 ``` js computed: { demo(){ return this.xxx*100 } } ``` * 搬到Vue3.x也可以使用,但是不建议这样混合使用 在Vue3.x中,通过`import {reactive,computed} from 'vue'`,接下来: ```js setup(){ let p = reactive({ xxx: 10 }) // computed默认写法 p.demo = computed(()=>{ return p.xxx*100 }) return { p } } ``` * 在这里对computed扩展一下(完整写法),和Vue2.x其实一样的 ``` js 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'` ```js setup(){ let sum = ref(100) // 基本类型 watch(sum,(newVal,oldVal)=>{ console.log(newVal,oldVal)) },{ // 第三个参数,配置项 // immediate: true, // deep: true // 其实被强制开启,改成false也无效,下面会有两种情况可以起作用 }) return { sum } } ``` * 可以写多个watch(sum1,()=>{}),但是Vue3.x提供数组写法 ``` js 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,()=>{})的形式即可。 ```js setup(){ let sum = reactive({ count: 100 }) // 基本类型 watch(sum,(newVal,oldVal)=>{ console.log(newVal,oldVal)) // newVal,oldVal这两对象中的count是相等的,目前无法解决 }) return { sum } } ``` ### 下面正式进入监听的一些实现方式 * 监听对象某一个属性,可以如下: ```js let p = reactive({count: 200}) watch(()=>p.count,(nVal,oVal)=>{ // 干点啥 }) ``` * 监听对象多个个属性,可以如下: ```js let p = reactive({count: 200,total: 5000}) watch([()=>p.count,()=>p.total],(nVal,oVal)=>{ // 干点啥 }) ``` * 监听相应数据对象中的对象,**deep:true就起作用**了,可以如下: ```js 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}) ``` ![](https://img.kancloud.cn/7a/67/7a67be42eb4b6b49993631242ec39464_584x265.png) ### watchEffect函数 与watch不同,watchEffect不用指明艰难听那个属性,而是在回调函数中使用到那个属性,则那个属性被监听了,和computed有点类似,但注重点不一样: computed:计算出来的返回值,而且必须写返回值; watchEffect:注重函数体,注重里边使用了哪些属性,并且不用写返回值。 ``` js // import { watchEffect } from "vue" let p = reactive({count:1}) watchEffect(()=>{ // 只要使用到p.count,则就会执行该函数体 }) ``` watch基本应该整理完成了。