Analysis of new features of Vue 3

Posted by white99 on Wed, 24 Jun 2020 05:25:20 +0200

It is known that the current stable version of Vue is 2.6.x, and the subsequent version is 2.7.x (part of vue3 content is added). After 18 months of maintenance, except for the security vulnerability update, the rest will not continue to update. Explain that we will embrace the era of vue3.0 in an all-round way

Information about the compatibility of vue3.0 with vue2.0 in use

1, Highlights

1.Performance [pəˈfɔːməns]

  • Rewrite the implementation of virtual Dom (skip static nodes and only deal with dynamic nodes)
  • 1.3-2 times higher update performance
  • SSR speed increased by 2-3 times

Tree shaking [ˈʃeɪkɪŋ]

  • The useless module can be "clipped" to pack only the required

Fragment ['frægmənt]

  • No longer limited to a single root node in the template

<Teleport> [ˈtelɪpɔːt]

  • Formerly known as < portal > [ˈ p ɔ tl], translated as a portal

<Suspense> [səˈspens]

  • Asynchronous dependencies that can wait for nesting at the nesting level

TypeScript

  • Better TypeScript support

Custom Renderer API

  • Custom renderer API
  • You can try WebGL custom renderer

Composition [ˌkɒmpəˈzɪʃn] API

  • Combined API, replacing the original Options [ˈ p ʃ nz] API
  • Organize code according to logical correlation to improve readability and maintainability
  • Better reuse of logical code (avoid naming conflicts when mixins are mixed)
  • But you can still use the Options [ˈ p ʃ nz] API

Proxy [ˈprɒksi]

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

  • The responsive principle is no longer based on Object.defineProperty

2, Configure vue3.0 based on vue/cli

https://github.com/vuejs/vue-next

vue-cli-plugin-vue-next

$ npm install -g @vue/cli
$ vue --version
$ vue create xxx
$ vue add vue-next
"dependencies": {
"vue": "^3.0.0-beta.1"
},
"devDependencies": {
"@vue/compiler-sfc": "^3.0.0-beta.1",
"eslint-plugin-vue": "^7.0.0-alpha.0",
"vue-cli-plugin-vue-next": "~0.1.3"
},
eslintConfig": {
    "extends": [
      "plugin:vue/vue3-essential"
    ]
}

3, Configure vue3.0 based on vite

web development tool developed by you Yuxi, author of vue

https://github.com/vitejs/vite

  • Development server based on browser native ES imports (use browser to analyze imports, compile and return on demand on the server side, completely skip the concept of packaging, and the server is ready to use)
  • At the same time, it not only has the support of Vue files, but also handles the hot update, and the speed of hot update will not slow down with the increase of modules

$ npm init vite-app xxx
$ cd xxx
$ npm install
$ npm run dev
$ npm run build
//perhaps
$ yarn create vite-app xxx
$ yarn
$ yarn dev
$ yarn build

4, Master setup and responsive system API

https://vue-composition-api-rfc.netlify.app/zh/api.html

setup

The setup function is a new component option as an entry point for using the Composition API within a component

  • Call between initialization props and beforeCreate
  • Can receive props and context
  • this is not available in setup()

props is reactive and can be monitored based on watchEffect/watch. After the value is deconstructed, it will be invalid

export default {
props: {
title: String,
},
setup(props) {
watchEffect(() => {
console.log(`title is: ` + props.title);
});
}
};

The returned results can be directly used for rendering in the template

export default {
props: { title: String },
setup() {
let supNum = 0,
oppNum = 0;
let change = lx => {
lx === 0 ? supNum++ : oppNum++;
};
return {
supNum,
oppNum,
change
};
}
};

ref

Accepts a parameter value and returns a responsive and changeable ref object

  • The ref object has a single attribute. Value that points to an internal value
  • When ref is used in a template, it will be automatically uncoupled, without additional writing of. value in the template

import { ref } from "vue";
export default {
setup() {
let supNum = ref(0),
oppNum = ref(0);
let change = lx => {
lx === 0 ? supNum.value++ : oppNum.value++;
};
return {
supNum,
oppNum,
change
};
}
};

reactive

Receive a normal object and return its responsive proxy

Equivalent to 2.x Vue.observable()

  • Reactive transformations are "deep": they affect all nested properties within an object

import { ref, reactive } from "vue";
export default {
props: { title: String },
setup() {
let state = reactive({
supNum: 0,
oppNum: 0,
arr: [10, 20]
});
let change = lx => {
lx === 0 ? state.supNum++ : state.oppNum++;
// than Object.defineProperty The good use is: for data or uninitialized object members, you can modify the value at will, and have a responsive effect
state.arr[0] = state.arr[0] + 1;
state.name = "Mount Everest";
};
return {
//...toRefs(state),
state,
change
};
}
};

unref / toRef / toRefs / isRef / isProxy / isReactive / isReadonly

readonly

Pass in an object (reactive or normal) or ref and return a read-only proxy for the original object

A read-only proxy is "deep" and any nested properties within the object are read-only

const original = reactive({ count: 0 })
const copy = readonly(original)
watchEffect(() => {
// Dependency tracking
console.log(copy.count)
});
// Changes on original trigger listening on copy
original.count++;
// Cannot modify copy and will be warned
copy.count++; // warning!

computed

Pass in a getter function and return a ref object that cannot be modified manually by default

const count = ref(1);
const plusOne = computed(() => count.value + 1);
console.log(plusOne.value); //2
plusOne.value++; //Error!

Or pass in an object with get and set functions to create a manually modifiable calculation state

const count = ref(1);
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1;
}
});
plusOne.value = 1;
console.log(count.value); //0
import { ref, reactive, toRefs, computed } from "vue";
export default {
props: { title: String },
setup() {
......
// Calculation properties
let ratio = computed({
get: () => {
let total = state.supNum + state.oppNum;
return total === 0
? "--"
: ((state.supNum / total) * 100).toFixed(2) + "%";
}
});
return {
......,
ratio
};
}
};

watchEffect

Executes an incoming function immediately, tracks its dependencies in response, and reruns the function when its dependencies change

export default {
props: {
title: String,
},
setup(props) {
watchEffect(() => {
console.log(`title is: ` + props.title);
});
}
};

watch

The watch API is exactly equivalent to 2.x this.$watch

  • watch needs to listen to a specific data source and perform side effects in the callback function
  • The default is lazy, which means that callbacks are only executed when listening for source changes

Listen to a single data source

//The listener's data source can be a getter function with a return value, or it can be

const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
);
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
});
import { ref, reactive, toRefs, computed, watch } from "vue";
export default {
setup() {
....
let ratio = ref("--");
watch(state, (state, preState) => {
let total = state.supNum + state.oppNum;
ratio.value =
total === 0 ? "--" : ((state.supNum / total) * 100).toFixed(2) + "%";
});
return {
...,
ratio
};
}
};

5, Master the use of new life cycle functions and templates refs

Template Refs

When using composite API s, the concepts of reactive refs and template refs are already unified

<template>
<div ref="root"></div>
</template>
<script>
  import { ref, onMounted } from 'vue';
  export default {
    setup() {
      const root = ref(null);
      onMounted(() => {
        console.log(root.value);
      });
      return {
        root
      };
    }
  }
</script>

Life cycle function

You can directly import the functions of the onXXX family to register the lifecycle hook

  • These lifecycle hook registration functions can only be used synchronously during setup()
  • When a component is unloaded, the listener and calculation state created synchronously within the lifecycle hook will also be removed

Topics: Javascript Vue npm TypeScript github