vue3 --相对于vue2的改变T1档次

前言

  vue3新增setup的初衷就是分散的逻辑块组合起来,使得开发者(特别是后续接替工作的开发人员)能够更好的理解代码逻辑,为此vue3新增了一系列的api方法来配合setup使用,其目的是我们原来写在声明周期(created,mounted等),以及监听函数、计算属性等中的逻辑,能够统一放在setup中,在上一篇vue3 --相对于vue2的改变T1档次,已经讲了setup、响应式api、生命周期,本文的讲解主要是computed、watch、provide、inject,在阅读之前希望能够对这些概念有初步的了解。

computed

  定义computed

    ref定义

    import {computed} from "vue //引入方法

const base = ref("plus one val"); //定义一个ref //定义一个computed,依赖base const plusOne = computed(() => { return base.value + " process"; }); plusOne.value = "new val"; //报错,plusOne 是只读的, setTimeout(() => { base.value = "9999"; //改变(ref) base同样会触发(computed) plusOne的副作用,也就是视图更新等响应式变化 }, 2000);

    普通对象定义

 //也可以直接返回普通对象来定义conputed
    const plusTwo = computed(() => {
      return "测试值";
    });

    reactive定义

    const reactiveBase = reactive({ prop: "reactive prop" }); //定义一个active

    const plusFour = computed(() => {
      return reactiveBase;
    });

    plusFour.value.prop = "new plus four val"; //因为plusFour.value是一个对象,所以我们改变对象下的prop属性,value的引用没有发生改变,所以不受computed只读限制。并且也会触发响应式副作用

    setTimeout(() => {
      reactiveBase.prop = "new plus four val2"; //改变(reactive) reactiveBase同样会触发(computed) plusFour的副作用
    }, 2000);

    通过传入{},定义get、set定义computed:值得一提的是,vue3任然保留了vue2在组件内部computed项,如果在组件的computed项中和setup返回的computed存在重名的项,组件内的computed会覆盖setup返回的computed

//通过传入对象,定义get、set方法来创建computed
    const refTwo = ref("ref two raw");
    const plusThree = computed({
      get() {
        return refTwo.value + " plus tree process";
      },
      set(val) {
        console.log(val); //只有改变plusThree.value 时,才会触发
        refTwo.value = val;
      },
    });

    setTimeout(() => {
      plusThree.value = "plusThree new val"; //定义set之后,computed是非只读的
      refTwo.value = "change ref two generate"; //同样会引起computed的副作用,但是不会引发set()
    }, 2000);

watchEffect

  普通使用

    const state = ref(0);
    const state2 = ref(0);
    watchEffect(() => {
      console.log(state.value); //定义之后立即执行一次打印0,2000秒后state发生改变,又执行一次打印:1
      console.log(state2.value); //如果在watchEffect内使用的多个响应式(ref||reactive)对象,那么只要有一个state发生改变,watchEffect就会执行
    });
    setTimeout(() => {
      state.value++;
      state2.value++;
    }, 2000);

  多个字段分别监听

export default {
  setup(props) {
    const state = ref(0);
    const state2 = ref(0);

    //监听state
    watchEffect(() => {
      console.log("监听state", state.value);
    });

    //监听state2
    watchEffect(() => {
      console.log("监听state2", state2.value);
    });

    setTimeout(() => {
      state.value++;
    }, 2000);

    setTimeout(() => {
      state2.value++;
    }, 3000);

    //setup中无需返回watchEffect
    return {
      state,
      state2,
    };
  },
  //如果在项中也定义了state的监听,那么watchEffect和watch都会执行,watch执行在watchEffect之后
  watch: {
    state(val) {
      console.log("项监听", val);
    },
  },
};

watch

    const state = ref(0);
    const state2 = ref(0);

    //监听state
    watch(state, (newState, prevState) => {
      console.log("监听state", state.value, state2.value); //定义时不会执行方法,只会在state改变后执行。即便内部使用了state2也不会对其进行监听
    });

    //监听多个字段
    watch([state, state2], (newStatesArray, prevStateArray) => {
      console.log(newStatesArray[0], newStatesArray[1]); //第一个参数为state,state2的最新数据数组
      console.log(prevStateArray[0], prevStateArray[1]); //第二个参数为state,state2的上一个状态数据数组
    });

provide和inject

 //父组件
  setup(props) {
    let refProvide = ref("refProvide");
    provide("key", "value"); //注入provide
    provide("key2", refProvide); //注入响应式provide
    return {
      refProvide,
    };
  },
...
//子组件
  setup(props) {
    let value1 = inject("key"); //value
    let value2 = inject("key2"); //ref value
    return {
      value1,
      value2,
    };
  },

    

  

  

原文地址:https://www.cnblogs.com/wrhbk/p/15194497.html