I met such a requirement in the project. To change the data under data in one component, let's see how to implement it.
In this tutorial, it is mainly implemented through props/$emit. There are many other methods, as well as vuex, which can be implemented. Let's summarize later.
1. Nesting of components
There are two horizontal components in the project KitRecords.vue And KitDrawer.vue , which are contained in the parent component ResearchContent.vue Next, we need to pass KitRecords.vue Components to change KitDrawer.vue Component's drawerShowFlag property value
ResearchContent.vue The contents are as follows:
<template> <main> <section class="research-content" :class="drawerShowFlag ? 'research-content__small' : ''" > <!-- Here is KitRecords.vue assembly --> <router-view></router-view> </section> <!-- Here is KitDrawer.vue assembly --> <kit-drawer v-if="$route.name === 'KitRecords'"> <kit-preview :research-id="researchBase.id" :title="researchBase.name" ></kit-preview> </kit-drawer> </main> </template>
Component is vue.js One of the most powerful functions, and the scope of component instances is independent of each other, which means that the data between different components cannot reference each other. In order to realize the direct communication of components, the data of the child component needs to be passed to the parent component first, and then to another child component by the parent component.
2. The child component passes $emit to the parent component
First in subcomponent KitRecords.vue To call a method and implement $emit
There are two parameters, the first is the method in the parent component, and the second is the parameter passed to the method
KitRecords.vue The contents are as follows:
<template> <header> <el-button @click="drawerShowFlag">{{ title }}</el-button> // Bind a click event </header> </template> <script> export default { data() { return { title:"Click to expand the sidebar" } }, methods:{ /** * @description: Call parent component ResearchContent.vue showDrawer method in */ changeTitle() { this.$emit("titleChanged","Pass value from child to parent");// The second parameter can be selected } } } </script>
In parent component ResearchContent.vue You can listen to events through v-on or @
ResearchContent.vue The contents are as follows:
<template> <main> <section class="research-content" :class="drawerShowFlag ? 'research-content__small' : ''" > <!-- Here is KitRecords.vue assembly --> <!-- monitor showDrawer event --> <router-view @showDrawer="showDrawer"></router-view> </section> <!-- Here is KitDrawer.vue assembly --> <kit-drawer v-if="$route.name === 'KitRecords'"> <kit-preview :research-id="researchBase.id" :title="researchBase.name" ></kit-preview> </kit-drawer> </main> </template> <script> export default { data() { return { drawerShow: false, } }, methods:{ /** * @description: This method is called by the subcomponent */ showDrawer(e) { this.drawerShow = true; } } } </script>
3. The child component receives the value of the parent component through props
In parent component ResearchContent.vue Through v-bind to the subcomponent KitDrawer.vue Pass parameters
ResearchContent.vue The contents are as follows:
<template> <main> <section class="research-content" :class="drawerShowFlag ? 'research-content__small' : ''" > <!-- Here is KitRecords.vue assembly --> <!-- monitor showDrawer event --> <router-view @showDrawer="showDrawer"></router-view> </section> <!-- Here is KitDrawer.vue assembly --> <!-- adopt v-bind To subcomponent KitDrawer Pass parameters --> <kit-drawer v-if="$route.name === 'KitRecords'" :drawerShow="drawerShow"> <kit-preview :research-id="researchBase.id" :title="researchBase.name" ></kit-preview> </kit-drawer> </main> </template> <script> export default { data() { return { drawerShow: false, } }, methods:{ /** * @description: This method is called by the subcomponent */ showDrawer(e) { this.drawerShow = true; } } } </script>
In subcomponent KitDrawer.vue Receive parameters through props in
KitDrawer.vue The contents are as follows:
<template> <!--Omitted here--> </template> <script> export default { props: { drawerShow: { // Parameters defined in the parent component type: Boolean, // Here is the type of receive parameter default: false, // This field seems useless }, }, data() { return { drawerShowFlag: false }; }, watch: { 'drawerShow': function (val) { // Listening for properties in props this.drawerShowFlag = val; } }, methods: { // Omitted here }, }; </script>
Here's a question. After props receives the parameters, it tries to use the drawerShowFlag= this.drawerShow Assign a value to the data in data. It is found that it is not possible. Then, we can operate by listening to events. In Vue, we can listen through calculated and watch. Here, I use watch to monitor the changes of props properties. If the props changes (i.e. the parameters passed by the parent component are received), we will assign the props to the drawerShowFlag to get the parameters passed by the component.
4. What to pay attention to
In this project KitRecords.vue Component already in router.js The route is registered in, but KitDrawer.vue There is no registration, so you need to import the component in the parent component and add it to components.
ResearchContent.vue The contents are as follows:
<template> <main> <section class="research-content" :class="drawerShowFlag ? 'research-content__small' : ''" > <!-- Here is KitRecords.vue assembly --> <!-- monitor showDrawer event --> <router-view @showDrawer="showDrawer"></router-view> </section> <!-- Here is KitDrawer.vue assembly --> <!-- adopt v-bind To subcomponent KitDrawer Pass parameters --> <kit-drawer v-if="$route.name === 'KitRecords'" :drawerShow="drawerShow"> <kit-preview :research-id="researchBase.id" :title="researchBase.name" ></kit-preview> </kit-drawer> </main> </template> <script> // Import required subcomponents import KitDrawer from './records/KitDrawer.vue'; import KitPreview from './plan/KitPreview.vue'; export default { name: 'research-content', components: { // Add components to components KitPreview, KitDrawer, }, data() { return { drawerShow: false, } }, methods:{ /** * @description: This method is called by the subcomponent */ showDrawer(e) { this.drawerShow = true; } } } </script>
5. References
I think this article is very comprehensive and worth collecting
Six ways of communication between vue components (complete version)