1. v2和v3的区别
- api
- v2: options API(选项式API):优点:对于新手容易,按照固定选项实现功能缺点: 对于代码的阅读\维护\复用(逻辑)不是很友好,v2中也可以通过Mixins实现逻辑的复用
- v3: composition API(组合式API)优点: 功能代码组合在一起
- 使用
- v2: 配合vuex,对与ts的支持不是很好,不允许使用多个根节点
- v3: 也可以使用vuex,推荐配合pina,底层就使用ts重构的,对ts支持很好,多个根节点
- 性能
- v3的性能会比v2快1.2_2倍:
- 虚拟dom的创建:v2中,数据发生变化,会将模板进行重编译,生成所有的虚拟dom,v3中数据发生变化,看该虚拟dom是否参与更新,如果参与更新,创建新的虚拟dom,如果不参与更新,直接复用上一次的虚拟dom
- v3采用了静态标记,给静态节点打上标记,diff的过程只对比动态节点,忽略静态节点
- 事件函数的缓存: 事件函数每次在模板编译的时候会进行缓存
- v3的tree shaking:实际情况中,虽然依赖了某个模块,但其实只使用其中的某些功能。通过 tree-shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的,v3的打包比v2的小
- 数据劫持:AOP:切面编程
- v2:Object.defineProperty
- v3: Proxy
2. vite和webpack的区别
- vite: 工程化工具
- vite原理: 启动项目不会对项目进行完全打包,启动服务,将资源通过服务进行托管,项目加载而是通过浏览器利用esm(es module)的方式加载资源,使用到资源才会加载才会处理,这实际上是让浏览器接管了打包程序的部分工作。
- webpack 真正的打包: 先读取配置文件,根据配置文件的规则进行打包,读打包的入口文件,根据入口文件的依赖进行打包,js转低级语法:babel,三方文件:loader,html:html-webpack-plugin,css文件的抽离:mini-css-extract-plugin,启动浏览器,浏览器加载资源,直接加载不会再次处理
3. vue3 如何定义响应式数据
- ref: 将简单数据类型或复杂数据类型处理为响应式
模板中使用自动解套value,在js中使用需要通过value访问到数据
- reactive: 只能将复杂数据类型处理为响应式,直接用数据不需要value
推荐的使用方式:
- 语法层面: 简单数据类型推荐使用ref, 复杂数据类型推荐使用reactive
- 性能: 更推荐全部使用ref, ref的性能在vue3.2之后比reactive高260%
4. script setup语法
- 语法: 在script标签上定义setup属性
- 特性:
- vue3.2版本更新
- setup函数的语法糖,可以直接在script中定义数据和方法,默认可以直接在模板中使用
- 不需要export default 对象
- 使用script setup语法后,无法给组件添加name属性进行命名,解决方案,使用vite-plugin-vue-setup-extend,则可以给script属性添加name进行组件命名
5. computed计算属性
- computed: 计算属性, 就是vue提供的一个函数.所以需要通过引入vue得到
- 语法: 调用computed函数, 传递一个回调函数,在回调函数内部进行计算,将计算好的数据return出
- 特性: 具有缓存, 多次调用多次定义, 除了可以传递函数,还可以传递对象, 包含get和set函数
6. watch监视
- 概念: 监听数据变化, 也是vue提供的一个函数, 所以需要通过引入vue得到
- 语法:
- 参数1: 监视的数据
-
- 监视单个数据: 直接写数据
- 监视多个数据: 写数组,数组内放数据
- 监视reactive对象中的某一个属性: 函数返回属性
- 参数2: 处理函数, 两个参数
-
- 参数1: 新值, 如果监视的是数组,参数1还是新值,以数组的方式体现
- 参数2: 旧值, 如果监视的是数组,参数1还是新值,以数组的方式体现
- 参数3: 配置对象
-
- 深度监听: deep: true, 监视的是ref的对象需要开启深度监听,监视的是reactive定义的对象不需要开启深度监听
- 首次监听: immediate: true, 开启首次监听
7. 生命周期函数
vue3中的生命周期函数来自vue,所以需要通过vue按需引入,生命周期函数可以多次调用
- 创建阶段
- vue2: beforeCreate/created
- vue3: setup
- 挂载阶段
- vue2: beforeMount/mounted
- vue3: onBeforeMount/onMounted
- 更新阶段
- vue2: beforeUpdate/updated
- vue3: onBeforeUpdate/onUpdated
- 销毁阶段
- vue2: beforeDestory/destoryde
- vue3: onBeforeUnMounte/onUnMounted
8. 组件通信
8.1. 父传子
- 父组件通过属性绑定传递
<script setup lang='ts'>
import { ref } from 'vue'
import Child from './components/Child.vue'
const money = ref(10000000)
</script>
<template>
<h1>
这是App组件: {{ money }}
</h1>
<div>------------------------</div>
<!-- 1. 父组件通过属性绑定去传 -->
<Child :money="money" />
</template>
<style></style>
- 子组件通过defineProps接收, 子组件接收的数据在模板中可以直接使用在js中,通过defineProps的返回值使用
<script setup lang='ts'>
const props = defineProps({
money: {
type: Number,
required: true
}
})
</script>
<template>
<h2>这是子组件: {{ money }}</h2>
</template>
<style></style>
8.2. 子传父
- 子组件获取emit对象
const emit = defineEmits(['buy-car'])
- 通过emit触发自定义事件,并传递数据
const buyCar = () => {
// console.log('买车', 1000000)
// 2. 通过emit对象触发一个自定义事件, 并且
emit('buy-car', 1000000)
}
- 父组件定义自定义事件和事件函数
<script setup lang='ts'>
import { ref } from 'vue'
import Child from './components/Child.vue'
const money = ref(10000000)
// 4. 定义事件函数,内部修改money数据
const setMoney = (val) => {
money.value = money.value - val
}
</script>
<template>
<!-- 3. 定义自定义事件 -->
<Child @buy-car="setMoney" />
</template>
<style></style>
8.3. 跨组件向下传值
- 父级组件通过provide提供数据
const money = ref(100000000)
provide('money', money)
- 后代组件通过inject注入数据
import { ref, inject } from 'vue'
const money = inject('money')
8.4. 跨组件向上传值
- 父组件通过provide传递函数
- 后代组件通过inject注入函数
- 调用函数将数据通过参数的方式传给父级组件
8.5. ref获取组件
- 创建空的ref
- 给组件绑定ref属性值是空的ref的名字
- 组件和空ref的value绑定在一起
- 利用ref.value获取子组件
<script setup lang='ts'>
import { ref } from 'vue'
import ComA from './components/ComA.vue'
// 1. 定义空ref
const comARef = ref(null)
const getComA = () => {
// 3. 利用ref的value获取组件
console.log(comARef.value?.updateMoney)
}
</script>
<template>
<!-- 2. 空的ref的value绑定为组件 -->
<ComA ref="comARef" />
<button @click="getComA">获取coma组件</button>
</template>
<style></style>
- 子组件通过defineExpose向外暴漏数据
<script setup lang='ts'>
import { ref } from 'vue'
const money = ref(1000)
const updateMoney = () => {
}
defineExpose({
money,
updateMoney
})
</script>
<template>
<h2>这是comA组件</h2>
</template>
<style></style>
9. 过滤器
- v3废除了过滤器
- 想过滤数据: 定义函数
10. toRefs的使用
作用: 保证解构的数据还是响应式
原理: 将解构的数据变为ref处理
11. 路由
vue3的路由结合vue-router@4.x版本
- 创建路由实例, 通过createRouter进行创建,createRouter就是一个函数,来自于vue-router的按需引入
- 配置路由模式,通过createWebHashHistory(hash路由模式)、createWebHistory创建history路由模式
import { createRouter, createWebHashHistory as createRouterMode } from 'vue-router'
// 可以创建路由实例
// 通过参数对象进行配置
const router = createRouter({
// createWebHashHistory 创建hash模式
// createWebHistory 创建history模式
history: createRouterMode(),
// 路由规则
routes: [
{
path: '/home',
component: () => import('../views/Home/index.vue')
},
{
path: '/about/:id',
component: () => import('../views/About/index.vue')
}
]
})
export default router
- 获取路由实例, 通过useRouter, useRouter函数来自于vue-router, 调用useRouter获取到router实例
import { ref } from 'vue'
// 引入useRouter
import { useRouter } from 'vue-router'
// 创建router实例
const router = useRouter()
const goAbout = () => {
router.push('/about/1')
}
- 获取当前的路由信息, 通过useRoute, useRoute函数来自于vue-router, 调用useRoute获取到route
import { ref } from 'vue'
// 引入useRoute
import { useRoute } from 'vue-router'
// 创建route
const route = useRoute()
12. pinia
12.1. pinia相比较vuex的优势
- 比vuex对vue3的兼容会更好
- pinia对ts的支持更好
- pinia和vuex5的提案很像
- pinia的使用比vuex使用更简单方便
12.2. pinia如何使用
- main.js中进行createPinia的引入,通过createPinia创建pinia实例,并进行挂载
// 引入创建pinia实例
import { createPinia } from 'pinia'
const pinia = createPinia()
const app = createApp(App)
// 挂载pinia
app.use(pinia)
- 创建pinia模块, 在js文件中通过defineStore(来自于pinia),创建一个模块数据管理
-
- 参数1: 模块标识
- 参数2:配置对象(state,actions, getters)
- 返回值: 函数
import { defineStore } from 'pinia'
// 参数1: 模块标识
// 参数2: 配置对象
// 返回值: 函数
const cartStore = defineStore('cart', {
state: () => {
return {
total: '111.00'
}
},
actions: {},
getters: {}
})
export default cartStore
- 使用模块的数据或方法, 导入模块, 直接调用模块的属性(state,getters)或方法(actions)
- 如果想对模块的数据进行解构,通过storeToRefs处理后解构的数据变为响应式了
- 模块肯定进行统一整合
12.3. pinia有哪些属性
- state: 定义数据
- actions: 定义方法, 同步和异步都可以处理
- getters: 定义派生数据
13. v3的setup函数
- 作用
是compositionApi的入口函数,所以在setup函数中可以使用compositionAPI
- 执行时机
在beforeCreated之前,组件实例还未创建,没有this,在setup函数中无法使用this获取当前组件
- script setup
在vue3.2之后推出script setup,在script标签上添加setu属性,内部就相当于是setup函数
不需要return数据和方法,定义后即可使用
- 使用script setup后组件名字处理
安装 vite-plugin-vue-setup-extend
,在vite.config.js中进行配置使用,可以在script标签上添加name属性从而给组件添加名字,name名字如果想生效,script标签内部还需要写代码