Article directory
Mainly to record what I learned from the video at station b, record notes, video address Shang Silicon Valley Vue2.0+Vue3.0 full set of tutorial丨vuejs from entry to master
Introduction
Vue.js released version 3.0 on September 18, 2020, codenamed: One Piece (One Piece), which
took more than 2 years, 2600+ submissions, 30+ RFCs, 60+ PRs, and 99 contributors
performance improvements
- 41% reduction in bundle size
- 55% faster initial render, 133% faster update render
- 54% less memory
Source code upgrade
Proxy
Reactive usingdefineProperty
instead- Override virtual
DOM
implementation andTree-Shaking
(import on demand)
Embrace TypeScript
- Vue3 can better support TypeScript
new features
1. Composition API (combination API)
setup
configurationref
andreactive
watch
andwatchEffect
provide
andinject
- …
2. New built-in components
Fragment
Teleport
Suspense
3. Other changes
- new lifecycle hook
- The data option should always be declared as a function
- Remove keyCode support as v-on modifier
- …
Create a Vue3 project
1. Use vue-cli to create
The version of vue-cli needs to be above 4.5.0 to install vue3 scaffolding. You can use vue --version
or vue --version
view the current version. If the version is lower than 4.5.0, use npm install -g @vue/cli
or yarn global add @vue/cli
upgrade the version
## 查看@vue/cli版本
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建Vue项目,选择Vue3
vue create vue3_test
## 启动
cd vue3_test
npm run serve
When creating a project, it will prompt version 2.x and version 3.x, just choose Vue 3 here
2. What is Vite
Official document https://v3.cn.vuejs.org/guide/installation.html#vite
official website https://vitejs.cn/
- It is a new generation of front-end construction tools created by the Vue team.
- The advantages are as follows:
- In the development environment, no packaging operation is required, and it can be cold started quickly.
- Lightweight and fast Hot Reload (HMR).
- True on-demand compilation, no longer waiting for the entire application to be compiled.
- Comparison chart of traditional construction and
vite
construction There are construction tools such as , , and so on, which are still mainstream
at present and relatively immature, but I believe it will become a trend in the future.vite
grunt
gulp
webpack
webpack
vite
- Create a project using vite
## 创建工程
npm init vite-app my_vite
## 进入工程目录
cd my_vite
## 安装依赖
npm install
## 运行
npm run dev
There is no node_modules dependency package for vite
the created project, so it needs to be installed manually
3. Analysis files
main.js
This is main.js in vue3, and then let's analyze this paragraph
import {
createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
// 引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数
import {
createApp } from 'vue'
import App from './App.vue'
// 创建应用实例对象——app(类似于之前Vue2中的vm,但app比vm更“轻”)
// 这个轻指的是在app身上属性和方法相对于vm少了很多
const app = createApp(App)
// 来输出一下app为什么更轻
console.log(app)
// 挂载
app.mount('#app')
app.vue
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
In vue3, there is no need to add a div root element like vue2
Composition API
1. kicked offsetup
- Understanding: A new configuration item in Vue3.0, the value is a function.
- setup is the "stage of performance" of all Composition APIs (composition APIs).
- The components used in the components: data, methods, etc., must be configured in the setup.
- Two return values of the setup function:
- If an object is returned, the properties and methods in the object can be used directly in the template. (Focus!)
- If it returns a rendering function: you can customize the rendering content. (just understand)
- important point:
-
Try not to mix with Vue2.x configuration
- Properties and methods in setup can be accessed in Vue2.x configuration (data, methos, computed...).
- But Vue2.x configuration (data, methos, computed...) cannot be accessed in setup.
- If there are duplicate names, setup takes precedence.
-
setup cannot be an async function, because the return value is no longer an object, but a promise, and the template cannot see the properties in the return object. (You can also return a Promise instance later, but it requires the cooperation of Suspense and asynchronous components)
<template>
<h1>个人信息</h1>
<h2>姓名:{
{
name}}</h2>
<h2>性别:{
{
sex}}</h2>
<h2>年龄:{
{
age}}</h2>
<button @click="sayHello">输出</button>
</template>
<script>
export default {
name: 'App',
setup(){
// 测试数据暂时不是响应式
let name = "蜜枣"
let age = 18
let sex = "男"
function sayHello() {
alert(`我叫${
name},今年${
age}岁`)
}
return{
name,
age,
sex,
sayHello
}
}
}
</script>
2. ref
Function
-
Role: Define a responsive data
-
grammar:
const xxx = ref(initValue)
- Create a reference object (reference object, ref object for short) that contains responsive data.
- Data manipulation in JS:
xxx.value
- Read data in the template: No need
.value
, directly:<div>{ {xxx}}</div>
-
Remark:
- The received data can be: basic type or object type.
- Basic types of data: Responsiveness relies on class
getter
andsetter
completion (we will see the source code later and you will know). - Object type data: internally "rescue" a new function in Vue3.0 -
reactive
function.
<template>
<h1>个人信息</h1>
<h2>姓名:{
{
name}}</h2>
<h2>性别:{
{
sex}}</h2>
<h2>年龄:{
{
age}}</h2>
<button @click="sayHello">输出</button>
<button @click="age++">一年后</button>
</template>
<script>
// 引入ref定义响应式的数据
import {
ref} from "vue"
export default {
name: 'App',
setup(){
let name = ref("蜜枣")
let age = ref(18)
let sex = ref("男")
function sayHello() {
alert(`我叫${
name.value},今年${
age.value}岁`)
}
return{
name,
age,
sex,
sayHello
}
}
}
</script>
Ref will return an instance object of RefImpl. Getter and setter are bound to the prototype object to detect data changes. Ref refers to reference, and Impl refers to implement, which is to refer to the implementation object
reactive
function
- Function: Define an object type of responsive data (do not use it for basic types, but use
ref
functions) - Syntax:
const 代理对象= reactive(源对象)
Receive an object (or array) and return a proxy object (Proxy
an instance object, referred to asproxy
an object) reactive
Reactive data is defined as "deep".- The internal
Proxy
implementation , and the internal data of the source object is manipulated through the proxy object.
<template>
<h1>个人信息</h1>
<h2>姓名:{
{
userInfo.name}}</h2>
<h2>性别:{
{
userInfo.sex}}</h2>
<h2>年龄:{
{
userInfo.age}}</h2>
<h2>职业:{
{
userInfo.type}}</h2>
<h2>爱好:{
{
userInfo.hobby}}</h2>
<h2 v-show="userInfo.data">新增data:{
{
userInfo.data}}</h2>
<button @click="changeUserInfo">修改信息</button>
</template>
<script>
// 引入ref定义响应式的数据
import {
reactive} from "vue"
export default {
name: 'App',
setup(){
let userInfo = reactive({
name:"蜜枣",
age:18,
sex:"男",
type:"切图仔",
hobby:["听歌","学习","玩游戏"]
})
function changeUserInfo() {
userInfo.age = 22
userInfo.type = "前端工程师"
userInfo.hobby[0] = "唱歌"
}
return{
userInfo,
changeUserInfo
}
}
}
</script>
Responsive principle in Vue3.0
Responsiveness of Vue2.x
- Realization principle
- Object type:
Object.defineProperty()
Intercept (data hijacking) by reading and modifying properties. - Array type: interception is achieved by overriding a series of methods for updating the array. (The change method of the array is wrapped).
- Object type:
Object.defineProperty(data, 'count', {
get () {
},
set () {
}
}
- There is a problem
- Use
Vue.set
,Vue.delete
orvm.$set
,vm.$delete
these APIs
- Use
Responsiveness of Vue3.0
<template>
<h1>个人信息</h1>
<h2>姓名:{
{
userInfo.name}}</h2>
<h2>性别:{
{
userInfo.sex}}</h2>
<h2>年龄:{
{
userInfo.age}}</h2>
<h2>职业:{
{
userInfo.type}}</h2>
<h2>爱好:{
{
userInfo.hobby}}</h2>
<h2 v-show="userInfo.data">新增data:{
{
userInfo.data}}</h2>
<button @click="changeUserInfo">修改信息</button>
<button @click="addData">增加数据</button>
<button @click="delHobby">删除数据</button>
</template>
<script>
// 引入ref定义响应式的数据
import {
reactive} from "vue"
export default {
name: 'App',
setup(){
let userInfo = reactive({
name:"蜜枣",
age:18,
sex:"男",
type:"切图仔",
hobby:["听歌","学习","玩游戏"]
})
function changeUserInfo() {
userInfo.age = 22
userInfo.type = "前端工程师"
userInfo.hobby[0] = "唱歌"
}
function addData(){
userInfo.data = 666
}
function delHobby(){
delete userInfo.data
}
return{
userInfo,
changeUserInfo,
addData,
delHobby
}
}
}
</script>
- Realization principle
- Pass
Proxy
(proxy): Intercept the change of any attribute in the object, including: reading and writing of attribute values, adding attributes, deleting attributes, etc. - Via
Reflect
(reflection): Operate on properties of the source object. - As described in the MDN docs
Proxy
withReflect
:
- Pass
reactive
Comparedref
-
Comparison from the perspective of definition data
ref
Used to define: basic type data .reactive
Used to define: object (or array) type data .- Remarks:
ref
It can also be used to define object (or array) type data , which will be automatically converted toreactive
a proxy object internally .
-
Comparison from a principle point of view
ref
Responsiveness (data hijacking) is achieved throughgetter
AND in the class .setter
reactive
Proxy
Responsive (data hijacking) is achieved by using , and byReflect
manipulating the data inside the source object.
-
From the point of view of use
ref
Defined data: required for.value
operating data , but not required.value
for direct reading in the template when reading data .reactive
Defined data: operation data and read data: neither is required.value
.
setup
two points of attention
setup
Timing of executionbeforeCreate
Do it once before ,this
yesundefined
.
setup
parameters-
props
: The value is an object, including: the properties passed from outside the component and received by the internal declaration of the component. -
context
: context objectattrs
: The value is an object, including: attributes passed from outside the component but notprops
declared in the configuration, equivalent tothis.$attrs
.slots
: Received slot content, equivalent tothis.$slots
.emit
: A function that dispatches a custom event, equivalent tothis.$emit
.
-
- Parent-child component passing value
Parent component App.vue
<template>
<Demo msg="Hello World"></Demo>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
components: {
Demo },
name: 'App'
}
</script>
Subgroup Demo.vue
<template>
<h1>{
{
msg}}</h1>
</template>
<script>
export default {
props:["msg"],
setup(props,context){
console.log('---props---',props);
console.log('---context.attrs---', context.attrs)
}
}
</script>
- Custom event
parent component App.vue
<template>
<Demo @hello="sayHello" msg="hello world"></Demo>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
components: {
Demo },
name: 'App',
setup(){
function sayHello(value){
alert(`你触发了hello事件,我收到的参数是:${
value}!`);
}
return{
sayHello
}
}
}
</script>
Subgroup Demo.vue
<template>
<div>{
{
msg}}</div>
<button @click="test">点击触发一下Demo组件的Hello事件</button>
</template>
<script>
export default {
props:["msg"],
emits:["hello"], // 如果不写则控制台会出现警告,如下图
setup(props,context){
console.log('---props---',props);
console.log('---context.attrs---', context.attrs)
function test() {
context.emit("hello", "Hello world");
}
return{
test
}
}
}
</script>![请添加图片描述](https://img-blog.csdnimg.cn/29d1ca70220b420c8c23e52ad51453e6.gif)
- slot
<!-- App.vue -->
<template>
<Demo>
<div>我是Demo组件的插槽</div>
</Demo>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
components: {
Demo },
name: 'App'
}
</script>
<!-- Demo.vue -->
<template>
<slot></slot>
</template>
Computed properties and monitoring
computed
function
computed
Consistent with the configuration function in Vue2.x
<template>
姓:<input type="text" v-model="person.firstNmae">
<br>
名:<input type="text" v-model="person.lastName">
<br>
<span>全名:{
{
person.fullName}}</span>
<br>
<input type="text" v-model="person.fullName">
</template>
<script>
import {
computed, reactive } from '@vue/reactivity';
export default {
name: 'App',
setup(){
let person = reactive({
firstNmae:"张",
lastName:"三"
})
// 计算属性-简写(没有考虑计算属性被修改的情况)
// 这种情况下去修改计算属性控制台会警告 computed value is readonly
person.fullName = computed(()=>{
return person.firstNmae + '-' + person.lastName
})
// 计算属性-完整(考虑读和写的情况)
person.fullName = computed({
get(){
return person.firstNmae + '-' + person.lastName
},
set(value){
const nameArr = value.split("-")
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
return{
person
}
}
}
</script>
watch
function
-
watch
Consistent with the configuration function in Vue2.x -
Two small "pits":
- When monitoring
reactive
the defined responsive data:oldValue
it cannot be obtained correctly, and the deep monitoring is forced to be turned on (deep
configuration invalidation). - When monitoring
reactive
a property in the defined reactive data:deep
the configuration is valid.
- When monitoring
<template>
<h2>sum:{
{
sum}}</h2>
<button @click="sum++">点击+1</button>
<h2>当前信息:{
{
msg}}</h2>
<button @click="msg+='~'">修改信息</button>
<h2>姓名:{
{
person.name}}</h2>
<h2>年龄:{
{
person.age}}</h2>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">修改年龄</button>
</template>
<script>
import {
reactive,ref,watch} from "vue"
export default {
name: 'Demo',
setup(){
let sum = ref(0)
let msg = ref("你好啊")
let person = reactive({
name:"张三",
age:20
})
//情况一:监视ref定义的响应式数据
watch(sum,(newValue,oldValue)=>{
console.log('sum变化了',newValue,oldValue)
},{
immediate:true})
//情况二:监视多个ref定义的响应式数据
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum或msg变化了',newValue,oldValue)
})
// 情况三:监视reactive定义的响应式数据的全部属性
// 1.注意:此处无法获取正确的oldValue
// 2.注意:强制开启深度监听(deep配置失效)
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{
immediate:true,deep:false}) //此处的deep配置无效
// 情况四:监视reactive定义的响应式数据中的某个属性
watch(()=>person.name,(newValue,oldValue)=>{
console.log('person的name变化了',newValue,oldValue)
},{
immediate:true,deep:true})
//情况五:监视reactive定义的响应式数据中的某些属性
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
console.log('person的job或者name变化了',newValue,oldValue)
},{
immediate:true,deep:true})
//特殊情况
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{
deep:true}) //此处由于监视的是reactive所定义的对象中的某个属性,所以deep配置有效
return{
sum,
msg,
person
}
}
}
</script>
watchEffect
function
-
watch
The routine is: specify not only the attribute of monitoring, but also the callback of monitoring. -
watchEffect
The routine is: don't specify which attribute to monitor, which attribute is used in the monitoring callback, then monitor which attribute. -
watchEffect
Something likecomputed
:- But
computed
pay attention to the calculated value (the return value of the callback function), so the return value must be written. - And
watchEffect
more attention is paid to the process (the function body of the callback function), so there is no need to write the return value.
- But
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
const x1 = sum.value
const x2 = person.age
console.log('watchEffect配置的回调执行了')
})
life cycle
- The lifecycle hooks in Vue2.x can continue to be used in Vue3.0, but two of them have been renamed:
beforeDestroy
rename tobeforeUnmount
destroyed
rename tounmounted
Lifecycle hooks can be used directly in the form of configured items, or in the form of combined APIs, as uniform as possible. Generally speaking, the hooks in the combined API will be executed before the hooks of the configuration items. The name of the hook in the combined API Change
- Vue3.0 also provides lifecycle hooks in the form of Composition API, and the corresponding relationship with the hooks in Vue2.x is as follows:
custom hook
function
-
what is
hook
it —— It is essentially a function that encapsulates the Composition API used in the setup function. -
mixin
Similar to that in vue2.x. -
Advantages of customization
hook
: Reuse code to makesetup
the logic in it clearer and easier to understand.
Create a hooks folder in the src directory, and create a usePoint.js file in the folder to encapsulate the method of point management
import {
reactive } from '@vue/reactivity';
import {
onBeforeMount, onMounted } from '@vue/runtime-core';
export default function(){
let point = reactive({
x:0,
y:0
})
//鼠标“打点”的方法
function savePoint(event) {
point.x = event.pageX;
point.y = event.pageY;
console.log(event.pageX, event.pageY);
}
onMounted(()=>{
window.addEventListener("click",savePoint)
})
onBeforeMount(()=>{
window.removeEventListener("click",savePoint)
})
return point
}
Then introduce this method in the Demo component
<template>
<h1>当前鼠标的坐标为:X:{
{
point.x}},Y:{
{
point.y}}</h1>
</template>
<script>
import usePoing from "../hooks/usePoint"
export default {
name: "Demo",
setup() {
let point = usePoing()
return {
point
};
},
};
</script>
toRef
- Function: Create an
ref
object whosevalue
value points to an attribute in another object. - grammar:
const name = toRef(person,'name')
- Application: When you want to provide a property in the responsive object for external use alone.
- Extension: Same
toRefs
astoRef
the function, but multipleref
objects , syntax:toRefs(person)
<template>
{
{
person}}
<h1>姓名:{
{
name}}</h1>
<h1>年龄:{
{
age}}</h1>
<button @click="name+='!'">修改姓名</button>
<button @click="age++">增长年龄</button>
<demo></demo>
</template>
<script>
import {
reactive, toRef, toRefs } from '@vue/reactivity';
import Demo from './components/Demo.vue';
export default {
components: {
Demo },
name: 'App',
setup(){
let person = reactive({
name:"蜜枣",
age:18
})
return{
person,
// name:toRef(person,"name"),
// age:toRef(person,"age"),
...toRefs(person)
}
}
}
</script>
Other Composition APIs
shallowReactive
andshallowRef
-
shallowReactive
: Responsive (shallow responsive) that only deals with the outermost properties of the object. -
shallowRef
: Only handle the responsiveness of basic data types, not the responsiveness of objects. -
When to use it?
- If there is an object data, the structure is relatively deep, but only the outer attribute changes ===> when changing
shallowReactive
. - If there is an object data, subsequent functions will not modify the properties in the object, but generate new objects to replace ===>
shallowRef
.
- If there is an object data, the structure is relatively deep, but only the outer attribute changes ===> when changing
readonly
andshallowReadonly
readonly
: Make a reactive data read-only (deep read-only).shallowReadonly
: Make a reactive data read-only (shallow read-only).- Application scenario: When the data is not expected to be modified.
toRaw
andmarkRaw
<template>
<input type="text" v-model="keyWord" />
<h3>{
{
keyWord }}</h3>
</template>
<script>
import {
customRef } from "vue";
export default {
name: "App",
setup() {
//自定义一个ref——名为:myRef
function myRef(value, delay) {
let timer;
// 通过curstomRef去实现自定义
return customRef((track, trigger) => {
return {
get() {
console.log(`有人从myRef这个容器中读取数据了,我把${
value}给他了`);
track(); // 通知Vue追踪value的变化(提前和get商量一下,让他认为这个value是有用的)
return value;
},
set(newValue) {
console.log(`有人把myRef这个容器中数据改为了:${
newValue}`);
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
trigger(); // 告诉vue去更新页面
}, delay);
},
};
});
}
// let keyWord = ref('hello') //使用Vue提供的ref
let keyWord = myRef("hello", 500); //使用自定义的ref
return {
keyWord };
},
};
</script>
provide
andinject
-
Role: Realize communication between ancestor and descendant components
-
Routine: The parent component has a provide option to provide data, and the descendant components have an inject option to start using the data
In the parent component:
setup(){
......
let car = reactive({
name:'奔驰',price:'40万'})
provide('car',car) // 给自己的后代组件传递数据
......
}
In descendant components:
setup(props,context){
......
const car = inject('car') // 拿到祖先的数据
return {
car}
......
}
Responsive Data Judgment
isRef
: checks if a value is anref
objectisReactive
: Checks if an object wasreactive
created a reactive proxyisReadonly
: Checks if an object is a read-only proxy created by readonly`isProxy
: checks if an objectreactive
isreadonly
a proxy created by the or method
V3 new components
Fragment
- In Vue2: Components must have a root tag
- In Vue3: Components can have no root tags, and multiple tags will be included in a Fragment virtual element internally
- Benefits: Reduce label levels, reduce memory usage
Teleport
- what is
Teleport
it —Teleport
is a technique that can move our componenthtml
structure to a specified location.
Here is an example to assign a dialog popup window to the body
app.vue
<template>
<div class="app">
<h3>我是App组件</h3>
<Child />
</div>
</template>
<script>
import Child from "./components/Child";
export default {
name: "App",
components: {
Child },
};
</script>
<style>
.app {
background-color: gray;
padding: 10px;
}
</style>
Child.vue
<template>
<div class="child">
<h3>我是Child组件</h3>
<Son />
</div>
</template>
<script>
import Son from "./Son";
export default {
name: "Child",
components: {
Son },
};
</script>
<style>
.child {
background-color: skyblue;
padding: 10px;
}
</style>
Sound.view
<template>
<div class="son">
<h3>我是Son组件</h3>
<Dialog />
</div>
</template>
<script>
import Dialog from "./Dialog.vue";
export default {
name: "Son",
components: {
Dialog },
};
</script>
<style>
.son {
position: relative;
background-color: orange;
padding: 10px;
}
</style>
Dialog.view
<template>
<div>
<button @click="isShow = true">点我弹个窗</button>
<!-- <teleport to='body'> -->
<div v-if="isShow" class="mask">
<div class="dialog">
<h3>我是一个弹窗</h3>
<h4>一些内容</h4>
<h4>一些内容</h4>
<h4>一些内容</h4>
<button @click="isShow = false">关闭弹窗</button>
</div>
</div>
<!-- </teleport> -->
</div>
</template>
<script>
import {
ref } from "vue";
export default {
name: "Dialog",
emits:["isShow"],
setup(props,context) {
console.log(props,context)
let isShow = ref(false);
context.emit("isShow",isShow)
return {
isShow };
},
};
</script>
<style>
.mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
width: 300px;
height: 300px;
background-color: #eee;
}
</style>
Here you can see that the mask mask layer will be on the descendant components, so you need to use teleport
the label
and then untie the comment of the label in the code teleport
to see that the mask mask layer points to the body
Suspense
-
Render some extra content while waiting for asynchronous components, so that the application has a better user experience
-
Steps for usage:
- Import components asynchronously
import {
defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
Use Suspense
the wrapper component, and configure it default
withfallback
<template>
<div class="app">
<h3>我是App组件</h3>
<Suspense>
<template v-slot:default>
<Child/>
</template>
<template v-slot:fallback>
<h3>加载中.....</h3>
</template>
</Suspense>
</div>
</template>
other
Global API transfer
- Vue 2.x has many global APIs and configurations.
- For example: registering global components, registering global directives, etc.
//注册全局组件
Vue.component('MyButton', {
data: () => ({
count: 0
}),
template: '<button @click="count++">Clicked {
{ count }} times.</button>'
})
//注册全局指令
Vue.directive('focus', {
inserted: el => el.focus()
}
These APIs have been adjusted in Vue3.0:
- Adjust the global API, namely: Vue.xxx to the application instance (app)
2.x Global API (Vue) | 3.x instance API (app) |
---|---|
Vue.config.xxxx | app.config.xxxx |
Vue.config.productionTip | remove |
Vue.component | app.component |
Directive.view | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
Vue.prototype | app.config.globalProperties |
other changes
data
Options should always be declared as a function- Transitional class name changes
- Vue2.x writing method:
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-leave,
.v-enter-to {
opacity: 1;
}
- Vue3.x writing method:
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.v-leave-from,
.v-enter-to {
opacity: 1;
}
- Removed as
keyCode
a modifier for and also no longer supportsv-on
config.keyCodes
- remove
v-on.native
modifier- Bind event in parent component
<my-component
v-on:close="handleComponentEvent"
v-on:click="handleNativeClickEvent"
/>
- Declare custom events in subcomponents
<script>
export default {
emits: ['close']
}
</script>
- Remove Filters
filter
While this seems convenient, it requires a custom syntax that breaks the assumption that expressions inside curly braces are "just JavaScript", which has not only a learning cost, but an implementation cost as well! It is recommended to replace filters with method calls or computed properties. - …