单向数据流

  • 单向数据流是Vue组件一个非常明显的特征,不应该在子组件中直接修改props的值

组件之间的通信

  • 父子组件的关系可以总结为 prop 向下传递,事件event向上传递
  • 祖先组件和后代组件(跨多代)的数据传递,可以使用provideinject来实现
  • 跨组件或者兄弟组件之间的通信,可以通过eventBus或者vuex等方式来实现

封装的组件如何实现v-model的数据双绑的效果

以下两种通常是我们的实现方式, 看着就很麻烦

  1. 通过emit将事件派发到父组件,prop将数据传到子组件
    // 子组件
    <template>
    <div>
    <van-button @click="add" type="default">加一</van-button>
    <div>
        {{countsVal}}
    </div>
    <van-button @click="reduce" type="default">减一</van-button>
    </div>
    </template>

    <script>
        export default {
            props: {
                value: Number
            },
            data () {
                return {
                // props的初始化比data的初始化要靠前
                countsVal: this.value
                }
            },
            methods: {
                add () {
                    this.countsVal++
                    this.$emit('add', this.countsVal)
                },
                reduce() {
                    this.countsVal--
                    this.$emit('reduce', this.countsVal)
                }
            }
        };
    </script>

    // 父组件
    <template>
        <div>
                <counter :value='value' @add='changeValue' @reduce='changeValue'/>
        </div>
    </template>

    <script>
        export default {
            data () {
                return {
                value: 10
                }
            },
            methods: {
                changeValue (data) {
                    this.value = data
                }
            }
        };
    </script>
  1. 将加减执行的回到函数通过父组件传到子组件中实现改变数据
    // 子组件
    <template>
    <div>
    <van-button @click="add" type="default">加一</van-button>
    <div>
        {{countsVal}}
    </div>
    <van-button @click="reduce" type="default">减一</van-button>
    </div>
    </template>

    <script>
    export default {
        props: {
            value: Number,
            add: Function,
            reduce: Function
        }
    };
    </script>

    // 父组件
    <template>
    <div>
    <counter :value='value' :add='add' :reduce='reduce'/>
    </div>
    </template>

    <script>
        export default {
            data () {
                return {
                value: 10
                }
            },
            methods: {
                add (data) {
                    this.value++
                },
                reduce (data) {
                    this.value--
                }
            }
        };
    </script>

通过v-model语法糖实现,父子组价的数据双绑

// 子组件
  <template>
      <div>
          <van-button @click="changeVal(1)" type="default">加一</van-button>
          <div>
              {{countsVal}}
          </div>
          <van-button @click="changeVal(-1)" type="default">减一</van-button>
      </div>
  </template>

  <script>
  export default {
      props: {
          value: Number
      },
      data () {
          return {
          // props的初始化比data的初始化要靠前
          countsVal: this.value
          }
      },
      methods: {
          changeVal (data) {
          this.countsVal += parseInt(data)
          this.$emit('input', this.countsVal)
          }
      }
  }
  </script>
  // 父组件只需要通过v-model将数据传进去就好了
  <template>
      <div>
          <counter v-model='counts'/>
      </div>
  </template>

  <script>
      import counter from './base/counter'
      export default {
          components: {
              counter
          },
          data () {
              return {
              counts: 10
              }
          }
      }
  </script>
05-12 22:57