On September 18, 2020, VUe3.0 was officially released. As a major release update, Vue3.0 is of course a big change from Vue2.0.

One of Vue3’s core features is the introduction of the Composition API. How is the Composition API different from vue2.0?

One, the Composition API

What is the difference between a composite API and a configuration API?

Vue2.0 (Configuration API)

In Vue2. X, the main logic of a component is written through configuration items, including some built-in lifecycle methods or component methods

export default {
  name: 'test',
  components: {},
  props: {},
  data () {
    return {}
  },
  created(){},
  mounted () {},
  watch:{},
  methods: {}
}
Copy the code

We usually write components, data, and various hooks and watches separately and pass them to the vue instance as options.

Vue 3.0(Combined API)

The setup() function is a new attribute in VUe3 that is specifically provided for components. It provides a unified entry point for using vue3’s new Composition API feature, which basically means that everything can be written to setup().

import { fetchGetList } from '@/api/repositories'
import { ref, onMounted, watch, toRefs } from 'vue'

setup (props) {
  const repositories = ref([])
  const getList = async () => {
    repositories.value = await fetchGetList()
  }
  onMounted(getUserRepositories)
  watch(getUserRepositories)
  return {
    repositories,
    getUserRepositories
  }
}
Copy the code

Why choose a composite API?

We are doing component programming, and we can write a lot of functions in the same component, such as popboxes, getList, Add, update, etc. In the era of VUe2.0, our component code might look like this:

vue2.0

Export default {name: ", components: {}, props: {}, data() {return {// play football: ", // play basketball: ", // Play billiards.... }}, created() {// play football // play basketball}, methods: {// playFootball playFootball() {console.log(this.football)}, // playBasketball playBasketball() {console.log(this.basketball)} // play billiards.... } } </script>Copy the code

Pieces of logic scattered all over the place made our components increasingly difficult to read, often frantically swiping up and down the screen to see a feature, rummaging through blocks and making changes.

mixins

Mixins can also be used for abstraction in Vue2.0, but they lose their flavor over time

Advantages of Mixins:

Code can be organized by function

Disadvantages of Mixins:

There are potential conflicts, you can use properties or functions in the same name conflicts

Dependencies are not clear, especially if multiple Mixins communicate.

Logical reuse is not flexible enough if you need to differentiate or configure Mixins across components.

vue3.0

How to write the composite API for VUe3.0:

<script> export default { setup(props, CTX){// play football const useFootball = function(){} // play basketball const useBasketball = function(){} return {useFootball, useBasketball } } }; </script>Copy the code

Without discrete blocks, we can write less code, and it’s easier to pull reusable logic out of components and into functions.

Basic syntax for the Composition API

Ref or reactive replaces variables in data

Vue2. X defines some data for the current component using the component data method:

data() {
  return {
    name: 'test',
    list: [],
  }
},
Copy the code

Create reactive objects by ref or Reactive in Vue3:

import {ref,reactive} from 'vue'
...
setup(){
  const name = ref('test')
  const state = reactive({
    list: []
  })
  return {
      name,
      state
  }
}
...
Copy the code

Ref creates a reactive data object from the given value and assigns an initial value (int or string). Reactive can directly define complex reactive objects. Why Reactive can define complex reactive objects is explained later.

Setup () uses props and this:

In Vue2. X, component methods can use this to get an instance of the current component and perform data variable modifications, method calls, component communication, and so on

In Vue3, setup() is called on beforeCreate and created, so you can’t use this as Vue2. X, but you can get an instance of the current component and props by receiving setup(CTX) :

export default {
  props: {
    name: String,
  },
  setup(props,ctx) {
    console.log(props.name)
    ctx.emit('event')
  },
}
Copy the code

Ii. Optimization of VUe3.0 (faster, smaller)

PatchFlag(static marking), hoistStatic(static promotion)

The source code of VUe2.0 when dealing with the virtual DOM, the choice is to traverse all the content in the template template to generate the virtual DOM. When the content changes, it is updated through the DIff algorithm. But in addition to bidirectionally bound dynamic data, THERE is so much static content in HTML that it can be a waste of performance to participate in traversal every time.

It can be seen that when Vue3.0 generates the virtual DOM, the second div tag is the bound variable, so it is marked with a tag of 1, which stands for TEXT. Therefore, the content can be divided into static resources and dynamic content, so that only the dynamic part can be diff when updating.

See the source code for details

We usually write functions in the development process, when defining some dead variables, variables will be promoted out of the definition, Vue 3.0 in this aspect also made the same optimization

This means that the variable will only be created once and then referenced, improving performance

CacheHandler (event caching)

By default, the @Click event is considered a dynamic variable, so it is tracked every time the view is updated.

Normally, however, our @click event is the same event before and after rendering the view, so we don’t need to track its changes, so Vue 3.0 has made an optimization for this called event listener caching.

Thus, with cacheHandler set, dynamic nodes statically marked as 8 become static nodes and thus do not participate in diff, improving performance.

Reactive Objects (Proxy objects and Reactive)

Literally, a Proxy object is a Proxy for a target object, through which any operation on the target object (instantiation, adding/deleting/modifying properties, and so on) must pass. So we can block and filter or modify all operations from the outside world.

Use the big guy example to show the function of Proxy object:

let foo = { a:1, b:2 } let handler = { set:(obj,key,value)=>{ console.log('set') obj[key] = value return true } } let p = new Proxy(foo,handler) p.a = 3 // Print console.log('set')Copy the code

I believe all front-end interviews have been asked this question, how is vUE two-way data binding implemented?

The standard answer should be the same:

Vue implements bidirectional data binding mainly using data hijacking and publish and subscribe modes. Data hijacking is the use of JavaScript accessor properties, namely object.defineProperty () method. When assigning an attribute to an Object, Object.defineProperty can be hijacked using the set method to change the data. The publisher (topic object) is then notified to notify all observers, and when the observers receive the notification, the view is updated.

In Vue2. X, object.defineProperty () is used to implement reactive objects. For complex objects, getter/setter listeners need to be added recursively to each property, making component initialization time-consuming. In VUe3, composition-API provides a way to create responsive objects, and reactive is internally implemented using Proxy API, so that each attribute can be added one by one to reduce overhead and improve performance.

The reactive source

The core features of the Vue3.0 update, along with Tree Shaking support, typescript support, Fragments, small things, and of course vite, are all worth checking out.