Reusability component details
1. Reasons for using components
Purpose: Improve code reuse
2. How to use components
-
Global registration
Vue.component('my-component', {template:'
I am the content of the component'}) Advantages: All NUE instances can be used. Disadvantages: Too much permission, low fault toleranceCopy the code -
Global registration
let app = new Vue({ el: "#app".components: { "my-component": { template: "
I am the content of the component",}}});Copy the code
Note:
Templates for VUE components are limited by HTML tags in some cases,
For example, a table can only contain < TD > elements, so using components directly in the table is not effective. In this case, components can be mounted using the IS attribute
<table>
<tbody is="my-component">
</tbody>
</table>
Copy the code
3. Weird techniques used by components
- It is recommended to use lowercase plus (must) child, my-Componnet to name components
- The contents of the template must be included in a DOM element, and can be nested
- In the definition of the component, options other than template – data,computed,methods
- Data must be a method
4. Using props to pass data The father passes data to his son
-
Use props in the component to receive parameters from the parent component,
Note: Properties defined in props can be used directly in components
-
Propps comes from the parent, and data return in the component is the component's own data. In both cases, the scope is the component itself, which can be used directly in template, computed, and Methods
-
There are two types of props, one is an array of strings, and the other is an object. In this section, we will focus on arrays
-
You can use vbind to dynamically bind content from the parent component
5. One-way data flow
explain
Passing data through props is a one-way flow, that is, when the parent component changes, it is passed to the child component, but not the other way around.
purpose
The parent component is decoupled as much as possible to prevent the child component from inadvertently modifying the state of the parent component.
Application scenarios
There are two common situations in business that require prop changes
In one case, the parent component passes in an initial value, and the child component stores it as an initial value, which can be used and modified at will in its own scope.
In this case, you can declare another data inside the component data, referencing the parent component’s prop
Step 1: Register components
Step 2: Pass in the parent component’s data and receive it in the child component using props
Step 3: Store the data passed in with the initial value, that is, set up a variable to give it the value
<div id="app">
<my-comp init-count="666"></my-comp>
</div>
<script>
var app = new Vue({
el: "#app".components: {
"my-comp": {
props: ["init-count"].template: "<div>{{init-count}}</div>".data: function () {
return {
count: this.initCount, }; }},}});</script>
Copy the code
In another case, prop is passed in as a raw value that needs to be transformed.
In this case, you can calculate the properties
Step 1: Register components
Step 2: Pass in the parent component’s data and receive it in the child component using props
Step 3: Recalculate the data passed in through the calculation properties
<div id="app">
<inputtype="text" v-model="width">
<my-comp :width="width"></my-comp>
</div>
let app = new Vue({
el:'#app'.data: {width:' '
},
components: {'my-comp': {props: ['width'].template:'<div :style="style">{{init-count}}</div>'.computed: {style:function () {
return{
width:this.width+'px'.background:'red'}}}}}})Copy the code
Data validation
CamelCased and Kebabcase in vue components
@ In HTML, myMessage and myMessage are identical,
Therefore, you must use kebabCase (dash) naming when using HTML in a component.
Hump !!!!!! is not allowed in HTML
@ In a component, the parent must use a dash to pass data to the child.
In template, you must use the camel’s name, if you name a dash, it will be an error.
@ in a component’s data, references to this.XXX can only be humped. An error is reported if a dash is named.
Conclusion: Use humps except in HTML.
type
- String
- Number
- Boolean
- Object
- Array
- Function
Vue.component ('my-compopent', {props: {/ / Must be a numeric typepropA : Number, / / must be a string or number typepropB : [String , Number], / / Boolean, default if not definedtrue
propC: {
type : Boolean ,
default : true}, / / number, and must passpropD: {
type: Number ,
required : true}, / / If it is an array or object, the default value must be a function to returnpropE: {
type : Array ,
default : function () {
return[]; }}, / / a custom validation functionpropF: {
validator : function (value) {
return value > 10; }}}})Copy the code
7. Component communication
Component relationship can be divided into father-child component communication, sibling component communication and cross-level component communication
1. Custom events – Child component passes data to parent component
In addition to monitoring DOM events, v-On can also be used for custom events between components.
JavaScript design pattern-observer, dispatchEvent and addEventListener.
The Vue component has a similar pattern. The child uses emit () to emit events, the parent uses emit () to emit events, the parent uses emit () to emit events, and the parent uses on () to monitor the child’s events.
Direct dump code
Step 1: Customize events
Step 2: Fire the event from the child component with $emit. The first parameter is the event name, followed by the data to be passed
Step 3: Accept the custom event with a parameter
<template> <div id="app"> <p> Hello, your current bank balance is {{total}} yuan </p> <btn-compnent @change="handleTotal"></btn-compnent>{{myString }} </div> </template> <script> export default { name: "App", components: { "btn-compnent": { template: '<div>\ <button @click="handleincrease">+1</button> \ <button @click="handlereduce">-1</button>\ </div>', data: Function () {return (count: 0, myString1: 0, myString2: 0, myString2: 0); }, methods: { handleincrease: function () { this.count += 1; this.$emit("change", this.count, this.myString1); }, handlereduce: function () { this.count--; this.$emit("change", this.count, this.myString2); }, }, }, }, data() { return { total: 0, myString: "", }; }, methods: { handleTotal: function (total, string) { this.total = total; this.myString = string; ,}}}; </script> <style> </style>Copy the code
2. Use vmode in components
$emit code. This line of code will actually fire an input event and the parameter after ‘input’ is the value of the property passed to the VModel binding
The vModel is actually a syntactic sugar that does two things behind it
- V-bind binds a value attribute
- The V-on directive binds the input event to the current element
To use vModel, do:
- Receive a value attribute.
- The input event is raised when a new value is present
<div id="app">
<p>Hello, your current bank balance is {{total}} yuan</p>
<btn-compnent v-model="total"></btn-compnent>
</div>
<script>
var app = new Vue({
el: "#app".data: {
total: 0
},
components: {
"btn-compnent": {
template:
'
\
\
\
'.data: function () {
return {
count: 0
};
},
methods: {
handleincrease: function () {
this.count++; -------- Pay attention. On this line, the emit is the input event ---------this.$emit("input".this.count);
},
handlereduce: function () {
this.count--;
this.$emit("input".this.count); }}}},methods: {
/* handleTotal:function (total) { this.total = total; } * /}}); </sciprt>Copy the code
3. Communication between non-parent components
Sometimes two components also need to communicate (not parent-child).
In simple scenarios, an empty Vue instance can be used as the central time bus
Design instances
<div id="app" >
<my-acomponent></my-acomponent>
<my-bcomponent></my-bcomponent>
</div>
components: {
"my-acomponent": {
template:
< button@click ="handle">
.data: function () {
return {
aaa: "I'm content from component A"}; },methods: {
handle: function () {
this.$root.bus.$emit("lala".this.aaa); }},},"my-bcomponent": {
template: "<div></div>".created: function () {
// The A component listens for the lala event when the instance is created
this.$root.bus.$on("lala".function (value) { alert(value); }); }},},Copy the code
The parent chain: this. $parent
Vue.component("child-component", {
template: .methods: {
setFatherData: function () {
this.$parent.msg = "The data has been revised."; }}});Copy the code
A chain: this. $refs
Provides a way to index a child component by adding an index to it with the special attribute ref
let app = new Vue({
el: "#app".data: {
/ / bus mediation
bus: new Vue(),
msg: "The data has not been revised.".formchild: "Not yet."
},
methods: {
getChildData: function () {
// Use to fetch the contents of the child component ---- $refs
this.formchild = this.$refs.c.msg; }}});Copy the code
4. Use slot to distribute content
1. What is a slot
In order for components to be composable, we need a way to mix the content of the parent component with the child component’s own template.
This process is called content distribution, and vue.js implements a content distribution API,
Use the special ‘slot’ element as the slot for the original content.
2. Scope for compilation
Before diving into the content distribution API, let’s clarify in which scope the content is compiled. Assume the template is:
<child-component>
{{ message }}
</child-component>
Copy the code
Should Message be bound to the parent component’s data or to the child component’s data?
The answer is the parent component.
Component scope is simply:
The contents of the parent component template are compiled in the parent component scope;
The content of the subcomponent template is compiled in the subcomponent scope.
3. Usage of slots
The content of the parent component is mixed with the child component to compensate for the view
Mix the content of the parent component with the child component’s own template
Single slot:
<div id="app">
<my-component>
<p>I am the content of the parent component</p>
</my-component>
</div>;
Vue.component("my-component", {
template:
"
\
\ IF the parent component does not insert content, I will appear as default \
\
"
});
Copy the code
Named slot:
<name-component>
<h3 slot="header">I am heading</h3>
<p>I'm the body content</p>
<p>There are two paragraphs in the body</p>
<p slot="footer">I'm the bottom message</p>
</name-component>
Copy the code
Vue.component("name-component", {
template:
'
\
\n'
+
' <slot name="header">\n' +
" \n" +
" </slot>\n" +
"</div>\n" +
'<div class="contatiner">\n' +
" <slot>\n" +
" \n" +
" </slot>\n" +
"</div>\n" +
'<div class="footer">\n' +
' <slot name="footer">\n' +
"\n" +
" </slot> \n" +
"</div>" +
" </div>"
});
Copy the code
4. Scope slot
A scoped slot is a special kind of slot,
Replace rendered elements with a reusable template
Get data from child components
The template template is not rendered
Vue.component("my-component", {
template:
'< div > \ < slot text = "I am data from the child components" ss = "FDJKFJLSD" name = "ABC" > \ < / slot > \ < / div >'
});
Copy the code
5. Accessslot
Through this. $slots. (NAME)
mounted:function () {
// Access the slot
let header = this.$slots.header;
let text = header[0].elm.innerText;
let html = header[0].elm.innerHTML;
console.log(header)
console.log(text)
console.log(html)
}
Copy the code
5. Advanced usage of components – Dynamic components
VUE provides us with an element called Component
Used to dynamically mount different components
Implementation: implemented using is features