vue3 里面父组件向子组件传值的一个问题 - V2EX
zzlit

vue3 里面父组件向子组件传值的一个问题

  •  
  •   zzlit Aug 18, 2021 3020 views
    This topic created in 1751 days ago, the information mentioned may be changed or developed.

    在 vue2 里面:

     // 父组件 <template> <ComponentA v-bind.sync="obj" /> </template> <script> data() { return { obj: {a: 1, b: 2} } } </script> // 然后在子组件 ComponentA 里面直接去拿 a 和 b 就好了,就相当于是 v-bind 把 obj 拆开了,添加了.sync 修饰符又能同步修改 props: ['a', 'b'] 

    如果按照 vue3 的写法:

    // 父组件 <template> <ComponentA v-model:obj="obj" v-model:c="c" /> </template> <script setup lang="ts"> import { reactive, ref } from 'vue'; const obj = reactive({ a: 1, b: 2 }); const c = ref(0) </script> // 子组件 <script setup lang="ts"> const props = defineProps<{ obj: { a: number; b: number; }; c: number; }>(); const emit = defineEmits(['update:obj', 'update:c']); function syncEdit() { emit('update:obj', { a: 2, b: 1 }); // 这个没有作用 emit('update:c', 2); // 这个起作用了 } </script> 

    现在遇到了两问题,求大佬们解答一下:

    1.如何在 vue3 里面把 obj 拆开,并且实现类似于.sync 的效果

    2.为什么 v-model:xxx="xxx",当 xxx 为 reactive 定义的时候不能同步修改,而 ref 可以

    6 replies    2021-08-26 13:51:02 +08:00
    joe237
        1
    joe237  
       Aug 18, 2021
    没人答么,我来稍微回复一下。

    2. 不答,不想答
    1. 其实与 vue2 也差球不多,文档中也有,可能你没注意到。

    ```
    obj: {
    id: 1,
    title: 'My Journey with Vue'
    }

    <component v-bind="post"></component>

    // 等价于:

    <component v-bind:id="post.id" v-bind:title="post.title"></component>

    ```

    参考文档: [here]( https://v3.vuejs.org/guide/component-props.html#passing-the-properties-of-an-object).
    a516307724
        2
    a516307724  
       Aug 19, 2021
    第一个没试过就不说了。
    第二个很好解释 reactive 定义的响应市对象本身的,如果要对象里面的值需要响应的话需要用到 toRefs 方法转化
    zzlit
        3
    zzlit  
    OP
       Aug 19, 2021
    @joe237 多谢大佬解答,我知道 v-bind 可以用,但是我是想在 v-bind 上在实现原 vue2 中.sync 的作用。
    其实我发现需要实现 1 主要问题在 2,之前一直以为 ref 是针对 string 或 number 这种基本的数据类型的,不能用于 object,结果一直弄错了,ref 会根据数据类型去判断,如果是 object 就会走 reactive 创建这个响应式对象,那么我如果要实现 v-bind.sync 的话其实有两种办法。
    第一种:父组件里面直接用 ref 定义,我的想的是因为在模板上 obj.value 是被解绑的所以直接写 obj 就行了,然后 v-model 的语法糖其实就是更新 obj 的 value,所以直接用 ref 定义可以

    ```
    // 父组件
    <template>
    <ComponentA v-model:obj="obj" />
    </template>

    <script setup lang="ts">
    import { ref } from 'vue';

    const obj = ref({
    a: 1,
    b: 2
    });
    </script>
    ```

    第二种:这个就其实是自己手动拆开了,就是在子组件里面麻烦一点需要定义很多个 update:xxx

    ```
    // 父组件
    <template>
    <ComponentA v-model:a="obj.a" v-model:b="obj.b" />
    </template>

    <script setup lang="ts">
    import { reactive } from 'vue';

    const obj = reactive ({
    a: 1,
    b: 2
    });
    </script>
    ```
    不知道我上面说的对不对
    ps:目前用的是第一种,就是在如果需要在方法里面用的时候是写成 obj.value.a,看起来怪怪的...
    zzlit
        4
    zzlit  
    OP
       Aug 19, 2021
    @a516307724 我好像有点懂了,其实就是相当于我上面第二种方法里面 toRefs 把 obj 转化一下一样的道理,v-model 更新的对象的值,就是需要一个 xx.value?


    ```
    // 父组件
    <template>
    <ComponentA v-model:a="a" v-model:b="b" />
    </template>

    <script setup lang="ts">
    import { reactive } from 'vue';

    const obj = reactive({
    a: 1,
    b: 2
    });
    const { a, b } = toRefs(obj);
    </script>
    ```
    JobinJia34
        5
    JobinJia34  
       Aug 26, 2021
    ```
    function syncEdit() {
    emit('update:obj', { a: 2, b: 1 }); // 这个没有作用
    emit('update:c', 2); // 这个起作用了
    }
    ```
    这两都能更新啊
    (adsbygoogle = window.adsbygoogle || []).push({});
    zzlit
        6
    zzlit  
    OP
       Aug 26, 2021
    @jiabinbin0115 你父组件的 obj 是不是 ref 定义的?我使用 ref 的可以,用 reactive 不行
    About     Help     Advertise     Blog     API     FAQ     Solana     5572 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 51ms UTC 06:37 PVG 14:37 LAX 23:37 JFK 02:37
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86