美文网首页react & vue & angular
vue3x 响应式后代传参(provide 和 inject)

vue3x 响应式后代传参(provide 和 inject)

作者: 暴躁程序员 | 来源:发表于2023-01-03 14:32 被阅读0次

一、vue3x 响应式后代传参

  1. 在源头组件App.vue中
    引入 provide 和 readonly函数:import { provide,readonly} from "vue";
    在 provide函数 中定义传递的响应式参数,如果不允许后代更改参数,可用readonly函数修饰参数
<template>
  <HelloWorld />
  <h1>{{ a3 }}</h1>
  <h1>{{ b3 }}</h1>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import { ref, provide,readonly, reactive, toRefs } from "vue";
export default {
  name: "App",
  components: {
    HelloWorld,
  },
  setup() {
    const a3 = ref("1000");
    const obj3 = reactive({
      b3: 'bbb'
    })

    provide("a3", readonly(a3));
    provide("obj3", obj3);

    setTimeout(() => {
      a3.value = "2000";
      obj3.b3 = "bbbbbb";
    }, 3000);
    
    return {
      a3,
      ...toRefs(obj3)
    };
  },
};
</script>
  1. 在子组件 HelloWorld.vue 中
  • 引入 inject函数:import { inject } from "vue";
  • 通过 inject函数获取源头组件传递的参数,此参数是响应式的
  • 子组件修改参数会影响父组件,解决方式是在源头组件使用readonly函数修饰
<template>
  <div>{{ a3 }}</div>
  <div>{{ b3 }}</div>
</template>

<script>
import { toRefs,inject } from "vue";
export default {
  setup(){
    const a3 = inject('a3')
    const obj3 = inject('obj3')

    setTimeout(() => {
      a3.value = "4000";
      obj3.b3 = "bbbbbbbbbbbbbbbbbbbbbbbbb";
    }, 4000);

    return {
      a3,
      ...toRefs(obj3)
    }
  }
};
</script>

二、vue2x,vue3x 响应式后代传参对比

  1. 在源头组件App.vue中
  • vue2x使用provide传data数据默认不是响应式的,需要把参数以回调函数的方式传递才是响应式的
  • vue2x 在子组件中无法通过修改后代参数来影响源头组件
<template>
  <HelloWorld />
  <h1>{{ a2 }}</h1>
  <h1>{{ b2 }}</h1>
  <hr>
  <h1>{{ a3 }}</h1>
  <h1>{{ b3 }}</h1>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import { ref, provide,readonly, reactive, toRefs } from "vue";
export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return {
      a2: "a2",
      b2: "b2",
    };
  },
  provide() {
    return {
      a2: () => this.a2, 
      b2: () => this.b2,
    };
  },
  mounted(){
    setTimeout(() => {
      this.a2 = "a2a2";
      this.b2 = "b2b2";
    }, 3000);
  },
  setup() {
    const a3 = ref("1000");
    const obj3 = reactive({
      b3: 'bbb'
    })

    provide("a3", readonly(a3));
    provide("obj3", obj3);

    setTimeout(() => {
      a3.value = "2000";
      obj3.b3 = "bbbbbb";
    }, 3000);
    
    return {
      a3,
      ...toRefs(obj3)
    };
  },
};
</script>
  1. 在子组件中HelloWorld.vue中
<template>
  <div>{{ a2() }}</div>
  <div>{{ b2() }}</div>
  <hr>
  <div>{{ a3 }}</div>
  <div>{{ b3 }}</div>
</template>

<script>
import { toRefs,inject } from "vue";
export default {
  components: {
    HelloWorldChildren,
  },
  inject: ["a2", "b2"],
  setup(){
    const a3 = inject('a3')
    const obj3 = inject('obj3')

    // 在源头组件的属性使用 readonly函数 修饰后,此属性在子组件中不可修改 
    setTimeout(() => {
      a3.value = "4000";
      obj3.b3 = "bbbbbbbbbbbbbbbbbbbbbbbbb";
    }, 4000);

    return {
      a3,
      ...toRefs(obj3)
    }
  }
};
</script>

相关文章

网友评论

    本文标题:vue3x 响应式后代传参(provide 和 inject)

    本文链接:https://www.haomeiwen.com/subject/ifmccdtx.html