Advanced component communication

01. Ancestors and Descendants

  • Provide and Inject enable cross-level component communication

    Only ancestors can pass values to offspring

    This injected value, which is intended for reading, is not recommended for change

    If you do need a change, you can pass a function from the ancestor to make the change within the ancestor

    // Provided in the ancestor element
    provide(){
        return {
            foo: '123123'.app: this // You can even return the ancestor instance directly}}// Descendant element
    export default {
        // Injects the values provided by the ancestor element into the descendant element
        inject: ['foo']}Copy the code

02. Distribution and broadcasting

  • Two custom events are defined through $ON and $EMIT to communicate between parent and child components

    $emit fires an event on the current component and then listens for this event on the parent component with V-on

    You can also listen to yourself on the current component via $on

  • Find the component with the specified name by recursing up/down

  • Each component should have a component name, name, which should be unique

    The Dispatch method can be called in the child component

    • Used to look up the specified component to the parent and trigger custom events and pass data
    • Upper-level components are required$onListen for this event

    The broadcast method can be called in the parent component

    • Used to look up the specified component to the child and trigger custom events and pass data
    • Child components are required$onListen for this event
    // componentName-- componentName, eventName-- eventName, params-- pass parameters
    function broadcast(componentName, eventName, params) {
        // Gets an array of subcomponents of the current component, traversing to find the subcomponents of the specified component name
        this.$children.forEach(child= > {
            // Gets the component name of the current child component
            const name = child.$options.name;
    
            if (name === componentName) {
                // If the name of the current subcomponent is the same as the name of the component being searched, the event is sent to the current subcomponent
                child.$emit.apply(child, [eventName].concat(params));
            } else {
                // Otherwise, look for the child in the current child and continuebroadcast.apply(child, [componentName, eventName].concat([params])); }}); }function dispatch(componentName, eventName, params) {
        // Get the parent or root component of the current component
        let parent = this.$parent || this.$root;
        // Gets the component name of its parent component
        let name = parent.$options.name;
    
        while(parent && (! name || name ! == componentName)) {// If there is no component name or a component name that is not searched, continue to look up
            parent = parent.$parent;
            if(parent) { name = parent.$options.name; }}/ / out of the loop, says no parent component | find the corresponding components
        if (parent) {
            // If the parent component exists, the component with the specified component name is foundparent.$emit.apply(parent, [eventName].concat(params)); }}Copy the code

03. AboutmixinMixed with

  • Mixins are used to distribute reusable functionality in Vue components

    • Mixin objects can contain any component options, such as lifecycle, base data, and instance methods
    • When the component is in use, all options that blend into the object will be blended into the component
    // mixin.js file -----
    let mixin = {
        // Write the same as in the component
        data(){return {}},
        created(){},
        methods:{}
    }
    export default mixin
    
    // In the component -----
    import mixin from './mixin'
    export default {
        // Local mixin
        mixins: [mixin]
    }
    
    // global mixin
    Vue.mixin({ mixin })
    Copy the code
    • The hook function of the same name (created,mounted) will be merged into an array, andWith the objectThe hook will be in the component hookBefore the call
    • Object options (methods,components), will be merged into the same object, when components conflict,Component first

    • Mixobjects with different components whose methods and parameters are not shared

    • Mixins are used when we need to globally inject methods, filters, hooks

    • Note: Once global mixin is used, it affects every Vue instance created later

  • The above distribution and broadcast methods can be blended into the desired components by mixing them with mixins

    export default {
        methods: {
            dispatch(componentName, eventName, params) {
                dispatch.call(this, componentName, eventName, params);
            },
            broadcast(componentName, eventName, params) {
                broadcast.call(this, componentName, eventName, params); }}};Copy the code

04. Component constructor Extend

  • Vue. Extend creates a class based on the Vue constructor that extends the instance

    • Its parameters are the same asnew VueIs basically the same as
    • But data, like a component, is a function
    • Combined with$mount, you can render the component and mount it to any specified node

    Extend creates a component constructor, not a concrete component instance

    This can be interpreted as constructing an object that has the same structure as the vUE component

    Finally, you need to register with Vue.com Ponents to use it

    let Profile = Vue.extend({
        template: ' '.data() {
            return{}}})Method 1: Create a Profile instance and mount it to an element
    new Profile().$mount('#app')
    // Method 2:
    new Profile({ el: "#app" })
    
    // Mode 3: Manually mount the file
    let myProfile = new Profile().$mount();
    export default {
        mounted(){
            // Since this is being added to an element by getting a node, it is important to mount it in the hook function to ensure that the dom node of the current page is loaded
            let app = document.getElementById('app')
            app.appendChild(myProfile.$el)
        }
    }
    
    // Register the component
    Vue.component('myProfile', Profile)
    // Or local components
    export default {
        components: {
            'myProfile': Profile
        }
    }
    Copy the code

I front-end side dish chicken, if there is wrong, please forgive