Vue3的学习记录


在将v3版的变化之前我们先来回顾一下v2版本的函数式组件,它有两种创建方式:functional attribute 和 { functional : true } 选项,代码分别如下

// attribute 方式

// 选项方式

export default = {

functional:true,

props:{

},

render:function(createElement,context){

/**

context传递了一些参数:

props,slots,parent,listeners,injections

**/

}

}

v2版本中组件有两种组件类型:有状态组件和函数式组件(无状态组件),相对于有状态组件,函数式组件不需要被实例化,无状态,没有生命周期钩子,它们的渲染速度远高于有状态组件。往往通常被适用于功能单一的静态展示组件从而优化性能。除此之外,函数式组件还有返回多个根节点的能力。

在v3版本中,有状态组件和函数式组件之间的性能差异已经大大减少,在大部分场景下几乎可以忽略不计。所以函数式组件唯一的优势就在一返回多节点的能力,但这种通常运用比较少,且组件往往比较简单,具体语法糖如下:

// 函数创建

import { h } from ‘vue’

const DynamicHeading = (props, context) => {

// context是一个包含 attrs,slots,emit的对象

return h(h${props.level}, context.attrs, context.slots)

}

DynamicHeading.props = [‘level’]

export default DynamicHeading

// 单文件组件(SFC)

<component

v-bind:is=“h${$props.level}

v-bind=“$attrs”

/>

  1. 全局API调整

v3版本中新增了一个新的全局APIcreateApp,通过ES模块的方式引入。调用createApp返回一个应用实例,该应用实例暴露出来全局API,这是Vue3的新概念,主要解决了不同"app"之间能够共享资源(配置,全局组件,指令等等)。我们来对比一下v3和v2分别创建应用的改变。

// v2 创建

import Vue from ‘vue’

import App from ‘./App.vue’

Vue.config.productionTip = false

