解决组件之间props双向绑定问题

解决方式一:

  • 在data对象中创建一个值,如visible
  • 使用watch监听props属性中对应的值 ,如value,
  • watch 赋予data副本 来同步组件外对props的修改,始终保持data中的值等于父组件传递过来的值
  • 当data中的值变化时,触发父组件的自定义事件
  // 子组件
<template>
  <div class="modal" v-show="visible">
    <p>我是子组件</p>
    <button @click="cancel">子组件的关闭按钮</button>
  </div>
</template>

<script>
export default {
  name: "MyList",
  props: {
    value: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      visible: false
    }
  },
  watch: {
    value(val) {
      this.visible = val;
    }
  },
  methods: {
    cancel() {
      this.visible = false;
      this.$emit('modalVisibleChange', false);
    }
  },
};
</script>


//父组件
<template>
  <div>
    <p>我是父组件</p>
    <button v-show="!isShow" @click="isShow=true">父组件的显示按钮</button>
    <MyList :value="isShow" @modalVisibleChange="modalVisibleChange"/>
  </div>
</template>

<script>
import MyList from './MyList'

export default {
  name: "app",
  data() {
    return {
      isShow: false
    };
  },
  components: {
    MyList,
  },
  methods: {
    modalVisibleChange(val) {
      this.isShow = val;
    }
  }
};
</script>

优点:解决了 父子组件之间props 双向绑定的问题;
缺点: 在父级调用 子组件的时候,还需要写一个 modalVisibleChange 的方法,而且子组件还需要写方法控制组件的显示和隐藏,代码过于冗长,且难以理解。

解决方式二:通过.sync


<template>
  <div class="modal" v-show="value">
    <p>我是子组件</p>
    <button @click="cancel">子组件的关闭按钮</button>
  </div>
</template>

<script>
export default {
  name: "MyList",
  props: {
    value: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    cancel() {
      this.$emit('update:value', false) // $emit触发父组件数据同步修改
    }
  },
};
</script>

// 父组件
<template>
  <div>
    <p>我是父组件</p>
    <button v-show="!isShow" @click="isShow=true">父组件的显示按钮</button>
    <MyList :value.sync="isShow"/>
  </div>
</template>

<script>
import MyList from './List'

export default {
  name: "app",
  data() {
    return {
      isShow: false
    };
  },
  components: {
    MyList,
  },
};
</script>

解决方式三:(推荐)

  • 使用 v-model 实现组件props的双向绑定
 // modal组件
<template>
 <div class="modal" v-show="value">
  <div class="close" @click="cancel">X</div>
 </div>
</template>

<script>
export default {
 props: {
  value: {
  type: Boolean,
  default:false
  }
 },
 methods:{
 cancel(){
  this.$emit('input', false);
 }
 },
}
</script>


// 父组件调用modal组件
 <modal v-model="isShow"></modal>
export default {
 name: 'app',
 data () {
 return {
  isShow:true
 }
 }
}
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容