Vue3 Preliminary Exploration (1) Combined API
Vue3 has been released for a while, and although it is still in beta testing, some features can also be understood in advance. This time, let’s take a look at the combined API of one of the most important features, something similar to React Hooks.
If you know Vue2 or have read my previous analysis of Vue2 source code, there is a conclusion I can throw out now:
That is, Vue3’s combined API itself does not use any essentially new features, or a set of reactive principles, but provides a new syntax that allows you to strongly correlate some columns of data, prop, compute, method, life cycle function encapsulated together, and finally the data that needs to be exposed is returned through an object, and the rest is no different from vue2. You can use this to call or use it directly.
The main content of the article comes fromVue3迁移指南-组合式APIIn the middle, it will be reorganized and explained according to its own ideas.
Why do you need a combined API?
By creating Vue components, we can extract the repeatable parts of the interface and its functionality into reusable code snippets. This alone can make our application go further in terms of maintainability and flexibility.
But when our components become very complex, we often encounter this situation in our daily work, we need to watch a prop change, and then change a certain data, and this data may lead to a The change of computing properties, which may also involve other computing properties and data, and may also use many functions.
If it’s just a series of changes caused by a prop, it’s okay, but in general, our components don’t have only one prop. ** When the change of each prop will cause a series of function calls, all functions, calculation properties, etc. will be mixed together. It will make people confused **.
If we have good coding habits, we can artificially chunk the code, that is, put function-related functions together. For example, in the example cited in doc, functions of the same color are function-related:
But this is still not clear enough, so Vue3 has come up with a way, the composite API, which provides a new syntax that allows us to put function-related data and functions together.
How to write Vue2
1 | // src/components/UserRepositories.vue |
Combined API
Now that we know why **, we can know how ** does **. In order to start using the Composite API, we first need a place where we can actually use it. In the Vue component, we call this location’setup '.
The new setup component option is executed before the component is created, once the props have been resolved, and acts as the entry point to the compositing API.
Due to the implementation of
The setup option should be a function that accepts props and context稍后Also, everything we return from setup will be exposed to the rest of the component (computed properties, methods, lifecycle hooks, etc.) as well as the component’s template.
Let’s first look at the following example:
1 | // src/components/UserRepositories.vue `setup` function |
The setup of this example accepts props as the parameter, uses the data in the prop to obtain the warehouse data, and then assigns it to repositories.
This is our starting point, but it can’t work yet, ** because our’repositories’ variable is non-responsive **. This means that from the user’s point of view, the repository list will remain empty, because vue’s MVVM is based on reactive objects. If repositories are non-responsive, that means it will not trigger any updates to views.
Belt
In Vue 3.0, we can make any reactive variable work anywhere with a new’ref 'function, as follows:
1 | import { ref } from 'vue' |
'Ref ‘takes the parameter and returns it wrapped in an object with a’value’ property, which can then be used to access or change the value of the response variable:
Note that ref returns an object, and imported parameters are placed in the value of the returned object
1 | import { ref } from 'vue' |
Wrapping values in objects may seem unnecessary, but it is necessary to keep the behavior of different data types uniform in JavaScript. ** This is because in JavaScript, primitive types such as’Number ‘or’String’ are passed by value, not by reference: **
Returning to our example, let’s create a repositories variable in response.
1 | // src/components/UserRepositories.vue `setup` function |
Done! Now whenever we call getUserRepositories, the repositories will change and the view will update to reflect the changes. Our component should now look like this:
1 | // src/components/UserRepositories.vue |
We’ve moved several parts of the first logical concern into the setup method, which are very close to each other. All that’s left is to call getUserRepositories in the mounted hook and set up a listener to do this when the user prop changes.
We’ll start with lifecycle hooks.
Lifecycle hook registration internal
In order to make the features of the composite API more complete than the optional API, we also need a way to register the lifecycle hook in’setup ‘. This is thanks to several new functions exported from Vue. The lifecycle hook on the composite API has the same name as the optional API, but is prefixed with’on’: i.e. ‘mounted’ looks like’onMounted '.
These functions accept callbacks that are executed when the component invokes hook.
Let’s add it to the setup function:
1 | // src/components/UserRepositories.vue `setup` function |
Now we need to react to the changes made by the’user ‘prop. For this we will use the standalone’watch’ function.
watch
Just like how we set the listener on the user property inside a component using the watch option, we can do the same with the watch function imported from Vue. It accepts 3 arguments:
- a responsive reference or getter function we want to listen to
- A callback
- Optional configuration options
** Here’s a quick look at how it works **
1 | import { ref, watch } from 'vue' |
For example, whenever’counter ‘is modified with’counter.value = 5’, watch will trigger and execute a callback (the second argument), in this case, it will record “The new counter value is: 5” to our Console.
** Here is the equivalent optional API: **
1 | export default { |
** Now we apply it to our example: **
1 | // src/components/UserRepositories.vue `setup` function |
You may have noticed the use of toRefs at the top of our setup. This is to ensure that our listeners can react to changes made by the user prop.
Independent
Similar to’ref ‘and’watch’, computed properties can also be created outside of Vue components using the’computed 'function imported from Vue. Let’s go back to our counter example:
1 | import { ref, computed } from 'vue' |
Here, the computed function returns a read-only reactive reference to the output of the getter class callback passed as the first argument of computed. To access the value of the newly created computed variable, we need to use the .value property as if it were ref.
Let’s move the search function to’setup ':
1 | // src/components/UserRepositories.vue `setup` function |
For other ** logical concerns ** we could do the same, but you’re probably already asking this question - * isn’t that just moving the code to the’setup ‘option and making it really big *? Well, that’s true. That’s why we’ll first extract the above code into a separate ** combined function ** before moving on to other tasks. Let’s start by creating’useUserRepositories’:
1 | // src/composables/useUserRepositories.js |
Then there is the search function:
1 | // src/composables/useRepositoryNameSearch.js |
** Now that we have these two features in separate files, we can start using them in our components. Here’s how to do it: **
1 | // src/components/UserRepositories.vue |