new Vue({

render: h => h(App),

}).$mount(‘#app’)

// v3 创建

import { createApp } from ‘vue’

import App from ‘./App.vue’

var app = createApp(App);

app.mount(‘#app’)

在"app"之间共享配置的一种方式是工厂模式:

import { createApp } from ‘vue’

import App1 from ‘./App1.vue’

import App2 from ‘./App2.vue’

const createMyApp = options => {

const app = createApp(options)

app.directive(‘focus’ /* … */)

return app

}

createMyApp(App1).mount(‘#foo’)

createMyApp(App2).mount(‘#bar’)

v3将可以全局改变Vue行为的API从原来的Vue构造函数上转移到了实例上了。列表如下

除此之外,还有一些全局API和内部组件都做了重构,考虑到tree-shaking,只能通过ES模块的方式导入,意味着当你的应用程序中没用到的组件和接口都不会被打包。受影响的API列表如下:

  • Vue.nextTick

  • Vue.observable (用 Vue.reactive 替换)

  • Vue.version

  • Vue.compile (仅全构建)

  • Vue.set (仅兼容构建)

  • Vue.delete (仅兼容构建)

// 错误使用

import Vue from ‘vue’

Vue.nextTick(() => {

// 一些和DOM有关的东西

})

// 正确使用

import { nextTick } from ‘vue’

nextTick(() => {

// 一些和DOM有关的东西

})

  1. 组合式API

重头戏!!!

这是v3中的新概念,vue给我们提供了一些新的api,这些新的api在一个地方使用,而这个地方就是vue给我们新提供了一个从组件初始化到销毁的过程中我们能够做一些事情的地方,我将之理解为钩子函数——Setup,在Setup里,你可以做原本你能在vue组件里面能做的所有事情,比如你在created,mountedcomputedwatch,methods 里面做的所有事情,都能在Setup里面完成,那要怎么才能做到呢,就是要通过vue提供的那些新的API。那这个东西主要解决什么事情呢?我们都知道组件的作用就是对功能的提取以及代码的复用。这使得我们的程序在灵活性和可维护性上能走的更远,但是这还不够,当一个组件内部的逻辑很复杂的时候,我们将逻辑分别散落在 created,mounted,methodscomputedwatch里面,然后整个文件代码长达好几百行。这对于没有编写这个组件的人来说,尝试去理解这些逻辑代码无疑是最头疼的事情。而Setup正是解决了这个事情,将所有的逻辑都集中起来在Setup中处理。从今以后,当你想制造一辆汽车的时候,你再也不用去全世界进口各种零件,你在Setup工厂中就能完成。让我们来见识一下Setup和那些新的API的使用以及作用(听说这种东西才被称之为干货???):

Setup

如果你听懂了我上面所说的,那我开局这么写你应该也能理解了:

// 当运行起来打印了run

Setup可以返回一个对象,你可以在组件的其他地方访问这个对象中的属性。

注意:在执行Setup的时候尚未创建组件实例,所以在Setup中没有this。不过它提供了两个接收参数——propscontext。在Setup中无法访问组件中其他的任何属性。

// 调用Demo组件

// Demo 组件

我们会发现试图并没有更新,我们发现setup返回的对象不是响应式的,响应式我们应该不陌生,在data()选项中的property都是响应式的,那是应为Vue在组件初始化的过程中就已经对data()中的property创建了依赖关系。所以当property发生变化时,视图即会自动更新,这就是响应式。那怎么让它变成响应式的呢?

ref & reactive

我们可以通过ref,reactive创建响应式状态,

我们使用ref可以创建基础数据类型和复杂数据类型的响应式状态,使用reactive只能创建复杂数据类型的响应式状态,如果使用创建数据类型不正确,控制台会给出对应的警告value cannot be made reactive: **。那refreactive的区别到底在哪里呢?

const refNum = ref(10);

const refObj = ref({

name:‘jac’,

age:20

});

const reactiveNum = reactive(10);

const reactiveObj = reactive({

name: ‘jac’,

age: 20

})

console.log(‘refNum’,refNum);

console.log(‘refObj’,refObj);

console.log(‘reactiveNum’, reactiveNum);

console.log(‘reactiveObj’, reactiveObj);

结果如下:

ref创建的是复杂数据类型的时候内部其实也是用reactive创建的。所以ref也是可以创建复杂数据类型的响应状态的,只是在setup中写法会有所不同。

setup(){

const refObj = ref({

name:‘jac’,

age:20

});

const reactiveObj = reactive({

name: ‘jac’,

age: 20

})

// ref 方式的更新

const changeRefObj = () => {

refObj.value.name=“mac”

}

// reactive 方式的更新

const changeReactiveObj = () => {

reactiveObj.name = ‘mac’

}

return {

}

}

注意:通过ref对值进行了包裹,在Setup中你需要使用变量.value的方式进行访问和设置值,从Setup中暴露出去的对象你可以直接通过this.变量访问。

小伙伴可以根据自己的编码习惯选择运用。

toRef & toRefs

有时候我们想通过解构的方式从一个复杂的响应式变量中剥离出一些变量时,我们的代码可能是这样的:

<button @click=“changeObj”>my name is {{info.name}}

这样会使我们解构出来的两个property失去响应性,这个时候我们需要使用toReftoRefs从中解构出来,toRef用于解构出单个property的响应式变量,toRefs是将源对象中所有property都创建响应式变量,在通过解构的方式创建我们对应的变量。

<button @click=“changeObj”>my name is {{info.name}}

watch & computed & 注册生命周期钩子

Setup中我们还能watch属性,创建独立的computed,还可以注册各种生命周期钩子,由于Setup执行的阶段是围绕beforeCreatecreated和进行的,所以原本在这两个生命周期中做的事情都能够放在Setup中处理。

// 输出结果如下:

我首先执行

created执行了

onMounted也执行了,结果输出如下

0

总计数:1

mounted执行了

看的出来,Setup中注册的生命周期钩子函数要比外面注册的钩子函数先执行!

provide & inject

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
created() {

console.log(‘created执行了’);

},

mounted() {

console.log(‘mounted执行了’);

},

}

// 输出结果如下:

我首先执行

created执行了

onMounted也执行了,结果输出如下

0

总计数:1

mounted执行了

看的出来,Setup中注册的生命周期钩子函数要比外面注册的钩子函数先执行!

provide & inject

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-NczDGugX-1715673924196)]

[外链图片转存中…(img-jTd2ubUB-1715673924197)]

[外链图片转存中…(img-jmXO9SrF-1715673924197)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值