Create a template
For components, most of the code is very similar in Vue2 and vue3. Vue3 supports fragments, that is, a component can have multiple root nodes.
This new feature can reduce div wrapping elements between many components. When developing vue, we will find that each component will be wrapped with a div element. There will be many layers of redundant div elements. Fragments solve this problem. For children's shoes with perfect obsessive-compulsive disorder, "it's really great.". We won't show it in the example here. We use a simple component with a single root node.
Vue2 table template
<template> <div class='form-element'> <h2> {{ title }} </h2> <input type='text' v-model='username' placeholder='Username' /> <input type='password' v-model='password' placeholder='Password' /> <button @click='login'> Submit </button> <p> Values: {{ username + ' ' + password }} </p> </div> </template>
The only real difference in Vue3 is data acquisition. The Reactive Data in Vue3 is contained in a Reactive State variable So we need to access this reaction state to get the data value.
<template> <div class='form-element'> <h2> {{ state.title }} </h2> <input type='text' v-model='state.username' placeholder='Username' /> <input type='password' v-model='state.password' placeholder='Password' /> <button @click='login'> Submit </button> <p> Values: {{ state.username + ' ' + state.password }} </p> </div> </template>
Establish data data
Here is the biggest difference between Vue2 and Vue3 - Vue2 uses the Options API to compare with Vue3 Composition API
The old optional API split different properties in the code: data, computed properties, methods, and so on. The new composite API allows us to use methods (function s) to split. Compared with the old API, we use attributes to group, so the code will be simpler and cleaner.
Now let's compare the differences between Vue2 and Vue3 in the code.Vue2 - Here, put the two data into the data attribute
export default { props: { title: String }, data () { return { username: '', password: '' } } }
In Vue 3.0, we need to use a new setup() method, which is triggered when the component initializes the construction.
In order to let developers have more control over reactive data, we can directly use Vue3's reactivity API.
Use the following three steps to establish reactivity data:
- Introducing reactive from vue
- Use the reactive() method to claim that our data is reactive data
- Use the setup() method to return our reactivity data so that our template can get these reactivity data
The last wave of code makes it easier for everyone to understand how it is implemented.
import { reactive } from 'vue' export default { props: { title: String }, setup () { const state = reactive({ username: '', password: '' }) return { state } } }
The reactivity data constructed here can be used by the template, and the value of the data can be obtained through state.username and state.password.
Vue2 vs. Vue3 methods to write
Vue2 The optional API divides methods into separate attribute areas. We can directly add methods to this attribute to handle various front-end logic.
export default { props: { title: String }, data () { return { username: '', password: '' } }, methods: { login () { // Login method } } }
Vue3 The setup() method in the synthetic API can also be used to manipulate methods. The method of creating a claim is actually the same as the claim data state We need to first name a method and then return it in the setup() method, so that this method can be called in our component.
export default { props: { title: String }, setup () { const state = reactive({ username: '', password: '' }) const login = () => { // Login method } return { login, state } } }
Lifecycle hook - Lifecyle Hooks
stay Vue2, we can invoke the lifecycle hook of Vue directly in component properties. The following uses a component mounted life cycle trigger hook.
export default { props: { title: String }, data () { return { username: '', password: '' } }, mounted () { console.log('Component mounted') }, methods: { login () { // login method } } }
Now? Vue3 The setup() method in the synthetic API can contain all the basic things. Life cycle hook is one of them!
However, in the Vue3 lifecycle, hooks are not globally callable and need to be introduced from Vue. Like the reactive just introduced, the life cycle mount hook is called onMounted.
After the introduction, we can use the onMounted hook in the setup() method.
import { reactive, onMounted } from 'vue' export default { props: { title: String }, setup () { // .. onMounted(() => { console.log('Component mounted') }) // ... } }
Calculation properties- Computed Properties
Let's try adding a calculated attribute to convert username to lowercase.
stay Vue2 We only need to add it in the option attribute in the component
export default { // .. computed: { lowerCaseUsername () { return this.username.toLowerCase() } } }
Vue3 The new design pattern allows developers to introduce dependent packages as needed. In this way, there is no need for redundant references, resulting in performance problems or too big problems after packaging. Vue2 has this persistent problem.
Therefore, to use calculated properties in Vue3, we first need to introduce calculated in the component.
It is used in the same way as reactive data. Add a calculation attribute to state:
import { reactive, onMounted, computed } from 'vue' export default { props: { title: String }, setup () { const state = reactive({ username: '', password: '', lowerCaseUsername: computed(() => state.username.toLowerCase()) }) // ... }
receive Props
Receiving component props parameter passing brings us the biggest difference between vue2 and vue3 this represents something completely different from vue2 in vue3.
stay Vue2 and this represent the current component, not a specific attribute. Therefore, we can directly use this to access the prop attribute value. For example, the following example prints the parameter title of the currently passed in component after mounting.
mounted () { console.log('title: ' + this.title) }
But in Vue3 In, this cannot directly get props attribute, emit events and other attributes in the component. However, the new setup() method can accept two parameters:
- props - Immutable component parameters
- context - Vue3 exposed attributes (emit, slots, attrs)
Therefore, receiving and using props in Vue3 will become like this:
setup (props) { // ... onMounted(() => { console.log('title: ' + props.title) }) // ... }
Events- Emitting Events
stay Vue2 Custom events are very direct, but in Vue3 If so, we will have more freedom of control.
For example, now we want to trigger a login event when we click the submit button.
stay Vue2 In, we will call this.$emit and pass in the event name and parameter object.
login () { this.$emit('login', { username: this.username, password: this.password }) }
But in In Vue3, we just said that this and vue2 no longer represent this component, so we need different ways to customize events.
So what?! Benefit (benefit)
Don't panic. There is emit in the content object of the second parameter in setup(), which is the same as this.$emit. Then, as long as we use the decomposition object method to extract emit in the second parameter received by setup(), we can use it freely in the setup method.
Then we write the login event in the login method:
setup (props, { emit }) { // ... const login = () => { emit('login', { username: state.username, password: state.password }) } // ... }
Final vue2 vs. vue3 code
Finally, I finished it Vue2 and Vue3 Send out the component code of:
Vue2
<template> <div class='form-element'> <h2> {{ title }} </h2> <input type='text' v-model='username' placeholder='Username' /> <input type='password' v-model='password' placeholder='Password' /> <button @click='login'> Submit </button> <p> Values: {{ username + ' ' + password }} </p> </div> </template> <script> export default { props: { title: String }, data () { return { username: '', password: '' } }, mounted () { console.log('title: ' + this.title) }, computed: { lowerCaseUsername () { return this.username.toLowerCase() } }, methods: { login () { this.$emit('login', { username: this.username, password: this.password }) } } } </script>
Vue3
<template> <div class='form-element'> <h2> {{ state.title }} </h2> <input type='text' v-model='state.username' placeholder='Username' /> <input type='password' v-model='state.password' placeholder='Password' /> <button @click='login'> Submit </button> <p> Values: {{ state.username + ' ' + state.password }} </p> </div> </template> <script> import { reactive, onMounted, computed } from 'vue' export default { props: { title: String }, setup (props, { emit }) { const state = reactive({ username: '', password: '', lowerCaseUsername: computed(() => state.username.toLowerCase()) }) onMounted(() => { console.log('title: ' + props.title) }) const login = () => { emit('login', { username: state.username, password: state.password }) } return { login, state } } } </script>
I hope this article can let you experience a more comprehensive development difference between Vue2 and Vue3.