Wide sea diving, sky high the birds to fly. Hey hello! I'm Molly
Vue3 has been released for some time, and it has also been supported by major manufacturers and communities and loved by many developers. The surrounding ecology is also gradually improving. It is a thriving landscape. This article aims to help you quickly master Vue3 by sorting out the common APIs of Vue2 and comparing Vue3 through differentiation
This article assumes that you already have some vue2
practical experience, and will not describe too much api
details
Why upgrade to Vue3?
Two key factors led us to consider rewriting Vue with a new major version:
- General browser support for the new
JavaScript
language feature. - Current
Vue
design and architectural issues that the codebase has exposed over time.
For more details, we can listen to the answer from the ancestor in Zhihu, written by You Yuxi: What did the new Vue 3 bring?
vue2 VS vue3 (coding somatosensory)
Recently, I made a background management system project about "shared stroller". Since it is a new project, I boldly selected vue3
+ vite
+ typescript
+ element plus
as the base technology stack. However, there is currently no free and easy-to-use basic template framework for the middle and backstage on the market, so I imitated the portal of the big man in flower pants: vue-admin-template wrote a vue3
version vue-element-admin
and applied to the actual project. As far as my personal coding habits are concerned, compared with vue2
of Option api
, vue3
of Composition api
can better organize cce349f40cce349f40 , supports custom hooks
to achieve code reuse, thereby replacing mixin
, in terms of code style, you can also write similar business logic into a code block, so as to avoid code dispersion, walking reading The code needs to jump up and down repeatedly. More friendly support TS
and the addition of many new features also make vue3
more comfortable to write and more conducive to code maintenance and expansion. Combined with the use of vite
, it greatly improves the development experience. In general, let's hug vue3
and give the vue
team a like👍👍👍
Intuitive new features of vue3
- Brand new
Composition api
let's organize code differently -
<script setup>
Syntax sugar to make the code more concise - The root element wrapping tag of
template
can be omitted - Provides a new built-in component
<teleport>
, which supports the component can be mounted to anydom
node - Provided to use ---bebb7b7179051e19d7252833df0c96f3
css
inv-bind
to introducescript
variable, another powerful black magic trick - Use
createApp
to create an application instance - more friendly
TS
support - Use
proxy
proxy to replacedefineproperty
- Global and internal
API
have been refactored to supporttree-shake
option api vs composition api
composition api
vue3
a major feature of vue3
, ---0b0ea39acb373e6e63c5cd18f77adcad--- exposes a large number of functions for us to reference and combine at will
In option api
, we instantiate Vue
and pass in the behavior object as a parameter
new Vue({
data(){
return {}
},
methods:{},
computed:{},
created(){},
...
})
In Composition api
we can pass setup
as the entry function and return an object data exposed to the template for use
<template>
<div @click="hi">{{ msg }}</div>
</template>
<script>
export default {
setup() {
const msg = ref('Hello!')
function hi() {
console.log(msg)
}
// 暴露给模板
return {
msg,
hi
}
}
}
</script>
setup
also supports another writing method, which simplifies the code even more
<template>
<div @click="hi">{{ msg }}</div>
</template>
<script setup>
const msg = ref('Hello!')
function hi() {
console.log(msg)
}
</script>
When using <script setup>
, any binding at the top level of the <script setup>
declaration (including variables, function declarations, and import
imports) can be used in the template use directly in
Definition of response data
vue2
define the response data to data
function return
data(){
return {
...
}
}
vue3
we can define the response data by ref
and reactive
const num = ref(0)
const obj = reactive({name:'molly'})
ref:
- In the template, you can directly use the data defined by
ref
96de426a656f273e69b8035b38954ac3---, and injs
you need to use.value
to take a value or assign a value - Use
geter
,seter
to implement responsive - It is recommended to use
ref
to define the base data
reactive:
- You can use
toRefs
to unpack it and use the correspondingattribute
directly in the template - Use
proxy
proxy to implement responsive - It is recommended to use
reactive
to define complex data
lifecycle hooks
vue2
provides 11 life cycle hooks, we can define and use them directly on the option object
vue3
, the lifecycle hooks are separated into corresponding hooks
functions, which are called in the form of onXXX
. It is noteworthy that the life cycle of the hook function can only be registered in setup
simultaneous use period, which means beforeCreate
and created
equivalent to setup
Execution phase. The usage of other cycles is basically the same, for example: mounted
corresponding to onMounted
import { onMounted } from 'vue'
setup() {
onMounted(() => {
console.log('mounted!')
})
}
computed
The two versions computed
are basically the same, the difference is vue3
The computed
e590d3df09b007d5d9163ddb53e8c1b5--- function is extracted into one hooks
// vue2
computed:{
num:()=>this.num *2
}
// vue3
const numVal = computed(() => num.value *2)
watch
vue2:
watch
Monitor the result change of a specific data source, and the parameters obtained by the callback function are the new value and the old value. In addition to listening data
data can also listen props
, $route
, $emit
, computed
. The option parameter deep
can be used for deep monitoring, and specifying immediate: true
will trigger the callback immediately
watch:{
obj:(val,old)=>{
deep: true,
immediate: true
}
}
vue3
The computed properties of vue3
have been greatly enhanced to support monitoring multiple data sources and executing side effects
// 监听单个数据源
const count = ref(0)
watch(count, (val, old) => {
/* ... */
})
// 假设count是一个对象,也支持监听整个对象,而无需指定deep属性
// 监听多个数据源
const count = ref(0)
const obj = reactive({name:'molly'})
watch([() => obj.name, count], ([newName, newCount], [oldName, oldCount]) => {
/* ... */
})
// 监听多个数据源时,watch函数的第一个参数可传入数据源数组,第二个回调函数的参数也是一个数组
vue3
also added watchEffect
, which means that a function passed in is executed immediately, while its dependencies are tracked responsively, and the function is rerun when its dependencies change.
Compared with watch
, watchEffect
does not need to pass in the specified monitoring data source, it will automatically collect dependencies. There is also no concept of new value and old value, as long as the dependency changes, the function will be re-executed
const count = ref(0)
watchEffect(() => console.log(count.value))
setTimeout(() => {
count.value++
}, 100)
watchEffect
will return a function to stop the listener
When watchEffect
in a component's setup
function or lifecycle hook is called, the listener is linked to that component's lifecycle and automatically stops when the component is unloaded.
const stop = watchEffect(() => {
/* ... */
})
stop()
filters
vue2
, we can easily use the filters filter to process some text format conversion and process the data.
filters: {
sum(num1,num2) {
return num1+num2
}
}
PLEASE NOTE: In vue3
the filter will be removed and is no longer supported. Officials recommend that we use method calls or computed properties to replace filters
As for why this is removed api
the official explanation is: although this seems convenient, it requires a custom syntax that breaks the expression inside the curly brackets "just JavaScript
" assumption, this has not only a learning cost, but also an implementation cost.
My understanding is: api
the function design is repeated, filters
can do things, computed properties and function calls can also be done, and they can be done better. So Youda tearfully removed filters
, poor filters
can only be discarded
The same is true of life, the survival of the fittest in the workplace, I hope we will never be the one who is optimized filters
😭😭😭
components
vue2
, we need to register the component through the option components
, and in vue3
, we can use the component directly
//vue2
import A from './a.vue'
components:{
A
}
//vue3
<template>
<A/>
</template>
<script setup>
import A from './a.vue'
</script>
Instructions: vue2 VS vue3
The instruction usage of the two versions is basically the same, here I only list the differences vue3
v-model
vue2
We implement a custom v-model
can write like this
// vue2
props:{
title:{
type:String,
default: 'molly'
}
},
model: {
prop: 'title',
event: 'change',
},
methods:{
change(val){
this.$emit('input',val)
}
},
vue3
can define v-model
parameter name, and also supports to set multiple v-model
// vue3
props:{
title:{
type:String
},
num:{
type:Number
},
},
setup(props,{emit}){
function change1(val){
emit('update:title',val)
}
function change2(val){
emit('update:num',val)
}
return {
change1,
change2
}
}
// 在父组件中使用
<Son v-model:title="molly" v-model:num="18" />
add command
-
v-memo
, which remembers a subtree of a template. Available on both elements and components. This instruction accepts a fixed-length array as a dependency value for memory comparison. If every value in the array is the same as when it was last rendered, the entire subtree update is skipped. Equivalent to memory for time, the same rendering content is read from memory. This is useful for long list scenarios
Other changes
- For
v-if
/v-else
/v-else-if
each branch-key
will no longer be necessary, because nowvue3
will automatically generate a uniquekey
- The
<template v-for>
ofkey
should be set on the<template>
label (not on its children). - When acting on the same element,
v-if
will have higher priority thanv-for
. - The
v-on
.native
modifier for ---5ef0c5990d56da07fc113bcee09a9647--- has been removed. -
v-for
ref
No longer registeredref
array in ---6e340188212730014bfc88b5e2050eb7--- When using
v-bind="object"
with the same name as component individual properties, then the order in which the bindings are declared will determine how they are combined. The latter is the standard<!-- 模板 --> <div id="red" v-bind="{ id: 'blue' }"></div> <!-- 结果 --> <div id="blue"></div> <!-- 模板 --> <div v-bind="{ id: 'blue' }" id="red"></div> <!-- 结果 --> <div id="red"></div>
Component communication: vue2 VS vue3
A variety of ---396c71deccafba23b5fcdc9000e9023b vue2
are provided in api
for our component communication:
-
props
/$emit
/$on
-
$attrs
/$listeners
-
provide
/inject
-
$parent
/$children
/ref
Most of the --- vue3
are still supported in api
, and have been adjusted appropriately
- Removed
$on
,$off
,$once
instance methods - Removed
$children
instanceproperty
-
$attrs
now includes allattribute
ea10ff22a784d4c58842ea5c8177225a--- passed to the component, includingclass
andstyle
- In
<script setup>
you must usedefineProps
anddefineEmits
API to declareprops
andemits
, they have the full type Inferred and directly available in<script setup>
slot vue2 vs vue3
In the slot, the two versions are basically the same, and there are not many changes, and the original use method is still retained. vue3
made a small update
-
this.$slots
Now expose slots as functions - Removed
this.$scopedSlots
Code reuse vue2 VS vue3
vue2
There are many ways of code reuse, mainly in the following ways
- Component extraction
- custom directive
- Instances are mounted globally
- Plug-in package
- mixin
- extend
vue3
also covers the above methods, and makes corresponding optimizations and updates
- The method of instance global mounting is in
vue2
, we generally useprototype
to mount the behavior object to thevue
prototype, this way Although simple and straightforward, there is also the problem of global pollution.
Vue.prototype.$xxx = {name:'molly'}
Corresponding to vue3
, we are not allowed to do this, and replaced by app.config.globalProperties
-
mixin
is also a great tool for code reuse, but it also exposes some problems. Whenmixin
is abused or used heavily, it can lead to unclear dependencies and difficult maintenance. Invue3
it is recommended that we use the customhooks
method to reuse code.
Implement a custom hook
We can extract data and logic related to a function and maintain it together, such as implementing an accumulator
import {ref, onUnmounted} from 'vue'
export function useAccumulator(){
const count = ref(0)
let timer = null
timer = setInterval(()=>{
count.value ++
},1000)
onUnmounted(()=>{
clearInterval(timer)
})
return {count}
}
We define an accumulator hooks
function, which can be used like a normal function at the component entry useAccumulator()
import {useAccumulator} from '../utils'
let {count} = useAccumulator()
script setup added
Paste the description on the official website
<script setup>
is compile-time syntactic sugar for using the composition API in a single-file component (SFC). It has more advantages over the normal <script>
syntax:
- Less boilerplate, cleaner code.
- Able to use plain
Typescript
declareprops
and throw events. - Better runtime performance (its templates are compiled into render functions in the same scope, without any intermediate proxies).
- Better IDE type inference performance (reduces the language server's work to extract types from the code).
<script setup>
has brought us great convenience, the advantages are as follows:
- All top-level bound variable contents can be used directly in the template
-
<script setup>
The value in the range can also be used directly as the label name of the custom component, which means that we can register the component without passingcomponents
- Support using
:is
to bind dynamic components - Support top-level
await
, first thanJavaScript
One step to realize this feature is cool
Powerful style features
Powerful style
characteristics vue3
another magic weapon
depth selector
In order to make the styles between components do not affect each other, we can write <style scoped>
, when in scoped
and want to make deep selection, you can use :deep()
pseudo-class
<style scoped>
.a :deep(.b) {
...
}
</style>
slot selector
By default, the scope style does not affect the <slot/>
content, you can use the :slotted
pseudo-class to select the slot
:slotted(div) {
color: red;
}
global selector
Global styles can be implemented through the :global
pseudo-class
:global(.red) {
color: red;
}
css module support
The css class can be exposed to the component as the $style
object through the <style module>
method, and also supports custom names: <style module=“molly” >
<template>
<p :class="molly.red">red</p>
</template>
<style module="molly">
.red {
color: red;
}
</style>
state driven dynamic css
This is the most convenient feature in my opinion, it allows us to write a lot less code, which is very cool
In style
allows us to use v-bind
to dynamically associate css values to components
<template>
<div class="text">hello</div>
</template>
<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>
<style>
// v-bind可以直接引入script中的响应数据作为值
.text {
color: v-bind(color);
}
</style>
Well, at this point, it should be easy to get started with the vue3 project. Friends who like it are welcome to like and leave a message for discussion. Like more than 30, I will continue to update the differentiated comparison vue-router4.x and vuex 4.x series
grateful
scatter flowers✿✿ヽ(°▽°)ノ✿
scatter flowers✿✿ヽ(°▽°)ノ✿
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。