vue学习之组件(component)(二)

   自定义事件

    父组件使用 prop 传递数据给子组件。但子组件怎么跟父组件通信呢?这个时候 Vue 的自定义事件系统就派得上用场了。

   1. 使用 v-on 绑定自定义事件

    每个vue实例都实现了事件接口,即:

  1. 使用 $on(eventName)  监听事件
  2. 使用 $emit(eventName, optionPayload) 触发事件

   注意点: 父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件

     

{{msg}}

this is father component

{{"儿子发来的数据:"+msgFromSon}}

   2. 给组件绑定原生事件

     有时候,你可能想在某个组件的根元素上监听一个原生事件。可以使用 v-on 的修饰符 .native。例如:

    

   3.使用自定义事件的表单输入组件

   自定义事件可以用来创建自定义的表单输入组件,使用v-model来进行数据双向绑定。注意:

    vue学习之组件(component)(二)_第1张图片

   所以在组件中使用时,它相当于下面的简写:

    vue学习之组件(component)(二)_第2张图片

所以要让组件的v-model生效,它应该:

  1. 接受一个 value 的prop
  2. 在有新的值时触发 input 事件并将新值作为参数
          Vue.component('currency-input', {
              template: `$
                               
                                     @input='updateValue($event.target.value)'>
                          `,
              props: ['value'], // 1. 接受一个value的props
              methods: {
                  updateValue(value){
                      // 删除两侧的空格符,保留2位小数,这个例子还是比较初级的。比如,用户输入多个小数点或句号也是允许的
                      var formattedValue = value.trim().slice(0, value.indexOf('.') === -1
                          ? value.length : value.indexOf('.') + 3);
                      // 如果值尚不合规,则手动覆盖为合规的值
                      if (formattedValue !== value) {
                          this.$refs.input.value = formattedValue;
                      }
                      this.$emit('input', Number(formattedValue)); // 2. 触发input事件到父组件;
                  }

              }            
          })
        new Vue({
            el: '#app',
            data() {
              return {
                    price: ''
              }
            }
        })

4. 自定义组件的 v-model

     默认情况下,一个组件的v-model会使用 value prop和 input 事件。但如单选框,复选框之类的输入类型可能会把 value 用作它用。model 选项可以避免这样的冲突:

   vue学习之组件(component)(二)_第3张图片

   注意你仍然需要显式声明 checked 这个 prop。

   vue学习之组件(component)(二)_第4张图片

5. 非父子组件的通信

    有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线

    vue学习之组件(component)(二)_第5张图片

页面如下: 

<div id="example">
    <laoda>laoda>
    <hr/>
    <laoer>laoer>
div>

<script type="text/x-template" id="laoda-template">
    <div>
        <h1>laoda</h1>
        <button @click="tellLaoer">回家吃饭</button>
    </div>
script>
<script type="text/x-template" id="laoer-template">
    <div>
        <h1>laoer</h1>
        <span v-if="msgFromLaoDa">{{"老大说:"+msgFromLaoDa}}</span>
    </div>
script>

JS如下: 

   

    //新建一个Vue的实例,通过bus完成事件的绑定和触发
    var bus = new Vue();

    Vue.component('laoda', {
        template: '#laoda-template',
        methods:{
            tellLaoer: function () {

                //1. 触发事件通知老二回家吃饭
                bus.$emit('eventToBrother','赶紧回家吃饭')
            }
        }
    })
    Vue.component('laoer', {
        template: '#laoer-template',
        data:function(){
            return {
                msgFromLaoDa:null
            }
        },
        mounted: function () {
            console.log(this, bus); // 3.外面的this指向laoer这个组件
            // 2. 事件的绑定
            bus.$on('eventToBrother', function (result) {
                console.log('this:', this); // 4. 里面的this原指向bus,使用bind后,就指向了组件
                this.msgFromLaoDa = result;
            }.bind(this));
        }
    })

    new Vue({
        el: '#example',
        data: {
            msg: 'Hello Directive'
        }
    })

转载于:https://www.cnblogs.com/xuzhudong/p/8579616.html

你可能感兴趣的:(vue学习之组件(component)(二))