根标签
Vue2
-
Templata
只支持一个根标签
<template>
<div></div>
</template>
Vue3
-
Templata
支持多个根标签
<template>
<div></div>
<img/>
</template>
初始化方法
Vue2
- 使用
new Vue()
, 参数是new Vue({template, render})
import Vue from 'vue';
import router from './routers/';
import store from './stores';
import App from './App.vue';
const app = new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
Vue3
- 使用
createApp()
参数是createApp(组件)
import { createApp } from 'vue';
import App from './App.vue';
import { router } from './router';
const app = createApp(App).use(router).mount('#app');
挂载容器
Vue2
- 可以通过
el
选项和$mount()
方法来挂载容器
new Vue({
el:'容器名字 '
})
new Vue({
}).$mount('容器名字')
Vue3
- 只能通过
mount()
方法来挂载容器
Vue.createApp({
}).mount('容器名字')
data选项
Vue2
-
data
选项可以是一个对象,也可以是一个方法(由方法返回一个对象)
new Vue({
el:'容器名字 ',
data:{
}
//或者
new Vue({
el:'容器名字 ',
data () {
return { }
}
})
})
Vue3
-
data
选项只能是一个方法,由方法返回一个对象
Vue.createApp({
data(){
return{}
}
}).mount('容器名字')
响应式原理
Vue2的响应式
核心:
- 对象: 通过
defineProperty
对对象的已有属性值的读取和修改进行劫持(监视/拦截) - 数组: 通过重写数组更新数组一系列更新元素的方法来实现元素修改的劫持
Object.defineProperty(data, 'count', {
get () {},
set () {}
})
问题:
- 对象直接新添加的属性或删除已有属性, 界面不会自动更新
- 直接通过下标替换元素或更新length, 界面不会自动更新 arr[1] = {}
Vue3的响应式
核心:
new Proxy(data, {
// 拦截读取属性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 拦截设置属性值或添加新属性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 拦截删除属性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxy.name = 'tom'
Vue3的响应式数据的核心原理
简单实现,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Proxy 与 Reflect</title>
</head>
<body>
<script>
const user = {
name: "John",
age: 12
};
/*
proxyUser是代理对象, user是被代理对象
后面所有的操作都是通过代理对象来操作被代理对象内部属性
*/
const proxyUser = new Proxy(user, {
get(target, prop) {
console.log('劫持get()', prop)
return Reflect.get(target, prop)
},
set(target, prop, val) {
console.log('劫持set()', prop, val)
return Reflect.set(target, prop, val); // (2)
},
deleteProperty (target, prop) {
console.log('劫持delete属性', prop)
return Reflect.deleteProperty(target, prop)
}
});
// 读取属性值
console.log(proxyUser===user)
console.log(proxyUser.name, proxyUser.age)
// 设置属性值
proxyUser.name = 'bob'
proxyUser.age = 13
console.log(user)
// 添加属性
proxyUser.sex = '男'
console.log(user)
// 删除属性
delete proxyUser.sex
console.log(user)
</script>
</body>
</html>
Vue3更好的 ts 支持
- vue2 不适合使用 ts,在于它的 Options API 风格。
- options 是一个简单的对象,而 ts 是一种类型系统、面向对象的语法,两个不匹配。
- vue3 新增了 defineComponent 函数,使组件在 ts 下,更好的利用参数类型推断。如:reactive 和 ref 很具有代表性。
Vue3更先进的组件
Fragment
- vue2 中,每个模板必须有一个根节点,否则就会报错。
- vue3 中可以不需要根节点,多个元素或标签可并列存在。
Teleport
- 可以把 teleport 中的内容添加到任意的节点内,对于嵌套较深的组件来说绝对是一个福音。
Supense
- 允许程序在等待异步组件渲染一些后备的内容,可以让我们创建一个平滑的用户体验。
Vue3新推出的组合式API
- Vue2:定义方法的时候需要写在methods里面,后添加的属性是非响应式的。页面不更新。需要用get()和set()方法
- Vue3:组合式API的作用是将原来分散开来定义的数据、方法、计算属性、监听器、组合起来定义一个完整的业务。
生命周期
vue2的生命周期
vue2.pngvue3的生命周期
vue3.png与 2.x 版本生命周期相对应的组合式 API
-
beforeCreate
-> 使用setup()
-
created
-> 使用setup()
-
beforeMount
->onBeforeMount
-
mounted
->onMounted
-
beforeUpdate
->onBeforeUpdate
-
updated
->onUpdated
-
beforeDestroy
->onBeforeUnmount
-
destroyed
->onUnmounted
-
errorCaptured
->onErrorCaptured
组合式 API 还提供了以下调试钩子函数:
onRenderTracked
onRenderTriggered
例子
演示各个生命周期钩子
父组件App
<template>
<h2>App</h2>
<button @click="isShow=!isShow">切换</button>
<hr>
<Child v-if="isShow"/>
</template>
<script lang="ts">
import Child from './Child.vue'
export default {
data () {
return {
isShow: true
}
},
components: {
Child
}
}
</script>
子组件Child
<template>
<div class="about">
<h2>msg: {{msg}}</h2>
<hr>
<button @click="update">更新</button>
</div>
</template>
<script lang="ts">
import {
ref,
onMounted,
onUpdated,
onUnmounted,
onBeforeMount,
onBeforeUpdate,
onBeforeUnmount
} from "vue"
export default {
beforeCreate () {
console.log('beforeCreate()')
},
created () {
console.log('created')
},
beforeMount () {
console.log('beforeMount')
},
mounted () {
console.log('mounted')
},
beforeUpdate () {
console.log('beforeUpdate')
},
updated () {
console.log('updated')
},
beforeUnmount () {
console.log('beforeUnmount')
},
unmounted () {
console.log('unmounted')
},
setup() {
const msg = ref('abc')
const update = () => {
msg.value += '--'
}
onBeforeMount(() => {
console.log('--onBeforeMount')
})
onMounted(() => {
console.log('--onMounted')
})
onBeforeUpdate(() => {
console.log('--onBeforeUpdate')
})
onUpdated(() => {
console.log('--onUpdated')
})
onBeforeUnmount(() => {
console.log('--onBeforeUnmount')
})
onUnmounted(() => {
console.log('--onUnmounted')
})
return {
msg,
update
}
}
}
</script>
网友评论