- Template: (template) Template declares the mapping relationship between data and the DOM that is ultimately presented to the user.
- Initial data: (data) The initial data state of a component. For reusable components, it is usually a private state.
- Receiving external parameters: (props) data transfer and sharing between components through parameters. The default parameter is one-way binding (top-down), but it can also be explicitly declared as two-way binding.
- METHODS: Data modification is usually done in the component method. User input events and component methods can be bound by v-on instructions.
- Declare periodic hook functions: (lifecycle hooks) A component triggers multiple lifecycle hook functions, such as create, attach, destroyed, etc. In these hook functions, we can encapsulate some custom logic. Compared with traditional MVC, this can be understood as the logic of Controller is dispersed into these hook functions.
Registration Components
- Global Components
- Local components
1.1 Global component registration: Vue. component ('didi-component', DIDIDIComponent)
Parameter 1 ('didi-component'): Register the name of the component, that is, you can add the component in HTML by using the custom tag of the corresponding name: <didi-component> </didi-component>. Names can be defined by using the small hump naming method, in addition to using the middle line and adding the custom tag in html. The inner part of UE automatically matches to the HTml custom tag with a dashed line, that is,'didi-component'equals'didiComponent'. There are also irregular ways of writing to directly customize any English character. It is also possible not to use a connector (dashed line) nor a small hump name. Later examples will appear.
Parametric 2 (DI DIDIComponent): The hook constructor of the registered component, Function, can also be Object.
1 //Component Constructor Constructs Components: 2 var MyComponent = Vue.extent({ 3 //option... 4 }) 5 //The incoming option object registers the global component: 6 Vue.component('didi-component',{ 7 template:`<div>A custom component!</div>` 8 })
Instance Code (Code Folding):
1 <div id="example"> 2 <didi-component></didi-component> 3 </div> 4 <script> 5 var DIDIComponent = Vue.extend({ 6 template:`<div>A custom component!</div>` 7 }) 8 //register 9 Vue.component('didi-component',DIDIComponent) 10 //Establish vue Root instance 11 new Vue({ 12 el:'#example' 13 }) 14 </script>
1.2 Local component registration: It can also be said that components are registered on vue instances.
1 <div id="example"> 2 <didi-component></didi-component> 3 </div> 4 <script> 5 //Register local components 6 var DIDIComponent = Vue.extend({ 7 template:`<div>i am child!</div>` 8 }); 9 new Vue({ 10 el:'#example', 11 components:{ 12 didiComponent:DIDIComponent 13 } 14 }); 15 </script>
The so-called local component is not to use Vue.component() to register components, but to add components directly on the vue instance through component. In the above example, component construction is written on the real exception surface, or directly in the instance:
1 new Vue({ 2 el:'#example', 3 components:{ 4 didiComponent:Vue.extend({ 5 template:`<div>i am child!</div>` 6 }) 7 } 8 });
Note: Components constructed in vue can be written directly as objects instead of writing the Vue.extend() method. In the following examples, all Vue.extend() will be omitted.
Global components and local components are registered by the Vue.component() method, while local components are added directly to the vue instance object by component. Global component registration is always cached in the form of constructs, while local components are not cached when they are not used, but only when the vue instance needs to be constructed. Although caching component constructs in memory can improve code execution efficiency, on the other hand, it consumes a lot of memory resources.
In addition to the above single construct registration, other local components can be referenced directly in the template:
1 <div id="example"> 2 <didi-component></didi-component> 3 </div> 4 <script> 5 var Child = { 6 template:`<div>i am child!</div>`, 7 replace:false 8 } 9 var Parent = { 10 template:`<div>//This wrapping element can't use template tag now. It used to be. 11 <p>i am parent</p> 12 <br/> 13 <child-component></child-component> 14 </div>`, 15 components:{ 16 'childComponent':Child//Referencing other local components directly in the local component template 17 } 18 } 19 new Vue({ 20 el:'#example', 21 components:{ 22 didiComponent:Parent 23 } 24 }) 25 </script>
Data transmission
- props
- Component Communication
- slot
2.1 Data transmission through props:
The data transmission channel is established by adding HTML features to the component custom tag by v-bind.
Bind the data passed on the custom label on the component field props;
1 <div id="example"> 2 <!--take vue Data in an instance resultsList Binding to custom features list upper--> 3 <didi-component :list="resultsList"></didi-component> 4 </div> 5 <script> 6 //Binding data 7 var Child = { 8 props:['list'],//By customizing features list Getting the resultsList 9 template: `<div> 10 <p> 11 <span>Full name</span> 12 <span>Chinese</span> 13 <span>Mathematics</span> 14 <span>English</span> 15 </p> 16 <ul> 17 <li v-for="item in list" :key="item.name"> 18 <span>{{item.name}}</span> 19 <span>{{item.results.language}}</span> 20 <span>{{item.results.math}}</span> 21 <span>{{item.results.english}}</span> 22 </li> 23 </ul> 24 </div>` 25 } 26 var vm = new Vue({ 27 el:'#example', 28 components:{ 29 didiComponent:Child 30 }, 31 data:{ 32 resultsList:[ 33 { 34 name:"Zhang San", 35 results:{language:89,math:95,english:90} 36 }, 37 { 38 name:"Li Si", 39 results:{language:92,math:76,english:80} 40 }, 41 { 42 name:"Wang Wu", 43 results:{language:72,math:86,english:98} 44 } 45 ] 46 } 47 }); 48 </script>
From the example above, you can see the process of getting data from the parent component by the child component. You must have a question, what is the role of props here, and why do you need the field of props?
a. Each component has its own independent instance model to manage its own attributes. The data needed by the parent component can be obtained through props, and the data reference can be cached by its own attributes to improve the efficiency of program execution. If the data on the parent component is received wholly, it will be great for the child component itself. The amount of redundant data, on the contrary, reduces the efficiency of program execution.
b. Through the data verification of props, the correct data can be obtained and the reliability of the program can be improved.
2.2props receiving data and checking processing:
1 //Receiving data from parent components through customized features in the form of arrays 2 props:['data1','data2','data3'...]//Array receiving mode is only responsible for data receiving, not data checking and processing. 3 4 //Receiving data from parent components through custom features in object form 5 props:{ 6 data1:{ 7 type:Array,//Verify that the received data type is Array,type The value can also be an array, and adding data can meet the validation of multiple data types. 8 default:[{name:"I am the default parameter",...}],//When data1 When no data is received, the component uses default data rendering 9 required:true,//Checkout must receive data, or even if there is default data, it will print out an error message in the console. 10 validator(value){//Check data specific information, parameters value Received is the transmitted data, if the method returns false If the data does not meet the requirement, the console prints out an error message. 11 return value.length < 1; 12 } 13 }
Data validation can only ensure that relatively accurate error prompts are printed on the console when there are data errors, and it will not prevent data rendering, nor will it block the subsequent code execution.
2.3 stack memory transfer and one-way data flow
1 <div id="example"> 2 Parent objects pass values:<input type="text" v-model="info.name"/> 3 The parent object property passes values:<input type="text" v-model="obj.name"> 4 The parent string passes the value:<input type="text" v-model="name"> 5 <child v-bind:msg1.sync="info" v-bind:msg2="obj.name" v-bind:msg3="name"></child> 6 </div> 7 <script> 8 new Vue({ 9 el:'#example', 10 data:{ 11 info:{ 12 name:'Free ride' 13 }, 14 obj:{ 15 name:"Special train" 16 }, 17 name:"Express train" 18 }, 19 components:{ 20 'child':{ 21 props:['msg1','msg2','msg3'], 22 template:` <div> 23 Receiving object transfers value:<input type="text" v-model="msg1.name"/> 24 Receiving object property values:<input type="text" v-model="msg2"> 25 Receive string transfer values:<input type="text" v-model="msg3"> 26 </div>` 27 } 28 } 29 }) 30 </script>
Example effect:
Through the example, we can see that the value of the vue parent-child component is passed by the one-way data stream from parent to child. When the parent data changes, the child data will change. But at the same time, because stack memory assignment is used to transfer values, if the parent passes the reference value type data to the child, changing the data in the child will also cause the change of the parent data.
Note: In the authoritative guide, it is said that data can be controlled by adding modifiers on CE and sync to data delivery, but the two-way binding is not valid in 2.x test, but adding these modifiers does not report errors. On this issue, I think it should be version updating and optimization, but I can not be sure, after all, I have not used the previous version, nor read the manuals and source code of the previous version, this point is temporarily reserved.
Because vue parent-child component uses stack memory to transfer values, there is no way to guarantee the one-way transfer of data. The solution to this problem is simple. It is OK to save the data in the sub-component by cloning the data and using its own data reference, but it should be noted that declaring data in the sub-component requires the use of function type.
Note: Even if the data transmitted is the original value type, do not use the received data directly. Although the program can run normally, the vue alarms the behavior of using the original value directly in the console, so the correct way to receive the data is to create a data on the data of the sub-component itself after receiving the data through props. Copies are used.
data(){ return{ //Self Data Reference Name: Receiving Cloned Data from Reference Data Passed by Parent } }
Component Communication
In the previous section, we introduced the data transfer of parent-child components. We know that vue uses one-way data flow, which means that when a child component needs to pass values to the parent component, it needs other means. After all, more often than not, the child component is likely to have reusability, so the child component can not directly change the data of the parent component. But there will always be a lot of requirements for us to pass the calculation results of the child component to the parent component.
Vue defines events on the parent scope, and then uses $emit by the child component to deliver events. When dispatched to the corresponding event scope, it triggers the event callback function using the dispatched parameters (data), which is called component communication. Component communication can solve the problem of child components passing values to parent components.
An example of component communication in which a complete child component passes values to a parent component1 <div id="example"> 2 <!-- adopt transmitdata Receive the transfer instructions from the child component, and then trigger the parent component's addComData Method --> 3 <comment-complate @transmitdata="addComData"></comment-complate> 4 <ul> 5 <li v-for="item in comList" :key="item.id"> 6 <div> 7 <span class="userName">{{item.userName}}</span> 8 <span class="comDate">{{item.date}}</span> 9 </div> 10 <div>{{item.val}}<div> 11 </li> 12 </ul> 13 </div> 14 <script> 15 var comment = { 16 template: `<div> 17 <textarea v-model="comVal"></textarea> 18 <p><button @click="submitData">Submission</button></p> 19 </div>`, 20 data(){ 21 return { 22 userId:1001, 23 userName:"Snow Tread in Other Countries", 24 comVal:"" 25 } 26 }, 27 methods:{ 28 submitData(){ 29 console.log(this.comVal + 'a'); 30 var comDate = new Date(); 31 let comData = { 32 id:Number(''+this.userId + comDate.getTime()), 33 userName:this.userName, 34 date:comDate.toLocaleDateString() + ' ' + comDate.toLocaleTimeString(), 35 val:this.comVal 36 } 37 this.$emit('transmitdata',comData);//adopt $emit Listen for the click event of submitting a message and pass the data to the custom method when triggered transmitdata 38 } 39 } 40 } 41 var vm = new Vue({ 42 el:'#example', 43 components:{ 44 commentComplate:comment 45 }, 46 data:{ 47 comList:[ 48 { 49 userName:"Nandu Valley Owner", 50 id:1001, 51 date:'2019/7/8 00 a.m.:32:55', 52 val:'2017 At Ruyuan Site in the southeast corner of Changchun Garden, the workers were carrying out the project in 1986.' 53 } 54 ] 55 }, 56 methods:{ 57 addComData(data){ 58 //transmitdata When a custom event receives a request for data transfer, it hands over the transferred data to the user. addComData Handle 59 this.comList.unshift(data); 60 } 61 } 62 }); 63 </script>