美文网首页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