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

2022-08-15 09:26:57 +08:00
 ciming
<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 监听

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

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

获取数据--> 前置处理-->双向绑定--> (用户操作-->后置处理) --> 提交数据
zhuweiyou
2022-08-16 12:13:11 +08:00
一般来说, 调用者传入的值应该符合组件的需求, 而不是组件去迎合调用者.
这种情况我一般是在父上转换好格式再传给子组件用.
chenjiangui998
2022-08-28 01:57:38 +08:00
这项目没开 lint? modelValue: {
type: Array,
defualt:() => [],
},
多实例共享 modelValue 了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/872868

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX