vue entry: (component)

  • 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.

 1 <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>
An example of component communication in which a complete child component passes values to a parent component

If the event used to receive data transmission is a native DOM event, it is not necessary to use $emit() to listen for event triggering. It is only necessary to add a'. navite'suffix after the declaration of the original event to automatically trigger the listening event. The native event itself is monitored by the browser itself, so it is not necessary to use more. The rest of the operation. For example: @click.navite= "Event listening methods for parent components".

<comment-complate @click="addComData"></comment-complate>

4. Slots and Dynamic Components

4.1 slot: < slot > </slot >

Sometimes it is necessary to add some node content to the child component in the parent component, which can be achieved by using slot, and also by using named slot in the child component to insert the node at the specified location. Examples:

 1 <div id="app">
 2     <child>
 3         <span>{{titleName}}: </span><!--Insert slot-->
 4     </child>
 5 </div>
 6 <script>
 7     var vm = new Vue({
 8         el:'#app',
 9         components:{
10             child:{
11                 template:`  <div>
12                                 <slot></slot><!--Define slots-->
13                                 <input type="text" />
14                             </div>`
15             }
16         },
17         data:{
18             titleName:'mailbox'
19         }
20     });
21 </script>

Through the above slot function, the titles of input boxes can be dynamically switched. In some requirements, there are many ways of content input, so there is no need to define multiple components to realize it. Only the parent component is needed to switch the input headings, and the sub-component is only responsible for the input operation, so that multiple inputs can be realized on the same component. Enter the scene.

With multiple content input scenarios, it is necessary to have multiple input prompts. This input prompt must be matched with the input title. The data must be on the same parent component as the title content, and multiple slots are needed to implement it. At this time, a named slot is needed:

 1 <div id="app">
 2     <child>
 3         <span slot="title">{{titleName}}: </span><!--Insert header slot-->
 4         <span slot="hint">{{hint}}</span>
 5     </child>
 6 </div>
 7 <script>
 8     var vm = new Vue({
 9         el:'#app',
10         components:{
11             child:{
12                 template:`  <div>
13                                 <slot name="title"></slot><!--Define label named slot-->
14                                 <input type="text" />
15                                 <slot name="hint"></slot><!--Define Tip Named Slot--> 
16                             </div>`
17             }
18         },
19         data:{
20             titleName:'mailbox',
21             hint:"Please enter the correct email address"
22         }
23     });
24 </script>

Named slots can insert the parent inserted nodes into the specified place. Of course, you will say that it is feasible to switch these data directly on the sub-components, but the implementation of using sub-components will inevitably involve the transfer of values from the parent to the child components. Maybe you would also think that such a function can also be implemented using a parent component. Why use a child component? This is certainly possible, but it also involves another question, if it is a more complex requirement? Therefore, there is no absolute design advantage, which depends on specific requirements. If it is in more complex requirements, input operations and business logic can be separated through component level through slotting.

In addition to the above applications, slots will also play an important role in the next dynamic components.

4.2 Dynamic Components:

The so-called dynamic component is to define a sub-component in the parent component, which can be introduced into different sub-components through data switching. At this time, you must think that this can not be achieved through v-if and v-else? Note that the combination of v-if and v-else can only achieve two component switching, and two sub-components need to be introduced into the parent component, which is far from the dynamic component that only needs one sub-component and can switch the functions of multiple sub-components.

Syntax: <component is="bind specified subcomponents"></component>

Examples:

 1 <div id="app">
 2     <button @click="chanegCmp">Switching component</button>
 3     <component :is="cmpType"></component>
 4 </div>
 5 <script>
 6     const cmpOne = {
 7         template:`  <div>
 8                         <span>Fig. 1:</span>
 9                         <input type="text" />
10                     </div>`
11     }
12     const cmpTwo = {
13         template:`  <div>
14                         <span>Component 2:</span>
15                         <input type="text" />
16                     </div>`
17     }
18     const cmpThree = {
19         template:`  <div>
20                         <span>Component 3:</span>
21                         <input type="text" />
22                     </div>`
23     }
24     var vm = new Vue({
25         el:'#app',
26         data:{
27             cmpList:["cmpOne","cmpTwo","cmpThree"],
28             cmpType:"cmpOne",
29             cmpPresent:0
30         },
31         components:{
32             cmpOne:cmpOne,
33             cmpTwo:cmpTwo,
34             cmpThree:cmpThree
35         },
36         methods:{
37             chanegCmp(){
38                 console.log(this.cmpPresent  + ' - ' + this.cmpList.length)
39                 if( (this.cmpPresent + 1) === this.cmpList.length){
40                     this.cmpPresent = 0;
41                     this.cmpType = this.cmpList[this.cmpPresent];
42                 }else{
43                     this.cmpPresent ++;
44                     this.cmpType = this.cmpList[this.cmpPresent];
45                 }
46             }
47         }
48     });
49 </script>

