text
Talking about the different scenarios of data "exchange" between components Vue
Vue's official documents can be said to be very detailed. In my opinion, it and other frameworks and other documents react the same, more about the way that the "methodology" and not "on the scene", which also led: After we finished reading the document many times, and wrote code or can not help but feel there is a lot of confusion, because we do not know the scene in which the use of some knowledge points. This is the purpose of writing this article I explore the data "exchange" between components under different scenarios to achieve Vue
Data exchange between father and son Components
Sons data communication between components may be divided into two types:
1. The data transferred to the parent component subassembly
2. Data is transmitted to the parent sub-assembly component
Parent components pass data to the subassembly --props
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/8edec46b76964498af4500e497be8a85/%C3%A5%C2%B1%C2%8F%C3%A5%C2%B9%C2%95%C3%A6%C2%88%C2%AA%C3%A5%C2%9B%C2%BE3.jpg)
This is the component data communication is the most common scenario: You let the parent component master data source, and then passed to the sub-components, sub-assemblies for use
![](https://images2017.cnblogs.com/blog/1060770/201708/1060770-20170804194734194-705824014.jpg)
Many will say that this is very simple! Well with props! Yes, because of this, I want to say it's not the main content, but we still go over with a simple code:
Parent component
<Template> <div ID = "Father"> {{ 'I parent element'}} <Son: text = "text"> </ Son> </ div> </ Template> <Script> Import Son from '. /son.vue ' Export default { data: function () { return { text:' data transmitted from the parent component ' } }, components: { Son: Son } } </ Script> <style scoped> </ style>
Subassembly:
<template> <div> {{ '我是子组件,我接收了' + text }} </div> </template> <script> export default { props: { text: { type: String, default: '' } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
demo:
![](https://images2017.cnblogs.com/blog/1060770/201708/1060770-20170804194348553-1058128128.png)
In this demo there, we have "the data coming from the parent component" It's a string passed through the props to the subassembly
If we want to change the data in the parent element subassembly then, you can be defined in a parent function parent component of the component data change, and then passed to the function using the props subassembly, and the subassembly call the function at the appropriate time - changing the parent component thus play data in a subassembly effect
Subassembly components pass data to the parent
Subassembly passes data to a parent element way: callback parameter passing
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/01f4fccb31a241a8ac0e63075b20901d/%C3%A5%C2%B1%C2%8F%C3%A5%C2%B9%C2%95%C3%A6%C2%88%C2%AA%C3%A5%C2%9B%C2%BE4.jpg)
Parent component:
<template> <div id="father"> {{ '我是父组件,名称是' + componentName }} <son :changeComponentName = "changeComponentName"></son> </div> </template> <script> import son from './son.vue' export default { data: function () { return { componentName: '组件A' } }, methods: { changeComponentName: function (newComponentName) { this.componentName = newComponentName } }, components: { son: son } } </script> <style scoped> #father div{ padding: 10px; margin: 10px; border: 1px solid gray; } </style>
Subassembly:
<Template> <div> <the p-> I subcomponents: a the Button </ the p-> <= @click the Button "() => changeComponentName (newComponentName)"> The name of the parent component amended as follows: Peng bay components < / Button> </ div> </ Template> <Script> Export default { Data: function () { return { newComponentName: 'Peng a bay assembly' } }, the props: { changeComponentName: { type: function, default: ( ) => {} } } } </ Script> <-! the Add "scoped" attribute to limit the CSS to the this Component only -> <style scoped> </style>
demo:
Click ago:
Click:
Graphic:
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/652c9c59a4024829bd7be0cd1a302341/a4fi%2528p08m%257Ee0f58%2525%257E3_16ze.png)
Click on sub-components (button) when the name of the parent component from the "A" was changed to "Peng Bay Components"
We passed a function (changeComponentName) from the parent to the sub-assembly components. When sub-assembly and this function is called, passing the data inside a sub-assembly (newComponentName) to this function, such as a parameter, a function (changeComponentName) defined in the parent component subassembly can obtain parameters transmitted the
[PS] name too embarrassed
Subassemblies pass data to the parent assembly way: custom events
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/318850e0807d40af9aa6d5f5ce3bba7a/%C3%A5%C2%B1%C2%8F%C3%A5%C2%B9%C2%95%C3%A6%C2%88%C2%AA%C3%A5%C2%9B%C2%BE5.jpg)
Parent component:
<template> <div id="father"> <div> {{ '我是父组件,我的名称是:' + fatherComponentName }} <son v-on:changeComponentName = "changeComponentName"></son> </div> </div> </template> <script> import son from './son.vue' export default { data: function () { return { fatherComponentName: 'A组件' } }, methods: { changeComponentName: function (componentName) { this.fatherComponentName = componentName } }, components: { son: son } } </script> <style scoped> #father div{ padding: 10px; margin: 10px; border:1px solid grey; } </style>
子组件:
<template> <div> <p>我是子组件:一个按钮</p> <button @click="clickCallback"> 修改父组件的名称为:彭湖湾的组件 </button> </div> </template> <script> export default { data: function () { return { fatherComponentName: '彭湖湾的组件' } }, methods: { clickCallback: function () { this.$emit('changeComponentName', this.fatherComponentName) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
demo:
点击前:
点击后:
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/399973ffe33c495aa5d8fdf06ea2a319/%257Dn51gw0%257Bxk_%255B9g54pneh2%255Bc.png)
![](https://images2017.cnblogs.com/blog/1060770/201708/1060770-20170804194516225-280501573.png)
图解:
![](https://images2017.cnblogs.com/blog/1060770/201708/1060770-20170804194849662-510511633.jpg)
通过$emit(event, [...参数]),所有的参数将被传递给监听器回调,也就是我们在父组件中定义的changeComponentName方法,从而实现从子组件中给父组件传参
兄弟组件间的数据交流(有共同父组件的兄弟组件)
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/fbd573ba88b54588803aa12f06773c1c/%C3%A5%C2%B1%C2%8F%C3%A5%C2%B9%C2%95%C3%A6%C2%88%C2%AA%C3%A5%C2%9B%C2%BE.jpg)
父组件:
<template> <div id="father"> <div> {{ '我是父组件:father' }} <eldest-son :text = "text"></eldest-son> <youngest-son :changeText="changeText"></youngest-son> </div> </div> </template> <script> import eldestSon from './eldestSon.vue' import youngestSon from './youngestSon.vue' export default { data: function () { return { text: '我是一行文本' } }, methods: { changeText: function () { this.text = '我是经过改动的一行文本' } }, components: { eldestSon: eldestSon, youngestSon: youngestSon } } </script> <style> #father div{ border: 1px solid grey; padding: 10px; margin: 10px; } </style>
兄弟组件1:
<template> <div> <p>我是兄弟组件:eldestSon</p> <p>我有一个可变数据text:{{ text }}</p> </div> </template> <script> export default { props: { text: { type: String, default: '' } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
兄弟组件2:
<template> <div> <p>我是兄弟组件:youngestSon</p> <button @click="changeText">更改eldestSon兄弟组件中的文本</button> </div> </template> <script> export default { props: { changeText: { type: Function, default: () => {} } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
点击前:
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/65c0dc3e499646e5b2853e94a0296236/_upo_%257Dud%255Di0%2529m02%257B%25252%2529%257D%2524nq.png)
点击后:
![](https://images2017.cnblogs.com/blog/1060770/201708/1060770-20170804194623662-1540941358.png)
图解:
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/2096a4b5df1d47e69a67e3d170f701f3/jd%255Bykkh%2528n%25603tk%2560_0%255D%25250gb7w.png)
如果两个兄弟组件间存在这种数据关系的话,我们可以尝试寻找其共同的父组件,使数据和相关方法“提升”到父组件内部,并向下传给两个子组件
这样,其中一个子组件取得了数据,另外一个子组件取得了改变数据的方法,便可以实现上述的数据沟通
【注意】这种场景存在局限性,它要求两个组件有共同父组件。对于这种场景之外的处理方法,请看下文
Data exchange between global components --Vuex
I mentioned above many scenes which are applied to the props or function parameter passing way to handle data communication between components. However, in the slightly larger applications inside, they are invariably brought us a lot of trouble
E.g:
1. Data transfer from a parent component to the sub assembly via props
For direct component of parent-child relationship, the data flow is very clear and simple, but large-scale application in which, when a lot of us up and down the nested components, which will lead to our code very cumbersome and difficult to maintain
2. For brothers component does not have a common parent component, function parameter passing data transfer mode can not do anything, Vue documentation introduced to, you can pass data to $ emit and $ on function-based "event bus" communication, but it can not cope with more large-scale applications
This time Vuex became the best solution to achieve data exchange between global components of the
![](file:///C:/Users/lenovo/AppData/Local/YNote/data/qq558635343CE3D787D7910E2E25B05D68/5bcc799ebc4741fc8db36b9ad7116e51/%C3%A5%C2%B1%C2%8F%C3%A5%C2%B9%C2%95%C3%A6%C2%88%C2%AA%C3%A5%C2%9B%C2%BE%C3%A9%C2%98%C2%BF%C3%A7%C2%91%C2%9F%C3%A5%C2%A4%C2%A7%C3%A6%C2%97%C2%B6%C3%A4%C2%BB%C2%A3.jpg)
Vuex has a single data source (state) comprising a top layer of all state
1. All the components can be used inside a single data source data
2. All the components can be modified in this single source of data distribution operation (Actions)
![](https://images2017.cnblogs.com/blog/1060770/201708/1060770-20170804194944506-1890461583.jpg)
Supposed to "take a lot of detours" in order to achieve the communication of the data stream, suddenly found the shortest shortcut
Decoupling layer data and the model layer View
Data (Vue) in the processing section 1 and data processing in the third section (Vuex), in many cases two different types of data, the former belongs to the View layer, is responsible for only a simple display of the UI, the model layer mostly injected from the rear end of the data acquisition.
Suggestion:
1.Vue part of the code responsible for constructing View layer
2.Vuex part of the code responsible for building the model layer
(Refer to the above-Vue framework outside Vuex)
In the above two points, based on the code determined in the end to a portion which is written Vuex Vue written inside, and try to separate the two, in order to achieve decoupling of View layer and the model layer, and improve the maintainability of the front-end code expansibility