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

这种情形该怎么处理?

  •  
  •   waiaan · 2021-12-02 09:57:22 +08:00 · 2240 次点击
    这是一个创建于 848 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 的操作 ,除了加一个类似锁的变量之外还有什么别的办法吗? 谢谢。

    9 条回复    2021-12-02 14:19:39 +08:00
    66beta
        1
    66beta  
       2021-12-02 10:05:40 +08:00
    意思是 prop 只取一次吧?

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

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

    不是只取一次,父组件传过来的 prop 也有可能在父组件内发生变化,我需要的是在子组件通过 emit 改变这个值的时候不会触发 value 的 watcher ,目前只想到用一个变量锁住的办法。
    yqxxoo
        4
    yqxxoo  
       2021-12-02 10:25:46 +08:00
    vue watch 里面有个 deep 属性,使用 deep:tree 属性解决 具体查看 vue 官方文档
    dabaoziwy
        5
    dabaoziwy  
       2021-12-02 10:38:49 +08:00
    使用 event bus 替代 props 实现父子组件通信,自定义触发器和接收器应该可以实现。
    yqxxoo
        6
    yqxxoo  
       2021-12-02 10:41:14 +08:00
    @yqxxoo 习惯性 tree 是 true
    liangtao927190
        7
    liangtao927190  
       2021-12-02 13:43:28 +08:00
    都从父组件改变值不行吗。。
    子组件不要改变内部 data 的值,emit 出去,改变父的值,这样是不是就一致了?
    waiaan
        8
    waiaan  
    OP
       2021-12-02 13:58:14 +08:00
    @liangtao927190
    子组件在其它组件里都用得到,所以单独做这么一个子组件。
    JimmyB
        9
    JimmyB  
       2021-12-02 14:19:39 +08:00
    provide inject 。provide 的值默认不是响应式的。https://v3.cn.vuejs.org/guide/component-provide-inject.html
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2944 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 14:10 · PVG 22:10 · LAX 07:10 · JFK 10:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.