React Vue development guide
preface
Vue and React are two of the top three popular frameworks for the front end, and it’s hard to explain how popular they are in China. I have worked in many teams, and the first impression of the team that chooses Vue is that Vue is simple and easy to use. So is Vue really as simple as many developers claim? Can a React front-end app get started quickly? This article will introduce the simple use, features and comparison of Vue from the perspective of React development.
This article is intended for:
- React app that was forced to change the Vue framework by the boss
- Want to try Vue’s React app
- Vue, React shallow use, want to learn more about one of the program ape
To read this article, you need to know the following:
- Understand the direction of this
- Understand the syntax of ES6 classes, destruct assignments, and arrow functions
In addition, if you find it more convenient to view documents, here is a portal: cn.vuejs.org/index.html
Vue profile
Take a look at how Vue is defined on the website:
Progressive JavaScript framework
What’s incremental: As opposed to out of the box, the size of the framework is flexible depending on the size of your desired project. Vue ontology only provides the most basic data-view rendering function. If you want to use modular development, you can use @vue/ CLI. If you want to introduce routing, you can add VUex. If this is not enough, you can also introduce third-party or self-written plug-ins. Talk is cheap, show you the code
Extremely brief experience
Save the following code as an.html file and you’ll see it when you open it in your browser (Internet connection) :
<! DOCTYPEhtml>
<html>
<head>
<title>Simple Vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app"></div>
<script type="text/javascript">
const template = `<h3>{{ message }}</h3>`;
new Vue({
data() {
return {
message:; 'Hello Vue! '
}
}
}).$mount('#app')
</script>
</body>
</html>
Copy the code
The effect would be something like:
Hello Vue!
This approach, similar to jQuery, can be developed as soon as vue scripts are introduced.
Intuitive comparison
If modular development is required, it is difficult to write VUE code in HTML alone. Let’s look at a single-file component created with the scaffolding tool: This time it’s simple and implement a form with only a title and name: React
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class Cart extends Component {
// Attribute type check
static propTypes = {
title: PropTypes.string;
}
// The state of the component
state = {
name: 'John Smith'
}
onChange = (e) = > {
this.setState({
name: e.target.value
})
}
submit = () = > {
alert('Your name is:${state.name}`)}// Render the view
render() {
const {
props: { title },
state: { name },
onChange,
submit
} = this;
/ / JSX template
return (
<div>
<h3>{title}</h3>
<input value={name} onChange={onChange} />
<button onClick={submit}>submit</button>
</div>)}}Copy the code
Ok, this is OOP, let’s see how Vue works:
<template>
<div>
<h3>{{title}}</h3>
<input v-model="name" />
<button @click="submit">submit</button>
</div>
</template>
<script>
export default {
// Declare attributes
props: {
title: String
},
// Declare the status
data() {
return {
name: "John Smith"}},/ / callback
methods: {
settle() {
alert('Order successful, total price:The ${this.total}`)}}}</script>
Copy the code
It’s very methodical, it looks very regular, it looks like YOU’re writing HTML. Here are the features of Vue components:
- Vue components exist in a single file with the suffix
.vue
The JavaScript logic has become written configuratively. template
Double curly braces{{}}
Used as a placeholder to insert expressions- Tag attribute ratio
JSX
Complex, but the realization of the function is more. - status-representative
data
Attribute should be written as a function for the reasons below.
Concept of carding
Introduce the Template
Template is the template syntax that Vue uses to compose UI views. There are two ways to use it:
- If you are using scaffolding to create an engineered Vue project, you can create a new.vue file:
<template>
<div class="my-div">This is a.vue file that represents a component</div>
</template>
<script>
/ / JavaScript logic
export default {}
</script>
<style>
/* Here you can write CSS */
.my-div {
width: 300;
height: 100;
}
</style>
Copy the code
Vue compiles the above code into JavaScript code through a compilation tool.
- If used in pure JavaScript, template is written as a string:
const MyComp = {
template: '
This is also a vue component
}
Copy the code
MyComp’s template template is a render function, not HTML.
{
render(createElement) {
return createElement('div', { staticClass: 'my-div'}, 'This is also a VUE component')}}Copy the code
More on the render function below
The Template instruction
Instructions are special attributes of Vue. With the help of Vue’s rich instructions, many data and view interaction functions can be completed:
V-bind — Expression binding instruction
Normal attributes are treated as strings, whereas V-Bind parses JavaScript expressions inside them
<my-comp v-bind:value="myValue * 2" />
Copy the code
Where myValue is a variable that you define that can come from components like data, props, methods, etc. V-bind is too long to bind.
<my-comp :value="myValue * 2" />
Copy the code
V-on — Callback binding instructions
Similar to v-bind, v-on is used to bind callbacks:
<my-comp v-on:change="handleChange"/ > <! -- Arguments can be passed in and will not be executed immediately --><my-comp v-on:change="handleChange(1, 2, 3)" />
Copy the code
Abbreviations:
<my-comp @change="handleChange" />
Copy the code
V-model — Bidirectional binding instructions
This is a compound directive for bidirectional binding of form elements or custom components, typically used in form elements such as input and textarea:
<input v-model="inputValue" />
Copy the code
Is equivalent to
<input :value="inputValue" @input="e => inputValue = e.target.value" type="text" />
Copy the code
V-for — Loop instruction
Often used for list rendering, remember to include a key
<li v-for="(item, index) in list" :key="item.id">{{index}} - {{item.name}} </li>
Copy the code
In addition to arrays, you can also use strings, objects, and even write a number to indicate the number of cycles.
<span v-for="num in 6">{{num}}</span>
Copy the code
V-if/V-else — Conditional render instruction
As the name implies, conditions determine whether elements are rendered or not
<div v-if="scrore >= 100"> You are full marks </div><div v-else-if="scrore >= 60">You passed</div>
<div v-else>You hang up</div>
Copy the code
Note: When v-if is false, vue skips this node directly. If you want to render an element with style display: None, you can use the v-show command
<div v-show="false"> I'm in HTML, but display is none</div>Copy the code
Child node rendering
As with children in JSX, bytes in template need to use slots as placeholders:
<div> this is default <slot></slot> </div> <! You can also bind slots with namespaces --> <div>this is named <slot name="bar"></slot><div>
Copy the code
The parent passes in:
<! --this is default child node -->
<Foo>
<span> child node </span>
</Foo><! --this is named bar node -->
<Foo>
<span slot="bar"> bar node </span>
</Foo>
Copy the code
If you don’t use Template
Although template can cover most view scenarios, it is not the only option. The Vue component API provides the render function option to create the virtual DOM directly using JavaScript methods:
export default {
render(createElement) {
return createElement('h3'.null.'Hello Vue! ')}}Copy the code
emmmm… Tag properties Child node… Is there a sense of deja vu? React creates the virtual DOM by calling createElement in the Render method instead of JSX. The question is: Can you write Vue components using JSX? Yes, the Babel plugin @vue/ babel-Preset – JSX is available for JSX to write VUE component views. For details, see cn.vuejs.org/v2/guide/re…
A long story of this — Vue
This is a love-hate thing, but in Vue components, most methods refer to this and don’t need to differentiate between props and data:
export default {
props: {
propA: Number.propB: String,},data() {
console.log(this.propA); // propA passed the value
console.log(this.propB); // propB the value passed in
return {
dataA: 'a'.dataB: 'b',}},methods: {
getDataA() {
return this.a;
},
getPropA() {
return this.propA;
},
getMethodA() {
console.log(this.getDataA); // function
console.log(this.getPropA); // function}},/ /...
}
Copy the code
Note: The arrow function’s this does not refer to the current component as you would expect. Except for data, the first argument can access the current component. Write the method as an arrow function.
export default {
props: {
count: Number,},data: context= > ({
doubleCount: context.count * 2 // work, context refers to the current component
}),
methods: {
// Bad, this is wrong
badTripleCount: () = > this.count * 3; }}Copy the code
However, it is possible to use arrow functions inside the method scope, which should be distinguished
export default {
data() { return { user: ' '}}methods: {
// funtion
getUser() {
console.log(this.user); / /"
fetch('/user').then(res= > {
this.user = res;
console.log(this.user); // res valule})}}}Copy the code
In addition to Data and methods, watch, computed, or partially declared periodic hook callbacks, this also points to the current component. If you don’t like this, try the Composition API
Component state — data
In React, the component state is placed in state. To change the state, call setState and use a new object instead:
class Foo extends Component {
state = {
list: [{id: 1.name: 'foo' },
{ id: 2.name: 'bar' },
{ id: 3.name: 'baz']}},removeItem(id) {
const { list } = this.state;
this.setState(list.filter(i= >i.id ! == id)) } }Copy the code
In Vue, the component’s state is called data, but most updates can be done by assigning values directly to properties:
export default {
data() {
return {
a: 1.list: [1.2.3]}},methods: {
setA(num) {
this.a = num;
},
appendToList(num) {
this.list.push(num); }}}Copy the code
As for the implementation principle, you can move to contextual responsive data.
Unidirectional data flow
As with React, the state from the parent component is called Props, and the child component does not directly modify the state passed by the parent component:
export default {
props: {
title: String,},methods: {
badSetTitle() {
// BAD, do not modify directly
this.title = '?????? '}}}Copy the code
If you want to change it, use the Props callback:
export default {
props: {
value: String.onChange: Function
},
methods: {
setValue(value) {
this.onChange(value); }}}Copy the code
The parent component modifies it by passing in the onChange callback:
<template>
<MyComp :value="myValue" :onChange="handleChange" />
</template>
<script type="text/javascript">
export default {
data() {
return {
myValue: ' '}},methods: {
handleChange(value) {
this.myValue = value
}
}
}
</script>
Copy the code
Or update syntactic sugar with Vue convention events:
export default {
props: {
title: String,},methods: {
setTitle() {
this.$emit('update:title'.'????? ')}}}Copy the code
Then the prop passed in by the parent component is also processed:
<! -- The title attribute appends.sync to ensure that the update event takes effect --><MyComponent title.sync="title" />
Copy the code
Note: This method will be deprecated in Vue3.0. There is an alternative: encapsulate value and onChange as V-models (sorry, template compilation is optional) :
<template>
<input placeholder="type something" value="value" @change="e => onChange(e.target.value)" />
</template>
<script>
export default {
model: {
value: 'value'.event: 'change'}}</script>
Copy the code
The parent component can be fixed with a V-Model:
<my-input v-model="myValue"/ > <! -- equivalent to --><my-input :value="myValue" @change="e => myValue = e.target.value" />
Copy the code
Lifecycle hook
Components are not persistent. Each Timing process can handle logic from creation, update, and destruction. Here are some common lifecycle hooks:
beforeCreate
Vue mounts to component instance componentsdata
、props
Wait state before callingcreated
Component mounteddata
、props
And so on, where you can make a network request to get datamounted
The correspondingcomponentDidMount
This is where the component makes a network request to retrieve data after it has first completed DOM renderingupdated
The correspondingcomponentDidUpdate
Called after the component has been updated. Due to the Vue responsive mechanism, this method is mostly used in scenarioswatch
Alternative.beforeDestroy
The correspondingcomponentWillUnmount
A callback before component destruction, usually used to clear timers, certain native listening events, and so on.
Other hooks such as beforeMount, Actived, and deStoryed can be found at cn.vuejs.org/v2/api/#%E9…
features
With comparisons out of the way, let’s talk about some of Vue’s features:
Responsive data
If you’re not familiar with reactive properties, it might be surprising to see that assignments can also trigger updates. In fact, the Vue2. X version uses object.defineProperty to intercept get and set of reactive data, causing the status assignment to trigger update callbacks for update operations.
let valueA = 1;
let data = {};
Object.defineProperty(data, 'a', {
get() {
console.log('access to data. A')
return valueA
},
set(newVal) {
console.log('update data. A') valueA = newVal; }})// data = {a: 1}
data.a // Print "get data.a"
data.a = 100 // Print "update data.a"
Copy the code
Although Object.defineProperty can make updates more intuitive, the API has its limitations:
- It can only detect the update of object attributes, but cannot detect the addition and deletion of object attributes
data.b = 1
Assignment ordelete data.a
Delete, set callback is not triggered. Need to useVue.set(data, 'b', 1)
和Vue.delete(data, 'a')
Make explicit additions and deletions. - For the array
push
、pop
、splice
Vue implicitly overrides methods that change the original array so that calls to the array are normally listened on.
In Vue3. X, the Proxy API is used instead of Object.defineProperty:
const data = { a: 1 };
const proxyData = new Proxy(data, {
get(obj, key) {
console.log('access to data. A')
return obj[key];
},
set(obj, key, value) {
console.log('update data. A') obj[key] = value; }})const proxyArray = new Proxy([1.2.3] and {get(obj, key) {
console.log(Get the array [key] ')
return obj[key];
},
set(obj, key, value) {
console.log('update array [key]') obj[key] = value; }})Copy the code
Proxy can intercept object changes more elegantly, which solves the problem of adding and deleting attributes and intercepting arrays. Moreover, it does not need to intercept every attribute, which reduces the cost of monitoring data to a certain extent. Compared to React, Vue tracks data changes in more detail, minimizing the granularity of component updates.
Data should be a function
One question you might have noticed from looking at the previous code is: Why is data a function? This is to avoid creating multiple components where references to the same data will affect each other:
const MyComponent = {
data: {
a: 1}}// Instantiate the component's pseudo-code
const initComponent(comp) {
const compInstance = {};
for(const key in comp.data) {
compInstance[key] = data[key];
}
return compInstance;
}
const comp1 = initComponent(MyComponent)
const comp2 = initComponent(comp1)
comp1.a = 2;
console.log(comp1.a); / / 2
console.log(comp2.a); / / 2
Copy the code
How to avoid the above problems? You might want to make a deep copy of a component, but this would be an unnecessary performance waste. To gracefully solve this problem, we agree that data should be made into a function that returns an object:
const MyComponent = {
data() {
return {
a: 1}}}// Instantiate the component's pseudo-code
const initComponent(comp) {
const compInstance = {};
for(const key in comp.data()) {
compInstance[key] = data[key];
}
return compInstance;
}
// ...
console.log(comp1.a); / / 2
console.log(comp2.a); / / 1
Copy the code
Asynchronous updates to the DOM
Like React, Vue also creates a virtual DOM and transforms the virtual DOM into the real DOM through a series of Diff algorithms and patches. When does the real DOM in Vue update? The answer is to use JavaScript event loops to asynchronously update the next microtask after a state change:
<template>
<div id="msg">{{ message }}</div>
</template>
<script>
export default {
data() {
message: 'hello world'
},
setData() {
document.getElementById('msg').innerHTML // 'hello world';
this.message = 'goodbye world';
// The DOM has not yet been updated
document.getElementById('msg').innerHTML // 'hello world';
// The DOM has been updated for the next microtask callback
this.$nextTick(() = > {
document.getElementById('msg').innerHTML // 'goodbye world';
})
// Oh, it is a macro task, it has been updated for a long time
setTimeout(() = > {
document.getElementById('msg').innerHTML // 'goodbye world';
}, 0)}}</script>
Copy the code
summary
This article is a mirror of the React Developer’s Guide to getting started with Vue. It introduces the features and usage of Vue from the perspective of React developers. It aims to guide some React to Vue applications quickly. Avoid some of the React stereotypes that get in the way of Vue development.
Question and answer session
I feel like I can’t finish. What else can I tell you?
It would be impractical to compress Vue into a few hundred lines, so this article will focus on React. If you want to dig deeper, here are some common usage and configuration recommendations, check the documentation with these questions in mind:
- Vue global configuration
- Usage of plug-ins
- Custom instruction
- The computed and watch
- Provide/Inject Dependency injection
- Component instance methods (there are a lot of things mounted on component this)
- Built-in component
Vue has many similar apis, which one should I use?
Vue. Js: Which of those similar apis should I use? Vue API usage competition