V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ciming
V2EX  ›  Vue.js

关于 Vue3 自定义组件双向绑定问题

  •  
  •   ciming · 2022-08-15 09:26:57 +08:00 · 2158 次点击
    这是一个创建于 610 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <template>
      <div></div>
    </template>
    
    <script setup>
    const emit = defineEmits(["update:modelValue"]);
    const props = defineProps({
      modelValue: {
        type: Array,
        defualt: [],
      },
    });
    
    watch(
      () => props.modelValue,
      () => {
      	// 一些操作
      },
      {
        immediate: true,
      }
    );
    
    </script>
    

    有没有办法,如果组件内部 emit 改变 modelValue 的值不触发组件内部 watch 监听,只有在父组件改变了传入的值才触发组件内部 watch 监听

    13 条回复    2022-08-28 01:57:38 +08:00
    dingjs
        1
    dingjs  
       2022-08-15 09:38:05 +08:00
    不行,watch 的是 props ,只要改变必定会触发监听函数。
    简单点的办法是可以存个变量,emit 的时候更新,监听函数中判断一下值有没有变化
    lopssh
        2
    lopssh  
       2022-08-15 09:45:39 +08:00
    @dingjs 有道理。
    ciming
        3
    ciming  
    OP
       2022-08-15 09:51:59 +08:00
    @dingjs 主要是因为外部传进来的数据和组件处理的数据有差异,需要处理转换下,那个转换函数还要去遍历树,如果每次 emit 都会触发 watch ,就会很耗费性能
    Highlight1024
        4
    Highlight1024  
       2022-08-15 10:43:12 +08:00
    有一个蠢一点的方法就是弄一个值来区分是不是父组件改变的值
    haobaiZhang
        5
    haobaiZhang  
       2022-08-15 11:36:18 +08:00
    @ciming 组件内部用 computed ? emit 的时候, 只保持外部的数据结构?
    haobaiZhang
        6
    haobaiZhang  
       2022-08-15 11:37:09 +08:00
    @haobaiZhang 哦哦, 有点问题, 没考虑 emit 不触发 watch
    Sunzehui
        7
    Sunzehui  
       2022-08-15 14:54:51 +08:00
    @ciming 为什么不转换好了再传进来
    Vegetable
        8
    Vegetable  
       2022-08-15 15:27:12 +08:00
    本质上你的 emit 并没有修改 modelValue,而是向上 emit ,modelValue 的变化永远是外部触发的,所以这个场景和你描述的是不符的。
    比如你 emit("update:modelValue",1),但是外部可能是 @update:modelValue=(val)={value=val+1}

    如果用这种需求,不建议搞太复杂,弄两个方法算了
    lin07hui
        9
    lin07hui  
       2022-08-15 17:18:20 +08:00
    以后使用 `<script setup lang="ts">` 吧。
    joesonw
        10
    joesonw  
       2022-08-15 18:32:06 +08:00 via iPhone
    view 不要直接使用 props ,用一个 state 存,watch props 后存到 state 上
    gausszhou
        11
    gausszhou  
       2022-08-16 08:34:40 +08:00
    个人倾向于在组件外层,在接口回调中,进行数据结构的转换。

    获取数据--> 前置处理-->双向绑定--> (用户操作-->后置处理) --> 提交数据
    zhuweiyou
        12
    zhuweiyou  
       2022-08-16 12:13:11 +08:00
    一般来说, 调用者传入的值应该符合组件的需求, 而不是组件去迎合调用者.
    这种情况我一般是在父上转换好格式再传给子组件用.
    chenjiangui998
        13
    chenjiangui998  
       2022-08-28 01:57:38 +08:00
    这项目没开 lint? modelValue: {
    type: Array,
    defualt:() => [],
    },
    多实例共享 modelValue 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3617 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 04:53 · PVG 12:53 · LAX 21:53 · JFK 00:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.