作者:卡吉米国际早教_763 | 来源:互联网 | 2023-09-23 23:51
作为一个刚刚入行工作不久的前端菜鸟,Vue2.x都没整熟练。但看着身边人都在学习Vue3,我也不敢怠慢,毕竟Vue3正式版已经发布两个月了,我还是耐着性子好好的阅读了一下Vue3.0的文档。没有其他大佬们上来就看源码的气势,但我还是想做个学习笔记,至少先做个API调用师吧。
为啥又得掉头发,搞学习了? 为什么要学习Vue3.0,它和Vue2.x有哪些异同之处?我带着这个问题,开始了自己的学习。这几天学完后的感受,我总结了一下,大概有如下几点吧。
首先,Vue3.0使用TypeScript写的,对TypeScript兼容更好,但是对于Vue之前的语法并没有进行颠覆性的改变,你如果使用Vue2.x的语法,各种还能写,但是建议还是不要套着Vue3.0壳,去写Vue2。
Vue3.0最大的升级就是不再限制于Options API,可以使用了Composition API,啥意思呢?以前写一个组件,需要写data、methods、watch、computed,写一个功能需要反复横跳,一会儿去data里找数据,一会儿去methods里找方法。而现在有了组合式API,你可以将data、methods等等搞在一块,单独封装调用,功能的抽离更加方便。
搞明白了this。以前写的时候不论找谁,都先搞个this.
放这里,至于后面的内容何时何地挂在到了this上,摸鱼工程师是不管的。如果是一份祖传代码,还写了一大堆的Mixin混入的话,this就彻底成为了一个黑盒,不去深究谁也不知道里面发生了,但摸鱼工程师还不怕,调就完事了。Vue3.0最重要的API,setup()
就可以很好的解决this的问题。
哪些内容最重要? 一、 setup setup作为Vue3.0组合API的统一入口函数,它的调用是在beforeUpdate
生命周期之前,所以在调用setup函数时还没有生成实例,setup
里是就没有this可以调用。 setup
里有两个参数,一个是props
,一个是ctx
,props
用来获取属性,比如父组件给子组件传值,在子组件中就用props
获取,ctx
获取方法和其他内容。在setup里定义的状态、方法都要用return返回,只有return过才能在组件里进行动态响应。 // 父组件 import { ref, defineComponent } from 'vue' import Son from '@/components/provide/Son.vue' export default defineComponent({components: { Son },setup() {const username = ref('小明')return { username }} })// 子组件 import { defineComponent } from 'vue' export default defineComponent({props: ['username'],setup(props) {console.log(props.username)} })
二、 ref、reactive和toRefs 这两个API都是用来设置初始值的,两个用法有点小差异,都需要先解构才能使用。首先说ref,ref直接包含初始值就可以,但是在调用的时候一定记得是.value
的形式,如果要在组件中动态响应,那么还要return。比如:
// 可以定义一个name imoprt {defineComponent, ref} from 'vue' export default defineComponent({setup() {const name = ref('青山')console.log(name.value) // 青山return {name}} })
而reactive包裹的是一个对象,使用它之前也需要先从vue中解构,用xx.yy
来调用,也要return出去才能使用,但是注意,reactive不能够直接导出,当有多个属性值时,可以使用toRefs
来处理,将reactive对象转换成ref类型。如果直接导出,数据是不能响应的。例如:
imoprt {defineComponent, reactive, toRefs} from 'vue' export default defineComponent({setup() {const data = reactive({state: ['青山','隐隐','绿水','悠悠'],selectState: '',selectFun: (index: number)=>{data.selectState = data.state[index];}})const refData = toRefs(data)return { ...refData }} })
三、isRef isRef是用来判断创建的数据是否为ref类型,是的话就是true,如果不是,例如reactive就是false。通过使用toRefs来转换reactive类型,可以把reactive对象中的属性转换为ref,下面的例子可以看出。
const data = reactive({count : 0})const count = ref(0)console.log(isRef(count)) // trueconsole.log(isRef(data)) // falseconsole.log(isRef(data.count)) // falseconst refData = toRefs(data)console.log(isRef(refData.count)) // true
四、生命周期 setup() :开始创建组件之前,在beforeCreate
和created
之前执行。创建的是data
和method
onBeforeMount() : 组件挂载到节点上之前执行的函数。 onMounted() : 组件挂载完成后执行的函数。(以上初始化阶段) onBeforeUpdate(): 组件更新之前执行的函数。 onUpdated(): 组件更新完成之后执行的函数。(更新阶段) onBeforeUnmount(): 组件卸载之前执行的函数。 onUnmounted(): 组件卸载完成后执行的函数。 (卸载阶段)清除计时器,定时器,清除绑定事件,window、document上的事件,清除第三方实例释放内存。 onActivated(): 被包含在
中的组件,会多出两个生命周期钩子函数。被激活时执行。 onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行。 onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数。(错误捕获) 五、computed 计算属性 计算属性的基本使用,首先创建一个只读的计算属性。Vue3.0使用计算属性也要先解构出来 import {ref, computed} from 'vue' export default {setup() {const state = ref('hello world')const split = computed(() => state.value.split(''))return { state, split }} }
计算属性的get & set方法使用。通过get方法可以获取数据,通过set方法设置。比如下面的例子,可以通过get方法return出computed,可以通过set方法对计算属性进行处理。 姓: 名: 全名: import {ref, computed} from 'vue' export default {setup() {const firstName = ref('');const lastName = ref('');const fullName = computed({get() {return firstName.value + lastName.value},set(val) {firstName.value = val.slice(0,1)lastName.value = val.slice(1)}})return { firstName, lastName, fullName }} }
六、Watch侦听 watch的使用也需要解构。 单一数据的侦听,如果是一个ref类型,第一个参数直接写数据名,第二个参数是回调。 import {watch} from 'vue' watch(state,()=>{})
单一数据的侦听,如果是一个reactive类型,第一个参数写成返回某个属性值。 watch(()=> state.number,(number, preNumber) => {console.log(number, preNumber)} )
侦听多个数据源,第一个参数用数组,两种类型都有的情况下,ref类型和reactive类型的写法同上。 watch([number, ()=> state.count],(number, preNumber) => {console.log(number, preNumber)})
清除侦听,可以给watch定义一个变量,在事件中调用即可。 const watchStop = watch([number, ()=> state.count],(number, preNumber) => {console.log(number, preNumber)} ) const removeWatch = ()=>{watchStop() }
watchEffect,传入的函数会立即执行并侦听依赖值的变化,如果依赖值变化便会执行。 import { toRefs, reactive, watchEffect } from 'vue' export default {setup () {const data = reactive({count: 1,total: 999})const refData = toRefs(data)/**1. 传入的函数立即执行2. 当watchEffect传入的函数依赖值有变化时,会再次触发watchEffect函数*/watchEffect(() => {console.log(data.count)})setTimeout(() => {data.count = data.count + 2 // 【会】触发watchEffect函数data.total = data.total + 2 // 【不会】触发watchEffect函数}, 2000)return {...refData}} }
七、Teleport 瞬移组件或者传送组件,可以将组件独立于Vue组件之外,直接挂载在body下,但仍受Vue的控制。大大的提高了组件的可复用性和封装性。 xxx
也可以直接在index.html中留下,组件里to属性绑定id // index.html
// teleport组件xxx
八、Suspense suspense的英文是“悬念”,它提供了两个template
插槽分别返回异步组件成功或者失败的结果。