vue-learning: 27 - component - the three components of the two API: event

Three components of the two API: event

Wherein prop mentioned unidirectional downlink data in a bound, the parent component subassembly to pass values prop realized that if the parent component subassembly to pass required value or other communication request, by vuethe event monitor system (trigger event, monitor the implementation of the callback function, and can accept mass participation in the callback function).

VueBuilt a complete set of event triggers logic:

  • v-on / @: The original HTML elements listens native events, custom events or sub-assemblies
  • .native: Native event-triggered components of the root element
  • $on: Event Listener component itself triggered
  • $emit: trigger event
  • $off: Uninstall event listener component itself
  • $once: A single monitor, event listeners only once, after which no longer valid
  • $listeners: Includes v-on register on the component label all custom listener objects, key event name, value to the event listener function.

v-on / @

Click to view: v-on event and event modifier, and DOM / JQUERY events within

So to achieve the face component to parent component communication, we can in the parent component v-onbinding open an event listener on the child component tag, then use the internal sub-components $emitof the trigger event.

Click to see an example DEMO

<div id="app">
    <p>this is event example for v-on/@<p>
    <!-- 绑定监听事件some-event -->
    <com-child @com-btn-click="handleChildClick"></com-child>
</div>
const comChild = Vue.extend({
    template: `<button @click="handleClick">我是子组件内定义的按钮,点击触发父级监听事件</button>`,
    methods: {
        handleClick() {
            this.$emit('com-btn-click',666)
        }
    }
})

const vm = new Vue({
    el: "#app",
    components: {
        comChild,
    },
    methods: {
        handleChildClick(val) {
            alert('我是由子组件触发的:' + val);
    }
    }
})

The event name always uses kebab-case form
different from the assembly and prop, event name does not appear as a JavaScript variable or attribute names, so any automatic case conversion does not exist. That event triggered the need to name exactly matches the name used to listen to this event.
And because v-on is bound to the html element, but HTML is not case sensitive. The general name of the event and are based on more than one word, it is proposed that the name of the event all use kebab-casea hyphen form.

Event parameter passing
subassembly $emitwhile the trigger event, a value can be passed, in v-onthe received binding event listener.

// $emit第一个参数是监听器事件名,第二个是要传递的参数
this.$emit('some-event',666)
// 监听事件处理函数第一个参数即为接收的值
handleChildEvent(val) {
    alert('我是由子组件触发的:' + val)
}

$on / $once

$onOpen to listen for events and $emitlisten to events are triggered in the same component instance.

<div id="app">
    <p>this is event example for $on<p>
    <com-child></com-child>
</div>
const comChild = Vue.extend({
    template: `<button @click="handleClick">我是子组件内定义的按钮,点击触发监听事件</button>`,
    data: () => {
        return {
            count: 0,
        }
    },
    methods: {
        handleClick() {
            this.count++
            this.$emit('comBtnClick',this.count)
        }
    },
    mounted() {
        this.$on('comBtnClick', (val) => {
            alert('我是由$on注册的监听子组件按钮点击事件'+val)
            if (val === 3) {
                console.log('卸载事件监听')
                this.$off('comBtnClick')
            }
        })
        this.$once('comBtnClick', (val) => {
            alert('我是由$once注册监听子组件按钮点击事件,只会触发一次'+val)
        })
    }
})

const vm = new Vue({
    el: "#app",
    components: {
        comChild,
    },
})

For internal components under conditions trigger other events, such as to monitor the implementation of time with $once, or monitor the implementation and under certain conditions no longer listening use $on配合$off.
But if it is continuous monitoring, as long as the event is triggered on the implementation of an action, can be written in the listener callback methods in the method, the method is performed when the event direct handling.

const comChild = Vue.extend({
    template: `<button @click="handleClick">我是子组件内定义的按钮,点击触发监听事件</button>`,
    methods: {
        handleClick() {
            // this.$emit('comBtnClick',888)
            this.comBtnClick(val)
        },
        comBtnClick(val) {
            alert('我是按钮点击触发执行'+val)
        }
    },
})

Using the above $on / $emit, if the internal components perform only an object can not be achieved and the value of the communication component subassembly parent mass. At this point we need to with the $refsproperty implementation.

refWith a single characteristic HTMLover the elements may acquire the native DOMnode object, the label used in the assembly, the object can obtain the component instance.

Under the above modified example, using the $on / $emit / $refsobject instance to the parent component subassembly assembly

