前言
前段时间,由新东方出品直播带货品牌
东方甄选
火爆全网,其中最受大家关注的主播董宇辉,用网友的调侃来说“长着一个颗粒无收的脸,却拥有五谷丰登的灵魂”
。他在直播中推荐五常大米时说:“厨房里充满了饭香,就是人间浪漫。”
,介绍水蜜桃:“这个水蜜桃,美好的像穿越大峡谷的风,像仲夏夜的梦”
。卖牛排,告诉观众这是“Original Cutting”
。让网友赞叹不绝,大家都说这买的不是吃的,买的是知识付费
,买的是灵魂洗礼
。最重要的是,他尽然还是一个英语老师。很多人感叹,好好读书太重要了,因为知识能给人带来力量,带来高贵的灵魂。相比那些快节奏、声嘶力竭、充满商业诱导的的直播模式,简直就是降维打击
。
从笔者的角度来看,董宇辉的成功并非偶然,能够饱读诗书,一定源于自己多年不断的思考跟总结,不断的追求学习的本质才能让自己在无意之间沉淀的像个诗人,像个哲学家。这背后的付出,常人肯定无法想象。作家周岭说过
“所谓的学习,不是努力,努力,在努力。而是反馈,反馈,再反馈。光靠一味的输入,而不输出,这种学习大概率是低效率的”。
就像咱们前端技术圈一样,框架层出不穷,版本迭代快的让人无法喘息。很多小伙伴都焦虑的呐喊,学不动了。笔者认为,真正高效的学习一定是需要在输入的同时,要有很好的输出,让自己积累更多的正向反馈,就像我们平时学习某一种技术栈一样,光是一味的学习不行,还要做出高质量的实践跟输出才行!
笔者这篇文章会从vue3基础的知识点开始剖析,特别是在将
composition API
的时候,在代码示例中不会一上来就使用setup语法糖
,而是用早期的setup函数
,这样方便于初学的小伙伴们理解跟学习。文章篇幅较大,接下来,请您花个10分钟耐心的看完,或许会有不一样的收货。
声明
- 本文中下边所有的示例代码都可以直接访问这个网站点击这里查看效果需要源代码的小伙伴可以在评论区下留言,或者私信我。
- 本文章的讲解的所有实例面向对vue3的初学者,如有讲解不到位,或者有偏差的地方,欢迎大家留言指出。
vue3.0有哪些新特性
- Composition Api (最重要的新特性)
- 组件通信
- 生命周期
- 自定义Hook
- 插槽
- v-model的更改
- 更加纯粹的Tree-shaking
- 配合状态管理的Pinia
- 配合升级的vue-router 4.x
- 配合升级的打包工具vite
- 配合TS在项目中自由使用
vue3.0的优缺点
优点
- 使用
vue3
最大的优势个人认为倒不是它的Api,而是配合使用的vite
打包工具,特别是大型项目本地启动要比当前的webpack5
要快至少2倍
以上(项目中测试过) - 比起
vue 2.x
,Composition Api
的优势要明显的多,如果习惯了setup语法糖
的写法,你会发现爽的飞起,很多之前在vue 2.x
中大量重复逻辑不存在了 - 底层通过
Proxy
来实现双向绑定,性能上提升了很多 - 对
TypeScript
支持度更好,可以很愉快的在项目中使用TypeScript
缺点
- 如果还有
IE情节
的公司,那vue3
确实不太适合,因为vue3
已经抛弃了对IE11
的支持,再说了 微软人家自己都不打算维护IE
了,兄弟们,放弃IE
拥抱chrome
吧! Composition Api
的写法需要花一点点时间来适应,毕竟学习新语法还是需要成本的
如何解锁vue3.0
体验vue3.0的4中姿势
- 通过CDN
- npm
# 最新稳定版 npm install vue@next npm install -D @vue/compiler-sfc
如果你是从Vue 2.x
升级的,请注意 @vue/compiler-sfc
替换掉了 vue-template-compiler
- vue-cli
npm install -g @vue/cli vue upgrade --next
- vite
npm init vite@latest-- --template vue cd npm install npm run dev
推荐使用第4种方式,直接使用官方推荐最新的vite打包工具,直接初始化项目。
核心的composition API
setup
setup
是vue3
提出的一个非常重要的选项,也是Composition Api
最为核心的语法之一。setup
执行时机是在beforeCreate
之前执行的。setup
返回的是一个对象,对象中的所有属性都是可以在template
中使用setup
中不能使用this
setup
中注册生命周期onMounted
、watch
、computed
等,我们会在下边详细讲解
setup参数
- props
- context
setup语法糖
既然上边提到了setup
语法,那就有必要把setup
语法糖介绍一下,我们在实际的项目开发中在熟悉了setup语法的本质后,也推荐大家使用setup
语法糖来编写,这样也可以大大提升开发效率。
- 不需要像上述一样
return
,只需要在中声明一下即可
- 任何在
声明的顶层的绑定 (包括声明的变量,函数声明,以及
import
引入的内容) 都可以在模板中直接使用 - 组件在语法糖中可以自动注册,无需再通过
components
进行注册
ref、reactive
ref
跟reactive
都是vue3
中用来做数据定义使用的,如同vue2
中在data
中做数据定义一样,示例代码如下:
{{ state.count }}
{{ num }}
ref计算
ref
跟reactive
的区别在哪呢?很多人分不清楚,网上有很多文章简单的定义为ref
负责处理基本数据类型的双向绑定,reactive
负责处理对象的双向绑定。其实,这样笔者会觉得给很多初学者带来很多误导,其实ref
也可以处理对象的双向绑定,就像下边这段代码一样。
ref计算 {{ obj.count }}
watch跟watchEffect
watchEffect
- 当传入一个函数时,可以响应式的自动收集依赖,当依赖变更时重新运行该函数;
- 使用是需要配置
flush: post
,否则依赖在监听时无法被立即更新 - 也可以使用
stop
来立即停止对函数的监听
This is a root element
watch
watch
API 与选项式 APIthis.$watch
(以及相应的watch
选项) 完全等效。watch
需要侦听特定的数据源,并在单独的回调函数中执行副作用。默认情况下,它也是惰性的——即回调仅在侦听源发生变化时被调用。
与 watchEffect
相比,watch
:
- 是一个返回任意值的
getter
函数 - 是一个包装的对象,可以是
ref
对象、也可以reactive
对象 - 可以同时监听多个数据源
- 监听是需要配置
deep: true
,否则回调函数无法被触发
监听单个数据源1:{{state1.count}}
监听单个数据源2:{{state2}}
监听复杂对象数据源:{{state3.player}}
computed(计算属性)
- 接受一个
getter
函数,并根据getter
的返回值返回一个不可变的响应式ref
对象。 - 接受一个具有
get
和set
函数的对象,用来创建可写的ref
对象
computedNum值为:{{computedNum}}
computedNum2值为:{{computedNum}}
组件通信
组件通信这块跟vue2的区别不大,我们就拿常用的props跟emit来讲解一下。
props
- 父级组件向子组件传递数据
emit
- 子组件想父组件传递数据
- 需要通过
emits
选项来定义组件可触发的事件
父组件
子组件
props传递给子组件的消息:{{ msg1 }}
插槽
vue2中的使用
子组件
父组件
周岭:《认知觉醒》
vue3中的使用
vue3
插槽中提供了v-slot:name
写法,我们就拿作用域插槽来举例
子组件
我们定一个可循环的插槽content
父组件
父组件中可以有两种方式来引入子组件中的插槽,其一是通过v-slot:content="scopend"
的方式,其二是通过简写#content="{item}"
的方式
{{ item }}
生命周期
vue3的声明周期如果是使用选项性Api的话,原来的生命周期钩子可以照常使用,那如果选用vue3组合式Api的话,生命周期需要通过import引入的方式在setup中调用。下图是vue3跟vu2声明周期的区别
{{ counter }}
vue-router 4.0
vue-router 3.x跟vue-router 4.x比起来写法上的区别
vue-router 3.x
// router/index.js import Vue from 'vue' import Router from 'vue-router' import routes from './routes' Vue.use(Router) const router = new Router({ routes }) export default router // main.js import Vue from 'vue' import router from './router' // ... new Vue({ el: '#app', router, components: { App }, template: '' })
vue-router 4.x
// router/index.js import { createRouter } from 'vue-router' import routes from './routes' const router = createRouter({ history: createWebHistory(), // history模式 routes }) // main.js import { createApp } from 'vue' import router from './router' const app = createApp(App) app.use(router) app.mount('#app')
- 将
new Router()
改成createRouter()
- 将
mode: 'history'
改成history: createWebHistory()
Composition API
useRouter、useRoute
通过useRouter
进行路由跳转
关于我们
通过useRoute
来获取传递过来的id
关于我们
路由守卫
全局守卫
/router/index.js
详情页面meta中
添加登录标识needLogin
let routes = [ { path: '/detail', name: 'detail', component: () => import('@/views/detail.vue'), meta: { needLogin: true } } ]
main.js
添加守卫
import router from './router' // 全局路由守卫 router.beforeEach((to, from) => { if (to.meta.needLogin) { return { name: 'login' } } })
路由独享守卫
/router/index.js
let routes = [ { path: '/category/:id', name: 'category', component: () => import('@/views/category.vue'), beforeEnter: (to, from) => { // 如果不是正确的分类,跳转到NotFound的页面 console.log('id>>>>', to.params.id); if (!["0", "1", "2"].includes(to.params.id)) { return { name: "NotFound", // 这个是在地址栏保留输入的信息,否则地址栏会非常的丑 params: { pathMatch: to.path.split("/").slice(1) }, query: to.query, hash: to.hash, }; } } } ]
组件内部守卫
关于我们
keep-alive 和 transition 必须用在 router-view 内部
// vue-router 3// vue-router 4
style新特性
跟vue2不同的是,vue3中提供了提供了很多不同的选择器方便我们在样式编写上更加的灵活多变。
深度选择器
类似于sass
语法中的v::deep
,不过vue3
中的样式自带深度作用域
:deep 深度作用域测试
全局选择器
不用像vue2
一样写全局作用域时,需要单独开启一个style
标签,同时去掉scoped
属性;vue3
提供了一种便捷的写法,只需要使用global
属性传递你想全局修改的样式即可。
全局选择器测试module样式测试