Example implementation effect:

Although components can be switched through dynamic components, the above example may not be what we want, because the state of components can not be preserved when switching components. For example, when we switch components for the first time, when we switch back to this component for the second time after entering text, the input text can not be preserved. That is to say, the component switched back is a new rendering component, not the original component.

In response to this requirement, vue provides me with a label < keep-alive> that wraps the component label to preserve the state of the sub-component, so the code in the example can be modified as follows:

1 <keep-alive>
2     <component :is="cmpType"></component>
3 </keep-alive>

4.3 Scope Slot

In the previous 4.1, I introduced slots, which can define relatively flexible child components at the parent level. In the previous example, I just introduced that the parent inserts some element nodes at the child level designated as the node location. At this time, I think it should trigger another thought, since slots can define child-level specificity at the parent level. Located nodes, can we implement parent scopes to define child-specific data templates? That is to say, the child level can not only provide a placeholder, but also provide data reference to realize the node and data rendering of defining elements in the parent component. It's a bit of a twist to describe it in words. Let's start with a small example:

 1 <div id="app">
 2 < child: UserData = "user"> <! -- Gets the data user of the parent component and defines the new reference name userdata-->.
 3 < template slot-scope= "list"> <! - Data template receives data from slot through slot-scope feature, and defines index name list - >.
 4 <span>{{list.username} - {{list.userCom} </span> <! - - - Data is extracted from the data index received by the template and rendered to the page - > 4 <span> {list.username} - {list.userCom} </span> <!.
 5         </template>
 6     </child>
 7 </div>
 8 <script>
 9     const child = {
10 props: ["userdata"], // Receiving data UserData from parent components,
11         data(){
12             return{
13                 comData:"child"
14             }
15         },
16         template:`  <div>
17 <! -- Pass the data received from the parent component and the data from the child component itself to the template through the slot - > 1.
18 <! - The way to transfer data is to pass data into slot labels in a characteristic way - > The way to transfer data is to transfer data to slot labels in a specific way.
19                         <slot
20                         :username="userdata.name"
21                         :userCom="comData"></slot>
22                         <input type="text"/>
23                     </div>`
24     }
25     var vm = new Vue({
26         el:'#app',
27         data:{
28             user:{
29 name: "Snow in another country".
30             }
31         },
32         components:{
33             child:child
34         }
35     });
36 </script>

One of the keys here is to pass out the feature key data of the slot label, then receive the data through the template feature slot-scope, and then provide an example to further understand the scope slot:

 1 <div id="app">
 2     <cmp-two :list="list">
 3         <template slot-scope="list">
 4             <li>{{list.item}} - {{list.index}}</li>
 5         </template>
 6     </cmp-two>
 7     <cmp-two :list="list">
 8             <template slot-scope="list">
 9                 <li>{{list.index}} - {{list.item}}</li>
10             </template>
11     </cmp-two>
12 </div>
13 <script>
14     const cmpTwo = {
15         props:['list'],
16         template:`<div>
17                     Component 2:<input tyle="text">
18                     <ul>
19                         <slot v-for="(item,index) in list" 
20                         :item="item"
21                         :index="index">
22                         </slot>
23                     </ul>
24                     </div>`
25     }
26     var vm = new Vue({
27         el:'#app',
28         components:{
29             cmpTwo
30         },
31         data:{
32             list:[1,2,3,4,5]
33         }
34     });
35 </script>

Keywords: PHP Vue REST

Added by grandeclectus on Mon, 08 Jul 2019 23:56:10 +0300