start
September 19, vue3 0 arrived as scheduled. In fact, many people have experienced it for a long time, but I am lazy. In addition, I can't use it in the project without formal release, so I haven't tried it. I only saw some new functions in some sporadic articles. Now its formal release means that it has been recommended to use it in new projects. After all, compared with 2.0, Its advantages are still very obvious. Although some supporting tools have not been completed, there should be no problem in using them on some small projects.
At present, I haven't actually used it. This article summarizes it after reading its proposal documents, api documents and some articles, which will inevitably have problems. In addition, this article is no different from other similar articles introducing vue composite api. If you read other articles, you can ignore ~.
According to the official statement, vue3 The changes of 0 include performance improvement, smaller bundle volume, better support for TypeScript, and a new api for handling large-scale use cases. The new api refers to the composite api mainly discussed in this paper.
If your project has not been or cannot be upgraded to version 3.0, don't regret, it can also be used, 2 In the version of X, you can use the composite api in the project through the @ Vue / composition api plug-in, which mainly provides vue3 Some new interfaces in 0 object will be upgraded to 3.0 in the future. Just change the reference from the plug-in to Vue object. At present, some also support 2.0 X and 3 X version of the utility library (such as Vue use, Vue composable), so rest assured to use it boldly.
There must be a reason for the emergence of a new thing. The composite api appeared earlier in react, that is, react hooks. The reason why vue was introduced is certainly not because react exists, so I have to have it. Plagiarism is even less important. The development of the framework must go in a more advanced direction, such as the previous two-way binding, virtual DOM and so on.
Personally, I was 2 There are two main problems in the use of X:
1. For larger projects, reuse is very important. Using this modular framework without reuse is a great waste. In 2 In X, vue reuse mainly involves components and mixins. If it does not involve the logical reuse of templates and styles, mixins are generally used, but mixins are very painful to use, because after the code is extracted into mixins, you basically can't remember what's in it. There are multiple mixins. You don't even know which one comes from. You need to open mixins every time, Moreover, it is easy to cause the problem of repeated declarations.
2. Although it's better for a component to do only one thing, it's actually difficult. Components do several things more or less. Because vue's writing method is option organization, data and data are together, methods and methods are together, and other attributes are the same, so a relatively independent function is scattered everywhere, which is difficult to distinguish, Extracting reuse logic is also troublesome, which is terrible when a vue file has a large amount of code.
The emergence of composite api can solve the above two problems. In addition, it is more friendly to TypeScript type derivation.
In terms of specific use, for vue single files, the template part and style part are basically the same as before. The combined api mainly affects the logic part. Let's take the simplest example:
<template> <div @click="increment">{{data.count}}</div> </template> <script> import { reactive } from 'vue' export default { setup() { const data = reactive({ count: 0 }) function increment() { data.count++ } return { data, increment } } } </script>
The effect is to click the number and the number will increase. You can see that an obvious change is the addition of a setup function, and the previously familiar data and methods attributes are missing. It should be noted that the data to be used in the template should be explicitly returned in the setup function.
Although the example is small, you can see how it solves the above problems. For example, if you want to reuse this count, you only need to:
const data = reactive({ count: 0 }) function increment() { data.count++ }
It can be extracted into a function. In fact, it is to put all the things originally scattered in various options together. In addition, without this, each independent function can be extracted into a function. In order to distinguish, the function name generally starts with use, such as useCount. The setup function actually becomes a constructor function or a general init function in the code organized by class, which is used to call each use function.
If you're not used to this way, actually 2 The option mode of X can still be used. The composite api will be parsed before the options, so the properties in the options cannot be accessed in the composite api. The properties returned by the setup function can be accessed through this in the options, but it is better not to mix them.
Introduction to common APIs
setup
export default { setup() { return {} } }
The setup function is a new option to use the composite api. It will be called before the beforeCreate life cycle hook. Some knowledge points:
1. An object can be returned, and the attributes of the object will be merged into the context of template rendering;
2. You can return a function;
3. The first parameter is props. Note that props cannot be deconstructed. The second parameter is a context object, exposing some other common attributes;
reactive
import { reactive } from 'vue' const data = reactive({ count: 0, })
The reactive function turns an object into a response, and the returned data is basically equivalent to the previous data option.
watchEffect
import { reactive, watchEffect } from 'vue' const data = reactive({ count: 0, }) watchEffect(() => { alert(this.count) })
watchEffect is used to monitor data changes. It will be executed immediately. Then it will track all the responsive states used in the function. When the changes are made, the callback function will be executed again.
computed
import { reactive, computed } from 'vue' const data = reactive({ count: 0, }) const double = computed(() => { return data.count * 2 })
Equivalent to the previously calculated option, create a state that depends on other states. Note that an object called ref is returned:
{ value: xxx//This is the value you need }
The actual value referenced is the value attribute of the object. The reason for doing so is very simple, because in the final analysis, computed is only a function. If a value of basic type is returned, such as 0, then even the subsequent data The count is changed, and the double is still 0. Because JavaScript is a basic type, and the object is passed by value, and the object is passed by reference, the value obtained in this way is always the latest value.
In addition to passing the getter function, you can also pass an object with setter and getter properties to create a modifiable calculated value.
ref
import { ref } from 'vue' let count = ref(0)
In addition to returning ref through computed, it can also be created directly, but it can also be realized directly through reactive:
let data = reactive({ count: 0 })
ref and reactive have certain similarities, so we need to fully understand them in order to efficiently select different methods in various scenarios. The most obvious difference between them is that ref needs to be passed when used value instead of reactive.
The difference between them can also be understood in this way. ref is to provide response capability for a certain data, while reactive is to provide response capability for an entire object containing the data.
When using ref in a template and nested in a responsive object, you do not need to pass value, will untie itself:
<template> <div>{{count}}</div> </template> <script> let data = reactive({ double: count * 2 }) </script>
In addition to the responsive ref, there is also a ref that references DOM elements, 2 X is through this$ refs. XXX, but there is no this in the setup, so it is also used by creating a ref:
<template> <div ref="node"></div> </template> <script> import { ref, onMounted } from 'vue' export default { setup() { const node = ref(null) onMounted(() => { console.log(node.value)// Here is the dom element }) return { node } } } </script>
toRefs
If you return a responsive object from a composite function, you will lose responsiveness if you deconstruct it in the using function. To solve this problem, you can return it intact:
import { reactive } from 'vue' function useCounter () { let data = reactive({ count: 0 }) return data } export default { setup() { // let {count} = useCounter(), this is not possible // return {, you can't do that either // ...useCounter() // } return { count: useCounter()//That's it } } }
In addition, another way is to use toRefs, which will convert each attribute of a responsive object into a ref:
import { toRefs, reactive } from 'vue' function useCounter () { let data = reactive({ count: 0 }) return toRefs(data) } export default { setup() { let {count} = useCounter() return { count } } }
It is beneficial to use toRefs to convert the data returned in the setup function:
import { toRefs, reactive } from 'vue' export default { setup() { let data = reactive({ count: 0 }) return { data } } }
If so, you need to use it in the template through data Count to reference the value of count. If you use toRefs, you can directly use count:
<script> import { toRefs, reactive } from 'vue' export default { setup() { let data = reactive({ count: 0 }) return { ...toRefs(data) } } } </script> <template> <div>{{count}}</div> </template>
Life cycle function
import { onUpdated, onMounted } from 'vue' export default { setup() { onUpdated(() => { console.log(1) } onMounted(() => { console.log(1) } } }
Just change the previous life cycle to onXXX. Note that the created and beforeCreate hooks have been deleted, and the life cycle function can only be used in the setup function.
In addition, there are some other APIs. It is recommended to read through the official documents in detail and consolidate them in practical use.
ending
It still takes some time to adapt to the use of composite APIs. First, you need to be able to distinguish between ref and reactive. Don't get confused between basic types and application types, and get lost between responsive and non responsive objects. Second, how to split each use function. The composite api brings a better code organization, but it is easier to write the code and more difficult to maintain, For example, the setup function is very long.
Briefly summarize the upgrade idea. The data in the data option is declared through reactive through toRefs() returns; The calculated, mounted and other options are replaced by the corresponding calculated, onMounted and other functions; The functions in methods can be declared anywhere, as long as they are returned in the setup function.
Through this set of combined APIs, the scope of use is not limited to vue, but can be used in other places:
import { reactive, watchEffect } from '@vue/composition-api' let data = reactive({ count: 0 }) watchEffect(() => { renderTemplate(data)//Your template render function })
Well, no, I'm going to try it.
Reference articles