zoukankan      html  css  js  c++  java
  • vue学习之组件(component)(二)

       自定义事件

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

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

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

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

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

         

    <div id="example">
        {{msg}}
        <h1>this is father component</h1>
        <span>{{"儿子发来的数据:"+msgFromSon}}</span>
        <son @tofather='receiveMsg'></son>
        <!-- 2. 使用 $on(eventName) 监听事件:父组件使用v-on 来接收监听子组件触发的事件 -->
    </div>
    <script>
    
        Vue.component('son', {
            template: `<div> <h1>This is son component</h1> 
                            <input type="text" v-model="kw"/>
                            <button @click="handleClick">sendToFather</button>
                       </div>`,
            data(){
                return {
                    kw:''
                }
            },
            methods:{
                handleClick(){
                    console.log(this.kw);
                    this.$emit('tofather', this.kw);
                    //1.  $emit(eventName)触发事件,还可以发送数据kw到父组件 
                }
            }
        })
        new Vue({
            el: '#example',
            data: {
                msg: 'Hello Directive',
                msgFromSon:''
            },
            methods: {
                receiveMsg(msg) { //3. 接收从子组件传递过来的数据
                    console.log('msg',msg);
                    this.msgFromSon += ' '+msg;
                }
    
            }
        })
    </script>

       2. 给组件绑定原生事件

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

        

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

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

       

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

        

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

    1. 接受一个 value 的prop
    2. 在有新的值时触发 input 事件并将新值作为参数
              Vue.component('currency-input', {
                  template: `<span>$
                                  <input ref='input' :value='value' 
                                         @input='updateValue($event.target.value)'>
                              </span>`,
                  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 选项可以避免这样的冲突:

       

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

       

    5. 非父子组件的通信

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

        

    页面如下: 

    <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'
            }
        })
  • 相关阅读:
    JS之事件及冒泡
    DOM读取和修改内联样式
    dom查询与修改的一些常用方法
    js修改this指向的三种方法(call,bind,apply)
    JS原型概念
    JS创建对象
    JS的this(谁调用就指向谁)
    变量声明提前与函数声明提前
    JS对象创建
    正则应用之数据采集房屋网站信息
  • 原文地址:https://www.cnblogs.com/xuzhudong/p/8579616.html
Copyright © 2011-2022 走看看