Vue3 Chinese document: vue3js.cn/docs/zh/

Project address: github.com/layne1993/v…

Why vuE3

Vue.js 2.x has developed for a long time, and now the surrounding ecological facilities have been very perfect, and for vue.js users, it almost meets all the needs of our daily development. You may think vue.js 2.x is good enough, but in the eyes of Vue.js author You Xiaoyou, it’s not perfect enough.

Vue2. X is still inadequate

  • Vue2. X deep listening on array objects cannot be implemented. Because the component will bind the data in the data via defineProperty responsively or bidirectionally every time it renders, attributes that were not appended before will not be bound and will not trigger updated rendering.
  • Vue2. X involves a lot of unnecessary CPU work during template compilation.
  • As functionality grows, the code for complex components becomes difficult to maintain.
  • Vue2. X uses Facebook’s Flow for type checking, but inferring is problematic in some cases and isn’t very friendly to typescript support (which requires a bunch of decorator syntax).

What are the optimizations of VUe3.0

The source code optimization
  • Better code management: Monorepo splits modules into different subdirectories under the Packages directory based on functionality. In this way, module separation is more detailed, responsibility division is more clear, the dependency between modules is more clear, developers are easier to read, understand and change all module source code, improve the maintainability of the code.
  • Developing in typescript eliminates the need to maintain separate D.ts files.
Performance optimization
  • Source volume optimization: Removed some unpopular features (filter, inline-template, etc.) and introduced tree-shaking techniques to reduce packaging volume.
  • Data hijacking optimization: Use Proxy instead of defineProperty in vue2. X to listen deeply for changes in array objects.
  • Compiler optimization: Detect static nodes, subtrees, and even data objects in the template and promote them outside the rendering function in the generated code. This avoids the need to recreate these objects every time you render, greatly increasing memory usage and reducing the frequency of garbage collection.
  • Syntax API optimization: Launch composition API to optimize logic composition and reuse.

composition API

setup

The setup function is the entry point to the Composition API logical organization.

It runs before props, Data, computed, Methods, and lifecycle functions. Returns an object on which the properties are merged into the render context of the component template, and can also return a Render function

<template> <div> <div>count = {{count}}</div> <div> {{double}}</div> <el-button type="primary" @click="increment"> {{title}}</div> < el-button@click ="decrement"> Modify the values of title </ el-button@release > </div> </template> <script lang="ts"> import { defineComponent, reactive, ref, toRefs, computed, onMounted } from "vue"; export default defineComponent({ setup() { const count = ref(0); const increment = () => { count.value++; }; Const state = reactive({title: "vue3.0", Decrement: () => {state.title = "vue3.0 + typescript"; }}); const double = computed(() => count.value * 2); onMounted(() => { console.info("onMounted"); }); return { ... toRefs(state), count, increment, double }; }}); </script>Copy the code

Inside the Setup function, you define a reactive object state, which is created through the Reactive API (and can also be created using the REF API).

reactive

Reactive is a method of implementing responsiveness by receiving an object as a parameter and returning it wrapped in toRefs (the toRefs function converts a reactive object created by Reactive to a normal object, and every node on that object is reactive data of type REF ()).

ref

Ref, like Reactive, is a way of implementing reactive data by passing in a value as a parameter and returning a reactive REF object based on that value. Rerendering of the template is triggered by changing the value of count.value as in the example above.

computed

Computed is a function that takes a callback function as an argument and returns a responsive Ref object based on that value. You can also take an object form (only set and GET) as an argument.

<script lang="ts"> import { defineComponent, ref, computed } from "vue"; export default defineComponent({ setup() { const count = ref(0); const increment = () => { count.value++; }; const double = computed(() => count.value * 2); // const double = computed({ // get() { // return count.value * 3; // }, // set(val) { // console.log(val); // count.value = val - 1; / / / /}}); return { count, increment, double }; }}); </script>Copy the code

watchEffect

WatchEffect executes a function passed in immediately, tracing its dependencies responsively, and rerunking the function when its dependencies change. It can stop listening, clear side effects, side refresh timing, and listener debugging behavior.

<script lang="ts">
import { defineComponent, ref, watchEffect } from "vue";
export default defineComponent({
  setup() {
    const count = ref(0);
    watchEffect(() => console.info(count.value)); //0
    setTimeout(() => {
      count.value++; //1
    }, 100);
    return { count };
  }
});
</script>
Copy the code
  • When watchEffect is called on a component’s setup() function or lifecycle hook, the listener is linked to the component’s lifecycle and stops automatically when the component is uninstalled. In some cases, you can also explicitly call the return value to stop listening.
const stop = watchEffect(() => {
  /* ... */
})

// later
stop()
Copy the code
  • A function passed in to listen for side effects can receive an onInvalidate function as an input parameter to register a callback in the event of a cleanup failure. This invalidation callback is triggered when the side effect is about to be reexecuted or when the listener is stopped.
watchEffect(onInvalidate => {
  const token = performAsyncOperation(id.value)
  onInvalidate(() => {
    // id has changed or watcher is stopped.
    // invalidate previously pending async operation
    token.cancel()
  })
})
Copy the code

watch

Watch is a function that does not execute immediately, but only when the listening source changes. It can listen on multiple data and has behaviors shared with watchEffect (stop listening, clear side effects, side refresh timing, and listener debugging behavior). . It takes two arguments.

  • The first argument to watch can be a reactive Ref object
<script lang="ts"> import { defineComponent, ref, watch } from "vue"; export default defineComponent({ setup() { const count = ref(0); watch(count, () => console.info(count.value)); return { count }; }}); </script>Copy the code
  • The first argument to watch can be a getter function
<script lang="ts">
import { defineComponent, reactive, toRefs, watch } from "vue";
export default defineComponent({
  setup() {
  	const count = ref(0);
    const state = reactive({
      title: "",
      decrement: () => {
        state.title += "hi!";
      }
    });
    watch([count, () => state.title], () => {
      document.title = "updated " + state.title + count.value;
    });
    return { ...toRefs(state) };
  }
});
</script>
Copy the code
  • Listening to multiple data sources
<script lang="ts"> import { defineComponent, reactive, toRefs, watch } from "vue"; export default defineComponent({ setup() { const state = reactive({ title: "", decrement: () => { state.title += "hi!" ; }}); watch( () => state.title, () => { document.title = "updated " + state.title; }); return { ... toRefs(state) }; }}); </script>Copy the code

The life cycle

In Vue3.0, lifecycle hook functions are completely replaced with the following mapping:

Create -> use setup() 3. BeforeMount -> onBeforeMount 4. Mounted -> onMounted 5. beforeUpdate -> onBeforeUpdate 6. updated -> onUpdated 7. beforeDestroy-> onBeforeUnmount 8. destroyed -> onUnmounted 9.  activated -> onActivated 10. deactivated -> onDeactivated 11. errorCaptured -> onErrorCapturedCopy the code

In addition, vue.js 3.0 adds two new lifecycle apis for debugging: onRenderTracked and onRenderTriggered.