Abstract: Understand Vue components!
- Author: Sailing in the waves
- The three core concepts of the VUE component are explained in detail
FundebugReproduced with authorization, copyright belongs to the original author.
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.
/ / the parent component<props name='properties'
:type='type'
:is-visible="false"
:on-change="handlePropChange"
:list=,33,44 [22]
title="Attribute Demo"
class="test1"
:class="['test2']"
:style="{ marginTop: '20px' }"/ / note:styleThe priority is higher thanstyle
style="margin-top: 10px">
</props>// 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
/ / the parent component<template>
<div class="hello">
<div>
<p>MSG: {{MSG}}</p>
<p>Parent component array: {{arr}}</p>
</div>
<button @click="show = true">Open the model box</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>/ / child component<template>
<div v-if="show" class="border">
<div>MSG: {{MSG}}</div>
<div>Array of subcomponents: {{arr}}</div>
<button @click="closeModel">Close the model box</button>
<button @click=$emit('update: MSG ', 'emit ')">Change the text</button>
<button @click="Arr. push(' Front End Craftsman ')">Change the array</button>
</div>
</template>
<script>
export default {
props: {
msg: {
type: String
},
show: {
type: Boolean
},
arr: {
type: Array // Changing the array passed in the child affects the state of the parent}},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>The 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">The component content</custom-component>
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
<! -- Prevent the click event from propagating -->
<a v-on:click.stop="doThis"></a>
<! Submit events no longer reload the page -->
<form v-on:submit.prevent="onSubmit"></form>
<! -- modifiers can be concatenated -->
<a v-on: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)?
/ / the parent component<template>
<div class="toList">
<input v-model="info" type="text" /> <button @click="addItem">add</button>
<ul>
<TodoItem v-for="(item, index) in listData" :key="index">
<template v-slot:item="itemProps">// This is a named slot // where the value of 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>/ / child component<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. Here’s an example of the new syntax for default slots, named slots, and scoped slots:
/ / the parent component<template>
<div class="helloSlot">
<h2>2.6 the new grammar</h2>
<SlotDemo>
<p>Default slot: Default slot</p>
<template v-slot:title>
<p>Named slot: title slot1</p>
<p>Named slot: Title slot2</p>
</template>
<template v-slot:item="props">
<p>Scope slot: item slot-scope {{props}}</p>
</template>
</SlotDemo>
</div>
</template>
<script>
import Slot from "./slot";
export default {
components: {
SlotDemo: Slot
}
};
</script>/ / child component<template>
<div>
<slot />
<slot name="title" />
<slot name="item" :propData="propData" />
</div>
</template>
<script>
export default {
data() {
return {
propData: {
value: "Boat on the waves."}}; }};</script>
Copy the code
To recommend a good BUG monitoring toolFundebug, welcome free trial!
reference
- Five ways to handle Vue exceptions
- This article is enough for getting started with Vue development
- Fundebug releases Vue plug-ins to simplify BUG monitoring access code
- There are six modes of communication between Vue components
About Fundebug
Fundebug focuses on real-time BUG monitoring for JavaScript, wechat applets, wechat games, Alipay applets, React Native, Node.js and Java online applications. Since its official launch on November 11, 2016, Fundebug has handled over 1 billion error events in total, and paid customers include Sunshine Insurance, Lychee FM, Zhangmen 1-on-1, Walnut Programming, Weimai, Qingtuanshe and many other brand enterprises. Welcome free trial!