【前端知识点总结】Vue3的新特性 + 组件通信

Vue3

侦听器 watch 函数

watch 函数作用 : 定义侦听器,侦听数据的变化

watch 监听的三个参数

参数1 : 被监听的数据

  • 实参可以直接写需要监听的数据
  • 也可以传入一个函数() => 被监听的数据或者对象的属性
    参数2 : 回调函数
  • 语法 : (NewVal,OldVal) => {}
  • 回调函数也有两个参数
    • NewVal : 修改后的新值
    • OldVal : 修改前的旧值
      参数3 : 额外的配置,是一个对象
  • 对象中的可选属性
    • deep: true : 开启深度监听,用来监听复杂类型的数据(可以直接监听到对象中的属性发生改变)
    • immediate: true : 初次进入立即监听( 不用等到监听的数据发生改变)

watch 函数的 3 种语法

1 . 监听响应式数据的语法

  • watch(响应式数据,处理函数)
    2 . 监听响应式数据 某个属性 的语法
  • watch( () => 对象.属性名, 处理函数)
    3 . 深度监听 的语法
  • watch( () => 对象.属性名,处理函数,{ deep: true, immediate: true })

watch 监听数据的四种写法

注意 : 要监听的数据如果是复杂类型的数据,有四种写法(得到的结果也会不同)

写法1 : 直接写对象(复杂类型)

  setup () {
    var  n=ref(0)
    var obj=reactive({
      id:1,
      name:'rose',
      age:18
    })

     watch(obj,(newVal,oldVal)=>{
       console.log(newVal,oldVal) // 新值 , undefined
     })
     
      const say = () => {
      n.value++
      obj.age++
    
    }

    return {say,n,obj}
  }

结论 :

  • 可以直接监听到属性内部,但是只能获取新值
  • 开启深度监听后,可以获取新旧值

写法2 : 监听是一个函数

     watch( ()=>obj,(newVal,oldVal)=>{
       console.log(newVal,oldVal)//  新值 , undefined
     },{
       deep:true
     })

结论 :

  • 改变对象中的属性不会触发监听器
  • 想触发需要使用深度监听,但是也只能获取到新值

写法3 : 函数写法,监听的是对象中的属性

     watch( ()=>obj.age,(newVal,oldVal)=>{
       console.log(newVal,oldVal) // 新值 , 旧值
     })

结论 :

  • 可以触发,可以获取新旧值

写法4 : 监听对象包在数组中

    watch([obj,n],(newVal,oldVal)=>{
       console.log(newVal,oldVal)// 新值 , undefined
     })

结论 :

  • 那就可以触发,只能获取新值
  • 注意 : 监听对象包裹在数组中的话可以写多个

Vue3 中的生命周期钩子

生命周期函数 vue3 中的生命周期函数, 需要在 setup 中调用

注意 : 使用时都需要先导入

import { onMounted, onUpdated, onUnmounted } from 'vue'

export default {
  setup() {
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
  }
}

optionsAPIcompositionAPI 钩子函数的对比

初始化阶段

此阶段会生成 data
optionsAPI中的两个钩子

  • beforeCreate : 组件初始化前, 此时还没有生成 data (无法获取 data)
  • created : 组件初始化后, 可以获取 data
    compositionAPI 没有 beforeCreatecreated 钩子函数
  • setup() 函数可以就是初始化阶段,执行时机还要在 created 钩子函数之前

挂载阶段

此阶段会挂载真实 DOM
optionsAPI中的两个钩子

  • beforeMount : 组件挂载前, 此时真实 DOM 还有挂载(无法获取真实 DOM )
  • mounted : 组件挂载后, 可以获取真实 DOM
    compositionAPI中的两个钩子
  • onBeforeMount : 组件挂载前
  • onMounted : 组件挂载后

更新阶段

数据改变会触发此阶段,数据改变会重新渲染虚拟 DOM 给真实 DOM 打补丁
optionsAPI中的两个钩子

  • beforeUpdate : 组件更新前, 此时真实 DOM 还有没有更新(无法获取修改后的真实 DOM )
  • updated : 组件跟新后, 可以获取修改后的真实 DOM
    compositionAPI中的两个钩子
  • onBeforeUpdate : 组件更新前
  • onUpdated : 组件挂载后

销毁阶段

使用 v-if 可以触发此阶段,此阶段会清楚定时器和一些全局事件,还有表单中填写的数据
optionsAPI中的两个钩子

  • beforeDestory : 组件销毁前
  • destoryed : 组件销毁后
    compositionAPI中的两个钩子
  • onBeforeUnmount : 组件销毁前
  • onUnmounted : 组件销毁后

Vue3 中 ref 属性的使用

作用 : 用于获取模板中的元素 (真实 DOM 元素或者某个组件对象)

Vue3之前的版本

  • 模板中使用 ref 属性,
  • mounted() 中通过 $refs 获取真实 DOM 元素或者某个组件对象

Vue3 中 ref 的使用

  • 创建一个空的 ref 对象 : const myRef = ref(null)
  • 模板中建立关联 : <h1 ref="myRef">123</h1>
  • onMounted() 钩子函数中使用 : Rref.value
<template>
  <div>
    <h1 ref="myRef">钩子函数-----123</h1>
    <my-demo ref="myDemoRef"></my-demo>
  </div>
</template>

<script>
import MyDemo from './components/my-demo.vue'

import { onMounted, ref } from 'vue'

