Vue3新特性概述
一、双向数据绑定(响应式)原理
1. Vue2中的绑定
vue2的双向数据绑定是利用了es5 的一个API Object.definepropert() 对数据进行劫持 结合发布订阅模式来实现的。
new Vew({
data:{ n: 0 } //n被隐藏,外界不能直接使用
//给n添加get set方法,监听变化
n:{
get n(){ return this.n },
set n(value){
this.n = value;
通知函数() => 更新虚拟DOM树
}
}
methods:{
add(){ this.n++ } //修改外界的n,并非真正的data里面的n
}
})
缺点:
- 只能在首次创建的new Vue()对象里本就有的属性添加监听方法(访问器属性),后来添加的成员无法添加,因此不能监听到变化。
- 无法给索引数组的数字下标添加访问器属性。
- 结果:后来添加的成员、通过下标修改索引数组中的元素值,页面都不自动更新。
2. Vue3中的绑定
vue3中使用了es6的proxyAPI对数据进行处理。proxy在目标对象的外层起到一层拦截器作用,外界对目标对象的所有操作都必须通过这层拦截,因此后来添加的成员一样得到监视。
<body>
<script>
var arr = [1, 2, 3]
arr = new Proxy(arr, {
get(currentObject, toGetValuePoint) {
console.log(`有人视图获取arr中${toGetValuePoint}位置的元素值`)
return currentObject[toGetValuePoint]
},
set(currentObject, toGetValuePoint, newValue) {
console.log(`有人视图获取arr中${toGetValuePoint}位置的元素值为新值${newValue}`)
currentObject[toGetValuePoint] = newValue
}
})
let val = arr[3] //有人视图获取arr中3位置的元素值
arr[1] = 4 //有人视图获取arr中1位置的元素值为新值4
</script>
</body>
缺点:兼容性问题
二、脚手架创建的项目中的变化
1. main.ts文件 (了解)、axios模块化引入
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 模块化引入axios,不用像vue2一样挂到原型对象上,总是用this访问
import axios from 'axios'
axios.default.baseURL = '/。。。'
// 代替new Vew()
createApp(App).usu(router).use(store).mount(#app)
2. setup()
<template></template>
<script>
import { defineComponent, ref } from 'vue'
//vue3中引入defineComponent声明组件
export default defineComponent({
//setup代替了vue2的beforeCreate、created
//数据不再由data管理,而写在setup中
setup(props) {
let n = ref(10) //用ref包裹:起响应式作用 n={value:10}
let b = ref('zs')
const add = () => { n.value++ } //不可直接访问n,需通过n.value
//必须将数据return才可以在模板中使用 数据 和 方法
return { n, b, add }
}
})
</script>
<style></style>
- ref和toRefs配合使用集中监听
<template></template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup(){
const mydata = ref({
n: 10,
arr: [1,2,3],
obj: { name: 'zs', age: 18 }
})
//结构出来,并用toRefs保持其响应式特性
let { n, arr, obj } = toRefs(mydata.value)
const myMethods = {
add(){ n.value++ },
change(){ arr[1] = 10 }
}
return {
...toRefs(mydata.value), ...myMethods
}
}
})
</script>
<style></style>
3. watch监听函数
vue3中可写多个watch函数
<template></template>
<script>
import { defineComponent, ref, watch } from 'vue'
export default defineComponent({
setup() {
const mydata = ref({
n: 10,
arr: [1, 2, 3],
})
// 以便直接操作数据,不用 .value
let { n, arr } = toRefs(mydata.value)
watch(n,(newVal, oldVal) => { })
watch(arr,(newVal, oldVal) => { })
const myMethods = {
}
return {
...toRefs(mydata.value),
...myMethods
}
}
})
</script>
<style></style>
三、自定义指令
1. 全局自定义指令 main.ts 中
注:vue3中用mounted()函数代替了vue2中的inserted函数,其他用法一致。
<template>
<input v-my-focus>
</template>
var app = createApp(App)
app.directive('my-focus',{
mounted(el){
el.focus()
}
})
app.use(store).use(router).mount('#app')
2. 组件内有效的自定义指令
<template></template>
<script>
import { defineComponent, ref, watch } from 'vue'
export default defineComponent({
directive:{
'my-focus':{
mounted(el){
el.focus()
}
}
})
</script>
<style></style>
四、computed计算属性
<template></template>
<script>
import { defineComponent, ref, computed } from 'vue'
export default defineComponent({
setup() {
const mydata = ref({
phone:[
{id:1, name: 'huawei', price: 10, count: 2},
{id:2, name: 'iPhone', price: 30, count: 3},
{id:3, name: 'xiaomi', price: 20, count: 4}
]
})
//结构出来,并用toRefs保持其响应式特性
let { phone } = toRefs(mydata.value)
const myMethods = {
total: computed(() => {
return phone.value.reduce((box, elem) => {
box+elem.price*elem.count
},0)
})
}
return {
...toRefs(mydata.value),
...myMethods
}
}
})
</script>
<style></style>
五、过滤器
vue3中用计算属性代替过滤器
六、全局组件 main.ts 中
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import MyCom from './MyCom.vue'
app.component('my-com',MyCom)
createApp(App).usu(router).use(store).mount(#app)
七、props属性
https://www.jb51.net/article/240862.htm
八、其他变化
略
本文来自博客园,作者:RHCHIK,转载请注明原文链接:https://www.cnblogs.com/suihung/p/16654104.html