zoukankan      html  css  js  c++  java
  • Vue实现组件props双向绑定解决方案

    注意: 子组件不能直接修改prop过来的数据,会报错

    方案一:

    1. 用data对象中创建一个props属性的副本

    2. watch props属性 赋予data副本 来同步组件外对props的修改

    3. watch data副本,emit一个函数 通知到组件外

    HelloWorld组件代码如下:(代码里面有相应的注释)

    <template>
      <div class="hello">
        <h1 v-show="visible">测试显示隐藏</h1>
        <div @click="cancel">点我点我</div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      props: {
          value: {
            type: Boolean,
            default:false
          }
        },
      data () {
        return {
          visible: false
        }
      },
      watch:{
        value(val) {
          this.visible = val;
        },
    // 只有这一步 才触发父组件的方法 由父组件的
    paretnVisibleChange 方法去改变父组件的数据
      visible(val) { this.$emit("paretnVisibleChange",val); } },
      // 子组件修改的只能是子组件 本身的data数据 methods:{ cancel(){
    this.visible = !this.visible; } },
    // 注意这段代码 为了同步父组件的数据 mounted() {
    if (this.value) { this.visible = true; } } } </script> <style scoped> </style>

    父组件代码如下:

    <template>
      <div id="app">
        <HelloWorld :value = 'visible' @paretnVisibleChange="visibleChange" />
      </div>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      },
      data () {
        return {
          visible: true
        }
      },
      methods:{
    // 父子组件就是靠的这个方法改变数据的 visibleChange(val){
    this.visible = val; } } } </script>

    方案一 的缺点就是 父组件必须有个 visibleChange 这样的方法,有点累赘。

    这时候 想到了 v-model 

    因为

    <input v-model = 'someThing'>

    是下面这段代码的语法糖

    <input :value = 'someThing'  @input = 'someThing = $event.target.value'>

    也就是说 v-mode 自带了 一个改变父组件的方法 类似方案一的   paretnVisibleChange

    但是使用 v-model 的时候 需要注意两点:

    1. 子组件要接受  value  属性

    2. value改变时 要触发input 事件

    方案二:

    HelloWorld 子组件的代码如下;

    <template>
      <div class="hello">
        <h1 v-show="visible">测试显示隐藏</h1>
        <div @click="cancel">点我点我</div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      props: {
          value: {
            type: Boolean,
            default:true
          }
        },
      data () {
        return {
          visible: false
        }
      },
      watch:{
        value(val) {
          this.visible = val;
        },
    // 子组件 改变的就是这段代码 visible(val) {
    this.$emit("input",val); } }, methods:{ cancel(){ this.visible = !this.visible; } }, mounted() { if (this.value) { this.visible = true; } } } </script>

    父组件代码如下:(父组件省去了 paretnVisibleChange 方法)

    <template>
      <div id="app">
        <HelloWorld v-mode = 'visible'/>
      </div>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      },
      data () {
        return {
          visible: true
        }
      }
    }
    </script>

    方案三:

    vue 2.3.0之后新增了 .sync 属性 使用方法跟 v-model  类似 具体 请参考 : https://cn.vuejs.org/v2/guide/components-custom-events.html#sync-修饰符

    下面我写了一个简单的sync 的使用实例:

    父组件的代码如下:

         <li
            is="DragCompent"
            v-for="(item, index) in layoutItem"
            :item="item"
            v-model="cloneLeftItemText"
            :leftDragItemIsDraged.sync = 'leftDragItemIsDraged'
            :key="index"></li>

    子组件的代码如下:

    props: {
        leftDragItemIsDraged: {
          type: Boolean,
          default: false
        }
      },
    watch:{
        leftDragItemIsDraged(val) {
        this.thisLeftDragItemIsDraged = val;
    },
    thisLeftDragItemIsDraged(val){
        this.$emit('update:leftDragItemIsDraged', val)
    }
    }

    效果如下:

  • 相关阅读:
    BZOJ.3884.上帝与集合的正确用法(扩展欧拉定理)
    HDU.5608.function(杜教筛)
    HDU.5628.Clarke and math(狄利克雷卷积 快速幂)
    51Nod.1244.莫比乌斯函数之和(杜教筛)
    SPOJ.Visible Lattice Points(莫比乌斯反演)
    BZOJ.2301.[HAOI2011]Problem B(莫比乌斯反演 容斥)
    BZOJ.2242.[SDOI2011]计算器(扩展欧几里得 BSGS)
    Codeforces757E.Bash Plays With Functions(积性函数 DP)
    插值法
    2、Windows下安装配置Redis
  • 原文地址:https://www.cnblogs.com/yalong/p/9759264.html
Copyright © 2011-2022 走看看