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:

  1. Vue components exist in a single file with the suffix.vueThe JavaScript logic has become written configuratively.
  2. templateDouble curly braces{{}}Used as a placeholder to insert expressions
  3. Tag attribute ratioJSXComplex, but the realization of the function is more.
  4. status-representativedataAttribute 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:

  • beforeCreateVue mounts to component instance componentsdatapropsWait state before calling
  • createdComponent mounteddatapropsAnd so on, where you can make a network request to get data
  • mountedThe correspondingcomponentDidMountThis is where the component makes a network request to retrieve data after it has first completed DOM rendering
  • updatedThe correspondingcomponentDidUpdateCalled after the component has been updated. Due to the Vue responsive mechanism, this method is mostly used in scenarioswatchAlternative.
  • beforeDestroyThe correspondingcomponentWillUnmountA 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 attributesdata.b = 1Assignment ordelete data.aDelete, set callback is not triggered. Need to useVue.set(data, 'b', 1)Vue.delete(data, 'a')Make explicit additions and deletions.
  • For the arraypushpopspliceVue 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