1、项目创建
支持两种方式:vuecli和vite。前者不在细说。提供vite的创建方法:
npm init vite-app vue3-demo
cd vue3-demo
npm install && npm run dev
可以看到,构建几乎是秒开。vite之所以构建迅速就是因为它和webpack走了相反的道路,如下图:
很显然,vite一上来直接就把server准备好了,然后异步引入,你需要什么就引入什么,所以速度上占了优势。
2、组合api
目前vue3在写法上还是兼容vue2的,options API(data, computed,methods)还是可以写入组件,但是新增的组合api却应该更令人关注。
2.1、setup函数
setup函数就是组合api们大展身手的舞台了。所有相关的数据、方法全部写在里边。举个例子
export default {
name: 'app',
setup () {
// 定义一个数据,注意这个数据不是响应式的
let num = 100;
function changNum () {
num = 1000
}
return {
num,
changeNum
}
}
}
这里需要注意的就是以下两点:
1、setup的执行时机是在beforeCreate和created之间,所以没有this。
2、setup中定义的方法和数据都要return出去,才能在模板中使用,否则无效。
setup函数有个两个参数 - props和context。
第一个props,不再多说,就是父级传递过来的数据。
第二个context,字面意思是上下文。他里边主要包含了三个东西:attrs,slots,emits。
attrs这个东西就是vue2中$attrs,俗称“捡漏之王”。只要是传递过来的数据,不在props中,就会在attrs中。这个很好理解。
slots这个就是插槽。所有的slot都存在这里。
emits对应的就是$emit。
很好理解,可以自己打印出来多试试。
2.2、响应式数据的创建 - ref和reactive
vue2中创建一个响应式的数据,直接写在data中就可以。但是在vue3中创建响应式数据,就必须引入组合api -- ref和reactive了。
这两个api都是创建响应式数据,他们之间有什么不同?
简单来说,ref创建基本数据类型的数据,reactive创建引用数据类型的数据。举个例子:
// 注意使用组合api比如显性引入 不能直接使用
import {ref, reactive} from 'vue'
export default {
name: 'app',
setup () {
let num = ref(0);
let person = reactive({
name: 'www',
age: 20,
from: {
country: {
province: 'xx'
}
}
})
// 注意 创建好的数据一定要return出去
return {num, person}
}
}
但是,这并不代表ref不能创建引用数据类型。只不过,ref创建的引用数据类型,底层走的还是reactive的方法。
那么reactive和ref的底层分别是什么?
vue2的响应式原理都是基于Object.defineProperty的。那么ref的响应式就是基于此,只有get和set,面对基本数据类型非常简单。但是对于负责的引用数据类型,就会使用proxy作为响应式映射。
两者区别,不在细说。
2.3、计算属性 - computed
同样的需要显性引入,然后传入一个函数,在函数中计算data,如下
import {computed} from 'vue'
export default {
name: 'app',
setup () {
let str = ref('hello');
let _str = computed(() => {
return str + 'world'
})
return {
str,
_str
}
}
}
2.4、监控 - watch和watchEffect
数据的监控,基本用法还是和vue2类似,watch函数接收三个参数,第一个是监控的属性,第二个是一个函数,包含newval和oldval,第三个是配置项,比如immidate:true。举个例子:
这里需要注意,监控基本类型和引用类型的数据之间的写法是不同的。
import {
ref,
watch
} from 'index.js';
setup () {
// 基本类型的
let num = ref(0);
watch (num, (newVal, oldVal) => {
}, {
immidate: true
})
// 引用类型的
let person = {
name: 'www',
age: 30,
job: {
a: {
b: 'aaaa'
}
}
}
// 需要以函数的形式
watch (() => person.name, (newVal, oldVal) => {
}, {
immidate: true
})
}
监控多个属性
A、监控基本类型的数据多个属性
和vue2不同的地方就是watch可以同时监控多个属性,以数组的形式传入参数,同样也会以数组的形式接收结果。
......
watch ([num1, num2], (newVal, oldVal) => {
console.log('watch -- val', newVal) // newVal -> [1, 2] 数组形式
}, {
immidate: true
});
......
B、监控基本类型的数据多个属性
......
watch([() => person.name, () => person.age], (newVal, oldVal) => {
console.log('person.name, person.age', newVal, oldVal);
})
......
还有个watchEffect。这个api不在指定具体的监控的某个属性。它内部的函数中出现了谁,就会去监控谁。举个例子
watchEffect(() => {
// 用到谁就监控谁
let num = firstname.value;
console.log('watchEffect ---')
})
2.5、hooks
这个hooks可以看作vue2中的mixins。具体做法就是新建一个js文件,把需要提取的公共代码写入进去。举个例子
// 获取当前鼠标点击的坐标
// 提取这个公共功能模块
export default function () {
let point = reactive({
x: 0,
y: 0
})
function savePoint (event) {
point.x = event.pageX;
point.y = event.pageY;
}
onMounted(() => {
window.addEventListener('click', savePoint);
})
onBeforeUnmount(() => {
window.removeEventListener('click', savePoint);
})
return point
}
// 使用的时候直接引入即可
import usePoint from 'xxxx.js'
setup () {
let point = usePoint();
return {point}
}
2.6、provide和inject
这个很vue2的用法几乎一样,只不过需要单独引入。举个例子
// 祖辈组件负责提供数据
import {
provide,
reactive
}
setup () {
let car = reactive({
name: 'bmw',
price: '40w'
})
provide('car', car)
return {
car
}
}
// 后代组件
import {
inject
} from 'vue'
setup () {
inject('car');
return {
car
}
}
至此,习惯vue2开发的直接可以快速迁移到vue3,并且可以开始做一些功能了。上边这个几个api已经可以满足基本的开发需求了。
除此之外,还有一些黑科技需要提一下。
1、customRef
自定义ref。就是自己写get,set。实现一个自定义的响应式。举个例子,实现一个延迟的响应式
import {cutomRef} from 'vue'
let key = myRef('a'); // 自定义一个ref,它是一个函数
function myRef (value) {
let timer;
return customRef((track, trigger) => {
// cutomRef内部需要写入个人实现的逻辑,所以是一个函数,参数也是一个函数
return {
get () {
track();// track 是追踪变化,有了变化及时输出
return value;
},
set (newVal) {
clearTimeout(timer);
timer = setTimeout(() => {
value = newVal;
trigger();// trigger 是触发修改
}, 500);
}
}
})
}
2、teleport组件
这是个内部组件,可以直接使用。它的目的就是把这个组件包裹起来的dom,转移到某一个dom元素下。比如,写在一个组件中的对话框,你可以把它直接以到body下。
<Teleport to="body">
<div></div>
</Teleport>
// 之后这个div的上级节点就会变成body
暂时这么多吧,自己再项目中慢慢体会一下。
最后,需要了解vite+vue3+ts+setup+pinia的,请移步至我的另外一篇文章:
vue2到vue3的极简迁移之路
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/564.html