目录
基础回顾
创建项目
npm create vue@latest
来到项目目录后安装前端依赖
npm i
启动项目
npm run dev
启动成功
vue2选项式api
vue3是向下兼容的,所以可以兼容vue2的写法,先来看下vue2的选项式api
新建person组件
在根组件中引用
启动查看
vue3组合式api
setup
使用data可以拿取到setup的数据,而setup中削弱了this的定义,setup不能通过this拿取data的数据
setup通过this拿取data中的数据时,直接undefined,获取失败,并且在setup中定义的数据,前面进行点击年龄时,关羽的年龄也没有变化,setup中定义的数据并不是双向绑定式的
setup语法糖
前面可以看到在使用setup时,每个变量或方法最后都需要进行return,这样当变量或者函数方法太多时进行return不太方便或者有的时候忘记把某个变量进行return时就会出现一定的问题
此时可以采用setup语法糖进行书写
可以看到使用setup语言糖时,只需要在脚本标签处进行标记setup,内部直接书写变量和函数进行,会自动进行return
组件名优化
此时根据vue开发工具查看此时的组件名字
可以看到组件名字还是原先注册的组件名,注意使用setup语法糖无法进行组件名的暴露注册,所以还需要原先的script标签进行组件名的注册暴露
注意组件名的命名场景一般都是文件名,但是有可能出现在有些项目目录会创建不同的组件名目录,但是各个目录下的文件都是index.vue这种场景,这种场景下就无法使用文件名当做组件名,因为文件名都是index,不可能所有组件名也都是index了
当然也可以使用插件来进行优化处理,使得组件名也可以直接标记在script标签中
安装所需插件
npm i vite-plugin-vue-setup-extend -D
配置插件
然后就可以直接在script中直接标记组件名字进行暴露,将之前script标签注释掉
重启查看
可以看到组件名已经是script标签中标记的组件名了
响应式数据
之前的setup数据中在点击年龄按钮时发现点了后年龄页面也没有任何变化,说明setup里定义的变量还并不是响应式数据
在vue3定义响应式数据就需要用到ref或者reactive
ref
基本数据类型
查看三个变量的打印
可以看到前两个变量被ref包裹后打印出的是RefImpl对象类型的数据
此时已经是响应式的数据,此时再点击年龄的改变观察页面的变化
对象数据类型
ref也可以定义对象数据类型
注意ref在定义响应式对象数据类型时其实是调用了reactive来进行对象类型的定义的
ref自动填充.value
在使用ref时有的时候不想每次或忘记写.value,可以使用插件来进行优化
vscode中安装vue-official插件,并在设置中进行配置.value自动填充
查看效果
reactive
reactive可以定义对象类型的响应式数据
查看页面效果
注意reactive不可以定义基本类型的响应式数据
ref对比reactive踩坑
reactive重新分配对象,失去响应式
我们看下面的例子:
这是我们正常使用reactive定义的响应式对象数据
测试时其也是响应式
此时再调整数据对象给per
测试
或者调整为reactive包裹
再次尝试
还是不行
所以reactive在重新分配对象时,会失去响应式,此时可以使用Object.assign方法来进行分配
再次尝试
使用ref重新分配对象时还是响应式的
toRef和toRefs
创建一个ref对象 其value值指向另一个对象中的某个属性值
语法: const 变量名 = toRef(数据对象,'对象属性')
应用场景: 要将响应式对象中的某个属性单独提供给外部使用时
toRefs和toRef功能一致 但可以批量创建多个ref对象 语法: toRefs(数据对象)
下面以toRefs为例进行演示,两个区别一个是复数转换,一个是单数转换
观察调整结果
没有变化,然后使用toRefs进行转换
注意下面的年龄调整已不再是使用per这个对象进行调整,而是直接使用的gage进行调整数值
计算属性computed
下面来看下vue3的计算属性的书写
来看段示例,使用原先的双向绑定进行文本的输入和调整时,进行拼接文本
可以正常拼接,此时如果输入的是英文,并且想让其英文字母进行一系列字符串的转换或则计算,比如英文字母全部转大写或者小写,或者进行字符串截取
当然我们可以进行方法的封装或者直接在绑定数据时就进行字符串的转换调整,可是这样做会比较麻烦,并且后续还有需要到该计算方法时就要重新去书写
vue3的计算属性可以很优雅的实现
查看效果
输入的姓名字母转大写,字的字母转小写
还可以进行计算属性的写数据(此种情况不太多)
查看修改计算属性效果
watch监听
监听ref定义的基本数据
查看监视效果
打印下这个监视看下是什么
可以看到watch调用后返回的是一个停止监视的方法,也就是可以通过调用这个方法手动进行停止监视,比如说当年龄到20岁的时候停止监视
查看效果
可以看到当年龄大于20后已经停止了监视,成功实现了手动停止监视
监听ref定义的对象类型数据
查看数据变化
可以看到当我们调整整个对象时,watch监听到了数据的变化,但是当我们只调整对象的某个属性比如age时,watch并没有监听到数据的变化,这是因为watch默认就监听的是对象的地址值,如果想监听对象内部属性的变化,需要进行开启深度监听
查看效果
可以看到此时开启深度监听后无论是是调整整个对象还是对象的某个属性,watch都可以监听到数据的变化了
现在的监听都是在数据会发生变化时才会进行监听
有时可能会遇到当页面刚进行创建时就进行数据的监听,可以通过immediate进行配置
刷新页面不要更改任何数据查看是否监听成功
可以看到此时没有更改任何数据,在刷新页面时就已经触发了数据的监听
监听reactive定义的对象数据类型
reactivedi定义的对象数据类型默认开启隐式地开启深度监听
查看数据效果
reactive定义的对象类型数据,没有开启deep,无论是修改对象属性还是对象本身都监听到了数据的变化
监听ref或reactive定义的对象类型数据的某一个属性
若该属性值不是对象类型时,要写成函数的形式
查看监听效果
若该属性值依然是对象类型,可以直接写,也可以写成函数,建议写成函数,写成函数时且加上deep,下面查看两者的区别
直接写
可以看到直接写的方式在修改对象类型的属性时只触发了一次单个对象属性的监听,再更改对象属性时只检测到了整个对象的变化,没有再监听到单个属性的变化了
函数式写
可以看到效果,使用函数式书写并开启deep时可以监听到对象属性的多次变化和对象的变化
监视多个数据
watch还可以进行监听前面众多数据组合成的数组
watchEffect监听
watch和watchEffect有一个形象的比喻就是:
watch:学校里教导主任对某个班级班主任说:你们班孙悟空和贝吉塔一旦打架就立马告诉我
watchEffect:学校里教导主任对某个班级班主任说:你们班只要有学生一旦打架就立马告诉我
查看效果
props
vue3在进行父子组件嵌套时可以使用props进行父子组件通信
新建Animal.vue文件作为父组件,Dog.vue为子组件
查看效果
其中子组件的defineProps引入可以不写
hooks
hooks是vue3的组合式api的精髓
下面定义下自定义hooks来看下效果
思路:
(1) 小狗hook:定义小狗图片请求,拿取到小狗图片后进行图片渲染
(2) 小狗sumhook:计数小狗图片
两个hook进行单独定义解耦
定义后小狗hook拉取一次图片调用一次小狗sumhook
这里是网上找的接口进行测试,每次发送请求都会返回一个小狗图片,可以自己尝试下
随机获取小狗图片接口
查看效果
这里由子组件Dog进行引用调用dogHuook获取图片,然后dogHook调用sumHook计数小狗数量,三层调用
还可以进行调整,两个hook都由子组件来调用
注意这里使用监听时不要直接监听小狗容器本身的变化,小狗本身容器变化时底层指向的地址没有变化,所以监听这里会监听不到dogList的变化,这里直接监听其长度的变化
其他地方不动,查看效果
路由
简单使用
关于路由详细使用可以查看博主之前的vue博客,本篇主要回顾其代码用法
直接上代码
新建三个视图组件
新建路由文件进行书写路由
主启动文件进行挂载路由
启动查看效果
路由传参
query传参
路由在嵌套组件时,可以使用query进行传参
新建detail组件进行子路由嵌套
启动查看效果,并查看useRoute打印的东西
对象写法:
效果都是一样的
params传参
params传参时需要事先在路由处进行参数占位
传参地址占位
查看效果
第二种写法:
路由props配置传参
在路由中定义props传参可以比前面两个写法优雅的进行传参
props处理params参数
查看效果
props配置query传参
路由处调整
查看效果
编程式路由导航
编程式路由导航可以使用push和replace,两者区别在于push是有历史记录的,可以点击浏览器左上角进行回退,replace没有历史记录,无法回退
查看效果
可以看到雷杰多奥特曼是按照编程式导航进行传参的
路由重定向
Pinia集中式状态管理
使用pinia可以非常方便地进行状态数据的管理,共享组件间的数据
具体介绍可以查看官网文档
安装pinia
安装pinia
使用pinia
修改和存储数据
准备两个组件,一个进行计数加减法,一个进行获取文本数据
计数组件
获取文本组件
根组件中进行引用组件
启动查看效果
可以看到此时两个组件的数据各自是独立的,并没有进行共享
使用pinia进行数据共享,并且调整下需求,下面的土味情话的条数就是上面的sum数,土味情话条数增加时sum也跟着增加,但是sum本身的加减法方法不变,使用pinia进行数据共享实现
定义情话store
定义计数store
这里定义了初始值10,但等下初始化时将此初始值初始化为情话容器的长度
注意此处的sum条数显示土味情话条数时,再进行加减法sum的值就和情话容器的长度不对应了,这里主要只做pinia的数据共享功能进行演示
查看效果
可以看到效果已经实现,同时查看下各自store的打印结果
各自store对象的key值就是在store文件中进行定义的返回值,可以直接取
同时vue开发者工具中也可以看到pinia的数据
而pinia进行修改数据时提供了三种方法,上面的就是第一种修改数据方法
第二种方法
第三种方法:
查看效果
可以看到三种方法中最简单的就是直接使用store进行修改就行,也推荐使用第一种进行修改
storeToRefs
在使用store时每次都需要进行拼接store,可以进行解构后使用
注意解构时会失去响应式特性,使用toRefs进行响应式解构
查看下打印结果
可以看到toRefs进行解构时基本上把属性方法全部解构出来了
pinia也提供了相应的解构方法,使得我们只需要解构之前store定义好的属性,按需进行解构
可以看到pinia提供的storeToRefs是按照store定义的存储数据的属性进行按需解构的,节省了一部分资源和内存
getters
pinia中也提供了类似于computed的方法,使得我们可以定义一系列方法,监控数据的调整情况
查看效果:
消息订阅与发布
pinia为每个在store中存储的数据都提供了消息的订阅与发布,在消息内容有变化时可以立即进行监控 类似于watch
store的组合式写法
注意观察两者区别
组件通信
props
适用 父子互传
查看效果
自定义事件
适用 子传父
官网注意事项
查看效果
mitt
类似于$bus(全局事件总线)和pubsub(消息订阅与发布)
这三者基本通信原理都是需要提前绑好(提前订阅)事件
安装mitt
新建emmiter工具文件
新建两个子组件,进行模拟任意组件通信
查看效果
v-model
适合 父子互传
动态value值配合input事件
举例:
查看效果
在页面中修改数据,vue开发者工具中setup里的属性值也会变,修改vue开发者工具中setup的值时页面数据也会进行同步
$attrs
适合 祖传孙
当祖组件给父组件进行prop传参时,父组件如果没有适应defineProps进行接收,那么祖组件传的prop参数就放在attrs中表示未接收参数,然后父组件不接收直接将attrs中的参数和方法进行传递到子组件中
查看效果
$refs、$parent
查看效果
provide、inject
适用 祖孙互传
查看效果
pinia
集中式状态管理进行组件通信,可以查看前面写的案例
slot
具名插槽
为每个插槽占位起个别名,需要占位的元素进行插槽名字的书写从而确定要占位的具体位置
作用域插槽
查看效果
各通信方式总结
代码
学习代码已上传码云,需要的可以自取