这种情形该怎么处理?

2021-12-02 09:57:22 +08:00
 waiaan

child.vue

<template>
  <div class="child">
    <h4>这里是子组件</h4>
    <el-input v-model="data"></el-input>
    <el-button type="primary" @click="onClick">add</el-button>
    <!-- <grand-child></grand-child> -->
  </div>
</template>
<script>

export default {
  name: 'Child',
  props: {
  // 1 、用 v-model 绑定
    value: {
      type: [String, Number]
    }
  },
  data() {
    return {
      data: ''
    };
  },
  watch: {
  // 2 、监听 value 的变化,并做一些处理
    value: {
      handler(val) {
        console.log(val);
        this.data = val + 'parent';
      },
      immediate: true
    }
  },
  methods: {
    onClick() {
      this.data += 'child';
      // 3 、更新值
      this.$emit('input', this.data);
    }
  }
};
</script>

parent.vue

<template>
  <div class="father">
    <h3>这里是父组件</h3>
    <child v-model="data"> </child>
  </div>
</template>
<script>
import Child from '@/views/Child';

export default {
  name: 'Parent',
  components: {
    Child
  },
  data() {
    return {
      data: '888'
    };
  }
};
</script>

就是子组件要监听父组件传过来的 prop ,并做一些操作(步骤 2 )。当子组件更新值的时候(步骤 3 ),又会再次触发 watcher 且又执行一次步骤 2 ,此时我并不想再触发步骤 2 的操作 ,除了加一个类似锁的变量之外还有什么别的办法吗? 谢谢。

2449 次点击
所在节点    Vue.js
9 条回复
66beta
2021-12-02 10:05:40 +08:00
意思是 prop 只取一次吧?

data() {
return {
data: this.value + 'parent',
};
},

删除 watcher
fengxianqi
2021-12-02 10:11:25 +08:00
@66beta 对的,不过要补充一下。
如果父组件的数据是异步返回时,子组件在 data 里面取到的值往往是初始值。所以这种写法还得确保父组件数据返回后再渲染子组件,如父组件这样写 `<Child :key="data.id" v-model="data.value"></Child>`,data 表示父组件中异步返回的数据,key 变化后可以让子组件重新渲染从而实现父组件数据返回后才渲染的写法
waiaan
2021-12-02 10:19:21 +08:00
@66beta
@fengxianqi

不是只取一次,父组件传过来的 prop 也有可能在父组件内发生变化,我需要的是在子组件通过 emit 改变这个值的时候不会触发 value 的 watcher ,目前只想到用一个变量锁住的办法。
yqxxoo
2021-12-02 10:25:46 +08:00
vue watch 里面有个 deep 属性,使用 deep:tree 属性解决 具体查看 vue 官方文档
dabaoziwy
2021-12-02 10:38:49 +08:00
使用 event bus 替代 props 实现父子组件通信,自定义触发器和接收器应该可以实现。
yqxxoo
2021-12-02 10:41:14 +08:00
@yqxxoo 习惯性 tree 是 true
liangtao927190
2021-12-02 13:43:28 +08:00
都从父组件改变值不行吗。。
子组件不要改变内部 data 的值,emit 出去,改变父的值,这样是不是就一致了?
waiaan
2021-12-02 13:58:14 +08:00
@liangtao927190
子组件在其它组件里都用得到,所以单独做这么一个子组件。
JimmyB
2021-12-02 14:19:39 +08:00
provide inject 。provide 的值默认不是响应式的。https://v3.cn.vuejs.org/guide/component-provide-inject.html

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

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

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

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

© 2021 V2EX