zoukankan      html  css  js  c++  java
  • VUE中 $on, $emit, v-on三者关系

    VUE中 $on, $emit, v-on三者关系

    每个vue实例都实现了事件借口

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

    若把vue看成家庭(相当于一个单独的components),女主人一直在家里派($emit)男人做事,而男人一直监听$on着女主人的指派($emit)里eventName所触发的事件消息,一旦$emit事件一触发,$on则监听$emit所派发的事件,派发的命令和执行所要做的事都是一一对应的

    Vm.$emit(event,[...args])
    参数  {String}event
            [...args]

    触发当前实例上的事件,附加参数都会传给监听器回调

    Vm.$on(evnet,callback)
    参数  {String | Array<String>}event
         {function}callback            

    监听当前实例上的自定义事件,事件可以由Vm.$emit触发,回调函数会接受所有传入事件触发函数的额外参数

    第二个参数则是一个function,同样也被叫做之前回调函数,里面可以接受到$emit触发时所传入的参数

    <template>
        <div>
            <p @click="emit">{{msg}}</p>
        </div>
    </template>
    <script>
    export default {
        data(){
            return {
                msg:'点击后女人派发事件'
            }
        },
        create(){
            //派发wash_foods事件
            this.$on('wash_foods',arg=>{
                console.log(arg);
            })
        },
        methods:{
            emit(){
                //触发 wash_foods 事件
                this.$emit('wash_foods',['fish','potato','fruit'])
            }
        }
    }
    </script>

    当女人派发的事情多了,男人也会觉得很烦,听到事件后,总会抱怨几句,若女人在组成家庭之前,告诉男人将要监听哪些事情,如果做一件抱怨一次,岂不是多此一举,所以通过Array<String>event 把事件名写成一个数组,在数组里写入所要监听的事件

    <template>
        <div>
            <p @click="emit">{{msg}}</p>
            <p @click="emitOther">{{msg2}}</p>
        </div>
    </template>
    <script>
    export default {
        data(){
            return {
                msg:"点击后女人派发事件",
                msg2:"点击后女人派发事件2"
            }
        },
        create(){
            this.$on(['wash_foods','driver_car'],arg=>{
                console.log('事真多');
                
            });
            this.$on('wash_foods',arg=>{
                console.log(arg)
            });
            this.$on('ariver_car',arg=>{
                console.log(arg)
            })
        },
        methods:{
            emit(){
                this.$emit('wash_foods','fish')
            },
            emitOther(){
                this.$emit('driver_car',['audi','BWM'])
            }
        }
    }
    </script>

    通常在写组件的时候,让 $emit在父级作用域中进行一个触发,通知子组件 进行执行事情

    自定义事件可以用来创建自定义的表单输入组件

    使用v-mode来进行数据双向绑定

    <input v-model="sth">

    //不过是以下事例的语法糖
    <input v-bind:value="sth"
              v-on:input="sth = $event.target.value">

    每当输入框内容发生变化的时候,就会触发input事件,然后把input输入框中的value值再次传递给sth,此时value运用在一个input元素上,用 v-bind:value="sth" 意义上面只是把一一对应的双向绑定,这就像一个循环操作,当再次触发input事件时,input($event.target)对象中的value值会再次改变sth

    通过自定义事件让v-mode进行一个父子组件 双向绑定的花

    • v-bind:value="sth" 此时value是作为子组件接受props

    接受的只能是value,因为v-model是基于input输入框定制的,其中value值是input内部定制的

    此时作用域在组件上时,v-on监听的语法糖也会有所改变,监听的并不是$event.target.value,而是回调函数的第一个参数

    v-on:input = "sth = arguments[0]"

    这是一个模态框的基本雏形,可以在父组件中通过v-model 来进行model框和父组件之间的显示交互,通过子组件看出通过props接受了value值; 当点关闭的时候还是通过$emit事件触发input事件,然后通过出入false参数

    父组件隐式  v-on:input = "sth = arguments[0]"进行了监听,一旦input事件触发, 父组件就会进行监听回调,从而双向绑定

    checkbox 和radio 原理

    <input type="checkbox" :checked="status"
               @change="status=$event.target.checked"/>
    <input type="radio" :check="status"
               @change="status=$event.target.checked"/>      

    通过绑定checked属性,同样的监听的是change事件,无论是checkbox还是radio在操作的时候都会隐式自动触发一个change事件,跟input通过value值input触发事件原理绑定是一样的

        <!-- 父组件 -->
    <template>
        <div class="Father">
            <button @click="show=true">打开model</button>
            <Son v-model="show"></Son>
        </div>
    </template>
    <script>
    import Son from './Son'
    export default {
        name:"Father",
        data(){
            return{
                show:false
            }
        },
        components:{son}
    }
    </script>

      <!-- 子组件 -->
    <template>
        <div class="Son" v-show="value">
           <div>
                <p>model框</p>
                <input type="text" v-model="value" />>
                {{value}}
                <button @click="close">关闭model</button>
           </div>
        </div>
    </template>
    
    <script>
    export default {
        name:'Son',
        props:['value'], //接受父组件传来的value值
        methods:{
            close(){//页面关闭子组件model框按钮事件
                this.$emit('input',false)
            }
        }
    }
    </script>

    定义组件v-model

    定制组件,就可以重写v-model里的props和event

    默认情况下一个组件的v-model会使用value 属性和input 事件,而value值被占用了,

    或者表单和自定义v-model的$emit('input')事件发生冲突,为了避免这种冲突,可以定制组件v-model

    input中的v-model和model显示操作数据共同占用props中的value,同样两者也共同占据了emit('input' )触发事件,input输入框的事件自动触发,而model显示消失是手动触发的

    初始化的时候,input输入框的值会被value传入的false值给自动加上,当改变input输入框的时候,因为冲突而导致报错

    定制v-model,通过model选项改变props和event的值,从而解除两者的冲突

    • props代替掉原本value的值,可以自定义值
    • event代表掉原来input的触发事件,可自定义触发事件
  • 相关阅读:
    js高级-闭包
    js作用域
    js执行上下文与执行上下文栈
    js原型及原型链
    去除数组中重复的元素值
    树[省选联考2020]
    GDOI2020 游记
    Problem b[HAOI2011]
    分零食[JSOI2012]
    移动金币「SDOI2019」
  • 原文地址:https://www.cnblogs.com/tommymarc/p/12000360.html
Copyright © 2011-2022 走看看