This article brings you an introduction to the communication method of vue components (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you. help.
The componentization of vue should be its core idea. Whether it is a large page or a small button, it can be called a component. Vue-based development means writing components one by one, whether they are basic components or business components, and they all need to be assembled together in the end. According to the hierarchical relationship of components, the relationships between components can be summarized as: parent-child relationship, generational relationship, brother relationship, and no related relationship.
$ref, $parent, $children
Based on the current context, you can access the component instance through $ref, $parent, $children, and you can directly call the component's method or access data. Among them, $parent can access the parent component of the current component, and $children can access all child components of the current component. Although both $parent and $children can obtain component instances, they cannot communicate across levels or between siblings, which is their disadvantage.
provide and inject
provide / inject are new APIs added by Vue after version 2.2.0.
This pair of options needs to be used together to allow an ancestor component to inject a dependency into all its descendants, no matter how deep the component hierarchy is, and it will always take effect from the time the upstream and downstream relationships are established.
That is, provide a value in the parent component and inject the changed value into the descendant component that needs to be used, that is:
// Parent.vue export default { provide() { return { name: 'Stone' } } } // Child.vue export default { inject: ['name'], mounted() { console.log(this.name) } }
is not just Child.vue, as long as it is Parent.vue Subcomponents, no matter how many generations apart, can be injected through this method. This multi-level component transparent transmission method can ensure the clarity of one-way data flow. For example, global information such as user information can be completed with the help of these two APIs without introducing the third-party library vuex.
Instead of Vuex
vuex is to centrally manage the data, and then obtain it wherever it is needed. According to this idea, we can inject global information into the root component App.vue and add it to the page Use anywhere.
// App.vue <template> <div> <router-view></router-view> </div> </template> export default { provide() { return { userInfo: this.user } }, data() { return { user: {} } }, methods: { getUserInfo () { $.ajax('/user/info', (data) => { this.user = data }) } } }
Provide the entire App.vue instance this
to the outside world, so that other pages can obtain user information through this.userInfo
.
<template> <div> {{ userInfo }} </div> </template> <script> export default { inject: ['userInfo'] } </script>
$dispatch and $broadcast
These two APIs are Vue 1.0 versions. $dispatch is used to dispatch events to upper levels, and $broadcast is used to broadcast events to lower levels. They are in 2.0 version has been deprecated.
Because the event flow method based on the component tree structure is sometimes difficult to understand, and will become more and more fragile as the component structure expands.
However, we can implement the dispatch and broadcast methods ourselves for cross-level communication of components. The key to their implementation is how to correctly find the component to be communicated, that is, by matching the name option of the component to find the component downwards or upwards.
Both methods need to pass 3 parameters. The first parameter is the name option value of the communication component, the second is the custom event name, and the third is the value to be passed to the communication component. . In dispatch, the parent component is searched upward through the while loop until the componentName matches the name option of a parent component. At this time, the parent component is the component to be communicated with. The broadcast method is similar to dispatch, searching downwards for subcomponents through the forEach loop. Finally, encapsulate a mixins to facilitate reuse.
// emitter.js function broadcast(componentName, eventName, params) { this.$children.forEach(child => { const name = child.$options.name; if (name === componentName) { child.$emit.apply(child, [eventName].concat(params)); } else { broadcast.apply(child, [componentName, eventName].concat([params])); } }); } export default { methods: { dispatch(componentName, eventName, params) { let parent = this.$parent || this.$root; let name = parent.$options.name; while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.name; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, broadcast(componentName, eventName, params) { broadcast.call(this, componentName, eventName, params); } } };
Mix components into components through mixins to achieve communication between components.
<!-- Parent.vue --> <template> <button @click="handleClick"> 触发事件 <Child></Child> </button> </template> <script> import Emitter from "../assets/js/emitter.js"; import Child from "./Child.vue"; export default { name: "Parent", mixins: [Emitter], created() { this.$on("on-message", message => { console.log(message); }); }, components: { Child }, methods: { handleClick() { this.broadcast("Child", "on-message", "Hello, I am Parent Component"); } } }; </script>
<!-- Child.vue --> <template> <div></div> </template> <script> import Emitter from "../assets/js/emitter.js"; export default { name: "Child", mixins: [Emitter], mounted() { this.$on("on-message", message => { console.log(message); this.dispatch("Parent", "on-message", "Copy that, I am Child Component"); }); } }; </script>
Compared with the two built-in APIs in Vue 1.0 version, the self-implementation method has the following differences:
There are other methods for component communication in vue, such as:
props
, $ emit
<!-- Parent.vue --> <template> <Child :info="info" @update="onUpdateName"></Child> </template> <script> import Child from "./Child.vue"; export default { data() { return { info: { name: "stone" } }; }, components: { Child }, methods: { onUpdateName(name) { this.info.name = name; } } }; </script>
<!-- Child.vue --> <template> <div> <div>{{info.name}}</div> <button @click="handleUpdate">update</button> </div> </template> <script> export default { props: { info: { type: Object, default: {} } }, methods: { handleUpdate() { this.$emit("update", "new-name"); } } }; </script>
The parent component passes its own method to the child component, and the child component calls the method to pass data to the parent component using the event bus event bus $attrs and $listenersVue 2.4 new API.
$attrs contains attribute bindings (except class and style) in the parent scope that are not recognized (and obtained) as props.
$listeners contains v-on event listeners in the parent scope (without .native modifier). Vuex centralized state management
Written at the end
Different communication methods are suitable for different scenarios. Communication can be achieved through Vue’s built-in API or through custom events. Method, when the application is complex enough, you can use Vuex for data management.
This article is all over here. For more other exciting content, you can pay attention to the JavaScript Tutorial Video column on the PHP Chinese website!
The above is the detailed content of Introduction to vue component communication methods (with code). For more information, please follow other related articles on the PHP Chinese website!