• Vue自定义事件


    前面的话

      父组件使用props传递数据给子组件,子组件怎么跟父组件通信呢?这时,Vue的自定义事件就派上用场了。本文将详细介绍Vue自定义事件

    事件绑定

      每个 Vue 实例都实现了事件接口 (Events interface),即

    使用 $on(eventName) 监听事件
    使用 $emit(eventName) 触发事件

      [注意]Vue 的事件系统分离自浏览器的EventTarget API。尽管它们的运行类似,但是 $on$emit 不是addEventListenerdispatchEvent 的别名

      另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件

      [注意]不能用 $on 侦听子组件抛出的事件,而必须在模板里直接用 v-on 绑定

    <div id="example">
      <parent></parent>
    </div>
    <script>
    var childNode = {
      template: `<button @click="incrementCounter">{{ counter }}</button>`,
      data(){
        return {
          counter: 0
        }
      },
      methods:{
        incrementCounter(){
          this.counter ++;
          this.$emit('increment');
        }
      },
    }
    var parentNode = {
      template: `
      <div class="parent">
        <p>{{total}}</p>
        <child @increment="incrementTotal"></child>
        <child @increment="incrementTotal"></child>
      </div>
      `,
      components: {
        'child': childNode
      },
      data(){
        return {
          'total':0
        }
      },
      methods:{
        incrementTotal(){
          this.total ++;
        }
      }
    };
    // 创建根实例
    new Vue({
      el: '#example',
      components: {
        'parent': parentNode
      }
    })
    </script>

    命名约定

      自定义事件的命名约定与组件注册props的命名约定都不相同,由于自定义事件实质上也是属于HTML的属性,所以其在HTML模板中,最好使用中划线形式

    <child @pass-data="getData"></child>

      而子组件中触发事件时,同样使用中划线形式

     this.$emit('pass-data',this.childMsg)

    数据传递

      子组件通过$emit可以触发事件,第一个参数为要触发的事件,第二个事件为要传递的数据

    this.$emit('pass-data',this.childMsg)

      父组件通过$on监听事件,事件处理函数的参数则为接收的数据

        getData(value){
          this.msg = value;
        }
    <div id="example">
      <parent></parent>
    </div>
    <script>
    var childNode = {
      template: `
      <div class="child">
        <div>
          <span>子组件数据</span>
          <input v-model="childMsg" @input="data">
        </div>
        <p>{{childMsg}}</p>
      </div>
      `,
      data(){
        return{
          childMsg:''
        }
      },
      methods:{
        data(){
          this.$emit('pass-data',this.childMsg)
        }
      }
    }
    var parentNode = {
      template: `
      <div class="parent">
        <div>
          <span>父组件数据</span>
          <input v-model="msg">
        </div>
        <p>{{msg}}</p>
        <child @pass-data="getData"></child>
      </div>
      `,
      components: {
        'child': childNode
      },
      data(){
        return {
          'msg':'match'
        }
      },
      methods:{
        getData(value){
          this.msg = value;
        }
      }
    };
    // 创建根实例
    new Vue({
      el: '#example',
      components: {
        'parent': parentNode
      }
    })
    </script>

      下面示例中,修改子组件中的input值,则父组件到接收到相同值,则显示出来

    sync修饰符

      在一些情况下,可能会需要对一个 prop 进行双向绑定。事实上,这正是Vue1.x中的 .sync修饰符所提供的功能。当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定的值。这很方便,但也会导致问题,因为它破坏了单向数据流的假设。由于子组件改变 prop 的代码和普通的状态改动代码毫无区别,当光看子组件的代码时,完全不知道它何时悄悄地改变了父组件的状态。这在 debug 复杂结构的应用时会带来很高的维护成本,上面所说的正是在 2.0 中移除 .sync 的理由

      从 2.3.0 起重新引入了 .sync 修饰符,但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 侦听器

    <comp :foo.sync="bar"></comp>

      会被扩展为:

    <comp :foo="bar" @update:foo="val => bar = val"></comp>

      当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:

    this.$emit('update:foo', newValue)

      因此,可以使用.sync来简化自定义事件的操作,实现子组件向父组件的数据传递

    <div id="example">
      <parent></parent>
    </div>
    <script src="https://unpkg.com/vue"></script>
    <script>
    var childNode = {
      template: `
      <div class="child">
        <div>子组件数据:{{childMsg}}</div>
        <input v-model="childMsg">
        <button @click=add >+1</button>
      </div>
      `,
      data(){
        return{
          childMsg: 0
        }
      },
      methods:{
        add(){
          this.childMsg++;
          this.$emit('update:foo',this.childMsg);
        }
      }
    };
    var parentNode = {
      template: `
      <div class="parent">
        <p>父组件数据:{{msg}}</p>
        <child :foo.sync="msg"></child>
      </div>
      `,
      components: {
        'child': childNode
      },
      data(){
        return {
          'msg':0
        }
      }
    };
    // 创建根实例
    new Vue({
      el: '#example',
      components: {
        'parent': parentNode
      }
    })
    </script>

  • 相关阅读:
    在windows下拆卸Linux就是这么俭朴
    打点Linux下永中Office和桌面殊效的冲突
    Banshee 0.11.4
    ubuntu8.0中文输入法
    RedFlag 6.0 硬盘安置我解
    阅读器和把持体系和用户的IQ
    初试Fedora,最后还是Xubuntu
    VMware中放置Ubuntu后鼠标滚轮标题问题办理
    GNOME 的文件经管器将片面支撑标签式阅读
    ATI显卡开启fedora9的3d后果的一些条记
  • 原文地址:https://www.cnblogs.com/xiaohuochai/p/7389934.html
Copyright © 2020-2023  润新知