preface
This article focuses on the three basic vUE concepts of properties, events, and slots, how to use them, and some important details that are easily overlooked. If you are reading components written by others, you can also expand from these three sections, which can help you quickly understand all the functionality of a component.
The code of this article please stamp on github blog, the paper comes from the end of jue shallow, we begin to knock on the code!
A, attributes,
1. Customize properties props
Prop defines the configurable properties of the component and determines the core functionality of the component. When writing general-purpose components, it is better to write props as objects, so that each property can be set to a type, a default value, or a custom validation value. This is important in component development. However, many people neglect to use arrays of props.
// parent component <props name=' properties' :type='type' :is-visible="false" :on-change="handlePropChange" :list=[22,33,44] title=" properties Demo" Class ="test1" :class="['test2']" :style="{marginTop: '20px'}" // note: margin-top: 10px"> </props>Copy the code
// Subcomponent props: {name: String, type: {// The type passed in from the parent must be one of the specified 'success', 'warning', or 'danger' values. If anything else is passed, a warning validator will be thrown: (value) => { return ['success', 'warning', 'danger'].includes(value) } }, onChange: Type: Function, default: () => {}}, isVisible: {type: Boolean, default: False}, list: {type: Array, // Object or Array default values must be obtained from a factory function default: () => []}}Copy the code
From the above example, it follows that props can display and define one or more data, and that for the received data, it can be a variety of data types, as well as passing a function. Parent to child communication through general attributes; Communicate from child to parent through function attributes
2.inheritAttrs
This is an API added in 2.4.0. By default, feature bindings in the parent scope that are not recognized as props will “fall back” and be applied to the root element of the child component as normal HTML features. These default behaviors are removed by setting inheritAttrs to false. Note: This option does not affect the class and style bindings. In the previous example, the title attribute is not declared in props in the child component, so it is hung on the root element of the child component by default, as shown below:
3. The difference between data and props
- The same
Both options can store various types of data, and when the action changes, all the data used by the action and the data rendered by the template changes simultaneously.
- The difference between
Data is called dynamic data. In each instance, we can change its data type and data structure at will without being affected by any environment.
Props is referred to as static data, in each instance, once in the initialization is defined types, based on the Vue is a one-way data streams, the data transfer is always does not change its data type, and does not allow direct manipulation in the child components passed props data, but need to pass through other means, change the transfer of data from a source. As for how to change, we will go into details:
4. Unidirectional data flow
This concept appears in component communication. The props data is passed through the parent component or higher-level component data or literals. It is not allowed to change the props data in the instance. Instead, it is required to change the data in the source. What if we sometimes want to modify a prop passed in?
- Method 1: Transition to the data option
Copy a prop in the child component’s data, which can be modified
export default {
props: {
type: String
},
data () {
return {
currentType: this.type
}
}
}
Copy the code
In the data option, we want to perform an assignment to currentType= type, so we can not only get the currentType, but also change the currentType.
- Method 2: Use computed properties
export default { props: { type: String }, computed: { normalizedType: function () { return this.type.toUpperCase(); }}}Copy the code
The above two methods can modify the props value indirectly in the child component, but they do not help if the child component wants to modify the data and synchronize updates to the parent component. In cases where we may need to “bidirectional bind” a prop, the following two methods are recommended:
- Method 3: Use.sync
MSG: {{MSG}}</p> <p> Array of parent components: {{arr}}</p> </div> < button@click ="show = true"> </button> <br /> <demo :show. Sync ="show" :msg.sync=" MSG" :arr="arr"></demo> </div> </template> <script> import Demo from "./demo.vue"; Export default {name: "Hello", components: {Demo}, data() {return {show: false, MSG: "Simulate a model box ", arr: [1, 2, 3]}; }}; </script>Copy the code
// Subcomponent <template> <div v-if="show" class="border"> {{arr}}</div> < button@click ="closeModel"> </button> < button@click ="arr. Push "> </button> </div> </template> <script> export default { Props: {MSG: {type: String}, show: {type: Boolean}, arr: {type: Array}, methods: {props: {type: String}, arr: {type: Array}, methods: { closeModel() { this.$emit("update:show", false); }}};Copy the code
The parent component passes MSG and show values to the child component props using the.sync modifier. But.sync is great, but it has limitations, like:
1) Cannot be used with expressions (e.g. V-bind :title.sync=”doc.title + ‘! ‘” is invalid); 2) Can’t be used on literal objects (v-bind.sync=”{title: doc.title}” won’t work).
- Method 4: Wrap the data from the parent component into images and pass them to the child component
This is because objects and arrays are passed in by reference in JavaScript, so for a prop of an array or object type, changing the object or array itself in a child component will affect the state of the parent component. For example, in the example above, the state of the parent component is changed by modifying the array ARR passed by the parent component in the child component.
5. With or without V-bind when passing data to child components?
Beginners to literal and dynamic syntax may be confused about whether to add v-bind or not when passing data from a parent component template to a child.
v-bind:msg = ‘msg’
This is passing data through V-bind and the data is not a literal. The double quotes parse an expression, but also data and methods defined on an instance (referring to a variable).
MSG =’ sailing on the waves’
This can only pass a literal without V-bind, and this literal is limited to the String class, which is a String. If you want to pass literals, you must use v-bind before the props name to search internally for the instance. If the instance does not have this property and method, the default is the corresponding data type.
:msg='11111' //Number
:msg='true' //Bootlean
:msg='()=>{console.log(1)}' //Function
:msg='{a:1}' //Object
Copy the code
Second, the event
1. Event driven vs. data driven
Event-driven with native JavaScript usually looks like this:
- First find the node to be operated by a specific selector -> add the corresponding event listener to the node
- The user then performs an event (click, type, back, etc.) -> calls JavaScript to modify the node
This model is fine for the business, but it can be less desirable in terms of development cost and efficiency, especially as business systems grow larger and larger. On the other hand, finding and modifying nodes is inherently inefficient, hence the data-driven model.
One of the core ideas of Vue is data-driven. The so-called data-driven view means that the view is generated by data driving. We modify the view by modifying data rather than directly manipulating DOM. The process is as follows:
The user performs an action -> feedback to VM processing (which can cause Model changes) -> VM layer changes and directly updates the data at the corresponding location of the page through binding relationships
To put it simply: data-driven does not operate on nodes, but updates pages directly through a virtual layer of abstract data. It is mainly because of this that data-driven frameworks are fast (because there are no nodes to mess with) and can be applied to large projects.
2. Modifier events
Vue events are divided into normal events and modifier events, and we focus on modifier events here.
Vue provides a large number of modifiers to encapsulate these filters and judgments, allowing developers to write less code and spend their time on business and logic with only one modifier to call. Let’s start with the question: How do I bind a native click event to this custom component, custom-Component?
<custom-component> Component content </custom-component>Copy the code
If your answer is
, you are wrong. @click is a custom event click, not a native event click. Binding native Click looks like this:
<custom-component @click.native=" XXX ">Copy the code
The actual development process is inseparable from event modifiers, common event modifiers are the following:
- Form modifier
1).lazy
By default, v-Model synchronizes the value of the input box with the data after each input event is triggered. You can change to synchronization using the change event by adding the lazy modifier. This applies to the scenario where the view is updated only after the cursor has left after all content has been entered.
2).trim
If you want to automatically filter whitespace entered by the user, you can add the trim modifier to the V-model:
<input v-model.trim="msg">
Copy the code
This modifier can be used to filter out situations where you accidentally hit a space after entering a password. Note that it can only filter Spaces at the beginning and end! Heads and tails, the ones in the middle don’t filter.
3).number
If you want to automatically convert user input values to numeric types, you can add the number modifier to the V-Model:
<input v-model.number="value" type="text" />
Copy the code
From the example above, you can see that if you enter numbers first, it will limit you to only numbers. If you enter the string first, it’s like not adding the dot number
- Event modifier
<! Continue to spread, stop the click event - - > < v - on a: click. Stop = "doThis" > < / a > <! <form V-on :submit. Prevent ="onSubmit"></form> <! - the modifier can series - > < v - on a: click. Stop. Prevent = "doThat" > < / a >Copy the code
Third, slot
Slots are divided into regular slots and scoped slots, which are very similar except that scoped slots accept arguments passed by child components.
1. Scope slot
Let’s look at the scope slot with a Todolist example. What if the text turns yellow when item is selected (as shown below)?
// Parent <template> <div class="toList"> <input V-model ="info" type="text" /> <button @click="addItem"> <TodoItem v-for="(item, Index) in listData" :key="index"> <template V-slot :item="itemProps"> // This is a named slot // where itemProps is the object passed by the child component <span :style="{ fontSize: '20px', color: itemProps.checked ? 'yellow' : 'blue' }" >{{ item }}</span > </template> </TodoItem> </ul> </div> </template> <script> import TodoItem from "./TodoItem"; export default { components: { TodoItem }, data() { return { info: "", listData: [] }; }, methods: { addItem() { this.listData.push(this.info); this.info = ""; }}}; </script>Copy the code
// Subcomponent <template> <div> <li class="item"> <input V-model ="checked" type="checkbox" /> <slot name="item" :checked="checked"></slot> // Pass the checked value to the parent </li> </div> </template> <script> export default {data() {return { checked: false }; }}; </script>Copy the code
It’s worth noting that the object syntax of V-bind :style is straightforward — it looks a lot like CSS, but it’s actually a JavaScript object. CSS property names can be camelCase or kebab-case delimited (remember to use quotes).
2. V – slot new syntax
In 2.6.0, we introduced a new uniform syntax (the V-slot directive) for named slots and scoped slots. It replaces slot and slot-scope. Let’s consider a question: Should slots with the same name be merged or replaced?
- For Vue2.5, common slots are merged and scope slots are replaced
- Vue version 2.6, all replacements (see examples below)
Here’s an example of the new syntax for default slots, named slots, and scoped slots in Vue2.6:
// Parent component <template> <div class="helloSlot"> <h2>2.6 new syntax </h2> <SlotDemo> <p> Default slot</p> <template v-slot:title> <p> Named slot:title slot</p> <p> named slot: </p> </template> <template V-slot :title> <p>new named slot:title slot1</p> <p>new named slot: Title slot2</p> </template> <template V-slot :item="props"> <p> item slot-scope {{ props }}</p> </template> </SlotDemo> </div> </template> <script> import Slot from "./slot"; export default { components: { SlotDemo: Slot } }; </script>Copy the code
// Subcomponent <template> <div> <slot /> <slot name="title" /> <slot name="item" :propData="propData" /> // propData can be arbitrarily named </div> </template> <script> export default {data() {return {propData: {value: "propData"}}; }}; </script>Copy the code
To recommend a good BUG monitoring toolFundebug, welcome free trial!
Refer to the article
- Everest Architecture Course (highly recommended)
- Vue development practice
- Vue. Js components
- Vue. Js official document
- Vue component communication full disclosure
- Vue modifier – probably the most detailed documentation in the Old Hemisphere (hilarious)