<div id="app">
    <p>this is event example for $on / $emit / $refs<p>
    <com-child ref="comChild"></com-child>
</div>
const comChild = Vue.extend({
    template: `<div>
            <button @click="handleBtnClick">我是子组件内定义的按钮,点击触发监听事件</button>
            </div>`,
    methods: {
        handleBtnClick() {
            this.$emit('comBtnClick',999)
        },
    },
})

const vm = new Vue({
    el: "#app",
    components: {
        comChild,
    },
    mounted() {
        this.$refs.comChild.$on('outerSelfEvent', val => {
            console.log('组件按钮点击了')
        })
        this.$refs.comChild.$once('outerSelfEvent', val => {
            console.log('组件按钮点击了,我只监听执行一次')
        })
    }
})

$off

Remove custom event listeners.

  • If no parameters, then remove all the event listeners;
  • If only event, then remove all the event listeners;
  • If both events and callbacks, only remove this listener callback (callback function can not be used at this time of writing the anonymous function when registering events).
 <div id="app">
    <p>this is event example for $off<p>
    <com-child ref="comChild"></com-child>
</div>
const comChild = Vue.extend({
    template: `<div>
            <button @click="handleBtnClick1">点击触发触发组件内部监听事件elert</button>
            <button @click="handleBtnClick2">点击触发触发组件内部监听事件console</button>
            <button @click="handleUninstallAllListener">点击卸载组件内所有事件监听$off()</button>
            <button @click="handleUninstallTheEvent">点击卸载组件内指定事件监听器$off(event)</button>
            <button @click="handleUninstallTheEventCallback">点击卸载组件内指定监听器$off(event,cb)</button>
            </div>`,
    methods: {
        handleBtnClick1() {
            this.$emit('handleAlert')
        },
        handleBtnClick2() {
            this.$emit('handleConsole')
        },
        handleUninstallAllListener() {
            console.log('卸载所有监听器')
            this.$off()
        },
        handleUninstallTheEvent() {
            console.log('卸载指定事件handleAlert的所有监听器')
            this.$off('handleAlert')
        },
        handleUninstallTheEventCallback() {
            console.log('卸载指定事件handleConsole中的handleConsole2监听器')
            this.$off('handleConsole', this.handleConsole2)
        },

        handleConsole2() {
            console.log('监听器Console2')
        }

    },
    mounted() {
        this.$on('handleAlert',function () {
            alert('监听器alert1')
        })
        this.$on('handleAlert',function () {
            alert('监听器alert2')
        })
        this.$on('handleConsole',function () {
            console.log('监听器Console1')
        })
        this.$on('handleConsole',this.handleConsole2 )
    }
})

const vm = new Vue({
    el: "#app",
    components: {
        comChild,
    },
})

$listeners

Contains all registered by v-on event listeners parent scope in the component tag.
But does not include:

  1. Containing .native decorator native event listener
  2. Components use $ on registered listeners

The following example, we bind on the child component tag a native event, two v-oncustom events the way, a $oncustom event method.
But the final $listenersprint out only one of two v-onevents bound manner.

<div id="app">
    <p>this is event example for $listeners<p>
    <com-child
        ref="comChild"
        @click.native="handleNativeClick"
        @child-btn-click-console="handelChildBtnClickConsole" @child-btn-click-alert="handelChildBtnClickAlert"
    ></com-child>
</div>
const comChild = Vue.extend({
    template: `<div>
            <button @click="handleBtnClick" >点击触发触发组件内部监听事件elert</button>
            </div>`,
    methods: {
        handleBtnClick() {
            this.$emit('child-btn-click-alert')
            this.$emit('child-btn-click-console')
            this.$emit('handleConsole')
        },

    },
    mounted() {
        this.$on('handleConsole',function () {
            console.log('$on绑定监听器')
        })
        // 打印出$listeners
        console.log('$listeners:', this.$listeners)
    }
})

const vm = new Vue({
    el: "#app",
    components: {
        comChild,
    },
    methods: {
        handelChildBtnClickAlert() {
            alert('v-on绑定$emit触发alert')
        },
        handelChildBtnClickConsole() {
            console.log("v-on绑定$emit触发console")
        },
        handleNativeClick() {
            alert('native click')
        }
    }
})
$listeners:
child-btn-click-alert: ƒ invoker()
child-btn-click-console: ƒ invoker()

Guess you like

Origin www.cnblogs.com/webxu20180730/p/11031243.html