vue3 里面父组件向子组件传值的一个问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zzlit
V2EX    Vue.js

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

  •  
  •   zzlit 2021-08-18 16:49:05 +08:00 2744 次点击
    这是一个创建于 1582 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 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 条回复    2021-08-26 13:51:02 +08:00
    joe237
        1
    joe237  
       2021-08-18 19:00:33 +08:00
    没人答么,我来稍微回复一下。

    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  
       2021-08-19 10:05:11 +08:00
    第一个没试过就不说了。
    第二个很好解释 reactive 定义的响应市对象本身的,如果要对象里面的值需要响应的话需要用到 toRefs 方法转化
    zzlit
        3
    zzlit  
    OP
       2021-08-19 10:17:53 +08:00
    @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
       2021-08-19 10:25:00 +08:00
    @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  
       2021-08-26 10:14:40 +08:00
    ```
    function syncEdit() {
    emit('update:obj', { a: 2, b: 1 }); // 这个没有作用
    emit('update:c', 2); // 这个起作用了
    }
    ```
    这两都能更新啊
    zzlit
        6
    zzlit  
    OP
       2021-08-26 13:51:02 +08:00
    @jiabinbin0115 你父组件的 obj 是不是 ref 定义的?我使用 ref 的可以,用 reactive 不行
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3625 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 00:48 PVG 08:48 LAX 16:48 JFK 19:48
    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