Vue知识梳理

218 阅读4分钟

vue3生命周期

移除了beforeCreatecreated 这两钩子函数,取而代之 为 setup,setup为最早执行,在created以前就执行了,所有内部不能使用 this 来访问 vue 实列

2版本 和 3版本的区别

-   beforeCreate -> setup()
-   created -> setup()
-   beforeMount -> onBeforeMount
-   mounted -> onMounted
-   beforeUpdate -> onBeforeUpdate
-   updated -> onUpdated
-   beforeDestroy -> onBeforeUnmount
-   destroyed -> onUnmounted
-   errorCaptured -> onErrorCaptured

其次在vue3中新增了两个钩子函数# onRenderTrackedonRenderTriggered

onRenderTracked直译过来就是状态跟踪,它会跟踪页面上所有响应式变量和方法的状态,也就是我们用return返回去的值,它都会跟踪。只要页面有update的情况,它就会跟踪,然后生成一个event对象,我们通过event对象来查找程序的问题所在。

onRenderTriggered直译过来是状态触发,它不会跟踪每一个值,而是给你变化值的信息,并且新值和旧值都会给你明确的展示出来。

如果把onRenderTracked比喻成散弹枪,每个值都进行跟踪,那onRenderTriggered就是狙击枪,只精确跟踪发生变化的值,进行针对性调试。

vue3中ref 和 reactive 的理解

ref和reactive一样,都是用来实现响应式数据的方法

ref处理普通类型数据,reactive处理对象,数组类型数据。

Vue3中是通过Proxy来处理数据触发响应式的,但是Proxy不能处理普通类型的数据,ref底层就是就是将普通数据转换成 “value:” 这种对象的形式,然后交给Proxy再去做转换。

如果碰到时间类型的数据,那么reactive必须重新赋值,才能起作用。直接修改,是没效果的。例如:

<template>
<div>
  <p>{{msg.date}}</p>
  <button @click="c">button</button>
</div>
</template>
 
<script>
import { reactive } from 'vue'
export default {
  name: 'App',
  setup() {
    let msg = reactive({
      date: new Date()
    });
    function c() {
      console.log(msg);
      msg.date.setDate((msg.date.getDate() + 1)); //这一步达不到数据,视图都更新
      msg.date = new Date(msg.date);  //必须再重新赋值一次
      console.log(msg);
    }
    return {
      msg,
      c
    };
  }
}

创建了一个reactive对象,在template中是要用 xxx.zzz 方式使用,如果要使用解构赋值的方式展示,那就必须使用 toRefs() 包裹起来转换

code.png

readonly 表示只读,不能修改

let title = readonly('张三')

setup()函数的两个参数props,context

props是一个对象,包含父组件传递给子组件的所有数据。

context参数是一个普通的javascript对象,它对组件暴露三个属性:attrsslotsemit

attrs用途:当父组件传递数据给子组件时,子组件不通过props接收,那么父组件传递的数据就到了setup中的contextattrs属性。

slots:用于接收渲染父组件传递的插槽内容。

emit:向父组件触发事件。

computed 和 watch

computed计算属性,与vue2.0用法一致

let result = computed(()=>{
    return ...
})

watch监听, name 要监听的值,如果需要监听多个值的话,可以用数组的方式来写

//监听单个值
watch(name,(newvalue,oldvalue)=>{
    ...
})

//监听多个值
watch([name,age],([newName,newAge],[oldName,oldAge])=>{
    ...
})

当监听的数据是 reactive 类型的时候 监听他的某个属性 可以是 ()=> 来监听 如:

//单个值监听 
watch(()=>info.name,(newvalue,oldvalue)=>{
    ...
})
//多个值监听
watch([()=>info.name,()=>info.age],([newName,newAge],[oldName,oldAge])=>{
     ...
})

除了watch外,compostition API还提供了 watchEffect 这种监听方式

区别:

  1. watch 监听有惰性,页面刷新不会立即执行,(设置immediate:true 也可以改变为立即执行),

    watchEffect则没有惰性,页面刷新立即执行

  2. watch 参数可以拿到原始值,当前值

    watchEffect不能获取数据之前的值,不需要传递参数,自动会感知代码依赖.

组件传值

Vue2.0版本 常规的组件传值:子组件props接收一下值, 子组件触发事件,this.emit(事件名,要传递的值)父组件使用@事件名="事件名",这是比较简单的场景,但是实际开发中是会遇到嵌套组件传值,比如:爷孙组件等等,这样的场景使用props方法也能解决,但是不够优雅,代码比较繁琐。这时候可以使用emit(事件名,要传递的值) 父组件使用 @事件名="事件名",这是比较简单的场景,但是实际开发中是会遇到嵌套组件传值,比如:爷孙组件等等,这样的场景使用 props 方法也能解决,但是不够优雅,代码比较繁琐。这时候可以使用 `attrs$listeners` inheritAttrs属性官方的解释:默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings) 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上。

实际上可以这样理解, 设置 inheritAttrs: false 这样子组件就不会继承父子件的自定义属性,默认是true,也就是说 默认是继承的。

爷儿孙组件来讲, 要使用 $attrs$listeners ,那么儿组件 就相当于一个中间站,从而连接爷孙的交互

<template>
  <div>
      <P>我是子组件 ----- {{msg}} </P>
      <Sun v-bind="$attrs" v-on="$listeners"/>
  </div>
</template>

在vue3中 多层组件嵌套 直接使用 provideinject 来交互 爷组件使用

provide('字段名','字段值')

在孙组件使用接收到,然后记得在 setup 中 return 出去

const xxx = inject('字段名')

这块的inject可以有两个参数,第二个参数是设置默认值的,也就是说如果某个字段没有获取到,那么后面的值就是这个字段的默认值

孙组件像爷组件传值,需要在爷组件中定义一个函数出来,并用 provide 注册下

const fromSun = (val) =>{
    console.log('孙子传给我的值====',val);
}
  provide('fromSun',fromSun)

同样的 孙组件 用 inject 接收 然后在自己内部定义的事件函数中 使用 inject接收到的函数来 传递

const fromSun = inject('fromSun')
const add = () =>{
    fromSun('传给爷组件的值')
}