export default {
  components: {
    MyDemo
  },
  setup () {
    // 创建 ref
    const myRef = ref(null)
    const myDemoRef = ref(null)

    onMounted(() => {
      console.log(myRef.value) // DOM元素
      console.log(myDemoRef.value) // 组件对象
    })
    return {
      myRef,
      myDemoRef
    }
  }
}
</script>

Vue 组件通信

1 . props 传值(父向子)

作用 : 父组件向子组件传值

props 属性中定义数据

语法1 (数组)

  • props : [ '数据名1' , '数据名2' ]
    语法2 (对象)
  • props : { 数据名: { 属性 ...}}
  • 对象语法定义数据时的三个可选属性
    • type : 数据类型(可选值 String / Array… 等)
    • default : 父组件不传值时的默认值
    • required : trueflase ( true 表示父组件必需传值)

简写 :

  • 如果只有类型可以简写为 props : { 数据名: String }

使用 props 属性传值

父组件内 : 在模板的子组件中, 用自定义组件传值

  • 语法 : <组件名 自定义属性名="要传递的数据" />
    子组件内 :props 中定义变量接收数据 , 并在模板中使用
    export default {
      // props: ['自定义属性名'],
      props: {
        自定义属性名: {
          type: Number,
          default: 1
        }
      }
    }  

Vue3 中使用 props 传值

父组件用法不变

子组件内 :

  • props 中定义变量接收数据
  • setup() 函数中使用数据
  • 在模板中展示数据
   export default {
     props: {
       自定义属性名: {
         type: Number,
         default: 1
       }
     },
     //  setup中使用
     setup(props) {
          props.自定义属性名
     }
   }

props 注意点

  • props 用来接收父组件传过来的值
  • props 中使用驼峰形式,模版中要改为使用短横线拼接的格式
  • props 里面的值只读,不能修改
  • props 是单向数据流

2 . $emit 传值(子向父)

父组件内 : 绑定自定义事件,声明事件处理函数用于接收

  • 语法 : <组件 @自定义事件名 = "事件处理函数" />

子组件内 : 使用 $emit 传值, 触发父组件中的自定义事件, 并传值

  • 语法 : this.$emit( 参数1 , 参数2 , 参数3 ... )
  • 参数1 : 父组件中的 自定义事件名
  • 参数2~N : 要传递给父组件中的数据

最后在父组件的事件处理函数中, 以形参的方式接收传递过来的值(可以修改)

Vue3 中的 emit 传值

父组件用法不变

子组件内 :

  • 先使用 emits 接收
    • 语法 : emits[自定义事件名]
  • setup( ) 函数中 , 用形参 context 调用 emit 方法 传递参数
export default {
  emits: ['自定义事件名'],
  setup( context ) {
    const change = () => {
      // 子传父
      context.emit('自定义事件名', 数据 )
    }
    
    return {
      change
    }
  }
}
</script>

3 . .sync修饰符传值

作用 : 修饰 props 的传值, 使其不再是单向数据流, 可以在子组件中修改父组件传递过来的数据

语法 :

  • 父组件内 : <组件名 自定义属性名.sync = "要传递的数据" />

  • 子组件中 : 先在props中接收, 再使用 $emit("update:自定义属性名", 修改后的属性值) 修改值

    • 需要使用 update 关键字
 export default {
      // props: ['自定义属性名'],
      props: {
        自定义属性名: {
          type: Number,
          default: 1
        }
      },
      methods:{
          dd(){
           this.$emit("update:自定义属性名", 修改后的属性值)
          } 
      }
    }  

Vue3 中已经废弃了 .sync 修饰符

4 . 依赖注入- provideinject 传值

依赖注入的作用 : 可以非常方便的 , 实现跨层级的组件通信(例如: 父传子组件 , 父传孙组件)

使用方法 :

  • 父组件利用 provide 属性提供数据
  • 子组件使用 inject 属性获取数据 (子孙后代, 都可以拿到这个数据)

语法 :

  • 父组件内 provide : { 属性名 : '数据' }
  • 子组件内 ingect : ['属性名']

注意 : provideinject 都是和 data 同级的

Vue3 中的依赖注入

父组件中 : 先导入 provide, 再在 setup() 函数中使用 provide 传值

   import {provide} from  'vue' 
   setup(){
     provide('属性名',数据)
   }

子组件中 : 先导入 inject, 再在 setup() 函数中使用 inject 接收

   import {inject} from  'vue'
   setup(){
      const r=inject('rootMsg')
   }

5 . v-model 传值

v-model 本质和 sync 修饰符一样, 都是双向绑定, 可以直接在子组件中修改父组件中的值

使用 :

  • 父组件中 : <组件名 v-model = "值" />
  • 子组件中 :props 中使用 value 属性接收
 export default {
      // props: ['value'],
      props: {
        value : {
          type: Number,
          default: 1
        }
      }
}
  • 子组件中 : 使用 $emit 修改数据
    • $emit("update:value", 修改后的值)

Vue3 中 v-model 传值

父组件中用法不变

子组件中 :

  • 接收 :props 中使用 modelValue 属性接收
 export default {
      // props: ['value'],
      props: {
        modelValue : {
          type: Number,
          default: 1
        }
      }
}
  • 修改 :setup( ) 函数中 , 用形参 context 调用 emit 方法修改数据
export default {
  setup( context ) {
    const change = () => {
      // 子传父
      context.emit("update:modelValue", 修改后的值 )
    }
    
    return {
      change
    }
  }
}
</script>

6 . vuex 数据共享

作用 : 更加方便高效的实现组件间的数据共享

猜你喜欢

转载自blog.csdn.net/jiang_ziY/article/details/123953930