介绍
vue3官网: Vue.js - 渐进式 JavaScript 框架 | Vue.js
1.0更容易维护
支持组合式API 可以减少代码量, 并且分散式维护转为集中式维护, 更容易封装复用
友好的TS支持
vue3的源码都被TS重写, 所以对TS的支持更友好
2.0更快的速度
新的diff算法, 模版编译优化, 更高效的组件初始化, 是vue3项目的运行速度更快
3.0更小的体积
良好的TreeShaking和按需引入, 可以是vue3项目打包后的体积更小
4.0更优的响应式
使用ES7新增的Proxy API实现数据响应式, 优势是针对整个对象进行监听, 无论对象新增还是减少属性, 都不会失去响应式特点, vue2中对象的修改是监听不到的, 所以vue3的响应式方案更强大
Vite脚手架
create-vue是Vue官方的脚手架工具, 底层切换到了vite(下一代构建工具)
- 前提条件: node版本>= 16.0
- 安装执行: npm init vue @latest
- 该指令会安装并执行 create-vue
- 创建项目: npm create vue@latest
- 右侧是创建项目的可选项->_->
- 项目名称
- 可选TS (No)
- 可选JSX (No)
- 路由 (Yes)
- 仓库(Yes)
- 单元测试 (No)
- 端到端测试 (No)
- EsLint (Yes)
- 格式化工具 (No)
组件替换
目录结构
关键文件
- vite.config.js 项目配置文件
- package.json 项目包文件
- main.js 入口文件
- app.vue 根组件
- index.html 入口文件
import { createApp } from 'vue'
import App from './App.vue'
import './assets/main.scss'
// createApp(App)的作用: 创建应用实例
// vue2创建应用实例: new Vue()
// vue3创建应用实例: createApp()
// 对创建实例的方法进行封装, 保证每个实例的独立封闭性
// 在微前段或大型项目中有作用
// createRouter() createStore()
// mount('#app')的作用: 设置挂载点
// 把应用实例挂载到#app的盒子
// 简单理解: 把App根组件渲染到#app盒子中
createApp(App).mount('#app')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<!-- 单页入口, 提供app挂载点 -->
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<script setup>
// 脚本script和模版templates顺序调整
// 写结构,再写样式, 不用跨越脚本, 更合理
// 模版templates不再要求唯一根元素
// 脚本script通过添加setup标识, 支持组合式API
</script>
<template>
</template>
<style scoped>
</style>
辅助工具
vue3调试工具: VUE3 vue-devtools 调试工具下载安装_vue3 devtools下载-CSDN博客
组合式API
setup选项
Vue3提供了setup选项, 在该选项中可以书写组合式API
- setup选项的执行时机在 beforeCreate钩子之前, 自动执行
- setup选项中定义的数据和函数, 要以对象方式return之后, 才能在模版中使用
- setup选项中,获取不到this, this指向undefiend
setup语法糖
setup选项中组合式API, 还要return, 比较麻烦, 所以vue3支持 setup 语法糖, 简化组合式API的代码
写法
原理
- 语法糖代码, 还是要被编译成原始写法, 通过returen的方式, 让模版中拿到数据
- 语法糖, 自动帮我们完成了retuen操作, 更简单的编写组合式API代码
- 组件只需引入, 自动完成注册, 更方便
响应式变量
reactive()
接受对象类型的参数并返回一个响应式对象
使用
- 从vue包中导入reactice函数
- 在脚本中执行 reactice函数并传入对象类型的参数, 使用变量接收返回值
- 得到一个响应式的对象
- reactive不能处理简单类型的数据
ref()
接收简单类型或对象类型的参数并返回一个响应式对象
使用
- 从vue包中导入ref函数
- 在脚本中执行ref函数并传入初始值, 使用变量接收返回值, 得到一个响应式的对象
- ref可以处理简单类型和复杂类型的数据
- 本质: 把传入参数, 包装成为复杂类型,
- 底层: 再借助reactive函数实现数据响应式
- 在脚本中访问数据, 需要通过 .value
- 在模版中访问数据, 不需要 .value (自动简化)
对象和数据
如果使用ref创建响应式数据, 注意区分响应式对象和响应式数据
const data = ref('hello')
console.log(data) // 响应式对象
console.log(data.vue) // 响应式数据
计算属性
成功因素
组合式API下, 计算属性的写法有所改变
使用
- 导入 computed 函数
- 执行函数 在回调参数中 return 基于响应式数据做计算的值, 用变量接收结果
- 计算属性中应该保持单纯的数据计算, 不该有"副作用", 比如异步请求/修改DOM
- 尽量避免直接修改计算属性的值, 计算属性应该是只读的, 特殊情况下再配置get/set
侦听器
1.0侦听单个数据
- 导入watch函数
- 执行watch函数,传入要侦听的ref对象, 和回调函数
2.0侦听多个数据
同时侦听多个响应式数据的变化, 不管那个数据变化都触发侦听器
3.0首次侦听
在创建侦听器时立即出发回调, 响应式数据变化之后继续执行回调
4.0深度侦听
- 默认侦听器进行的是 浅层侦听
- 对于简单数据类型, 可以直接侦听
- 对于复杂数据类型, 侦听不到内部属性的变化, 只能侦听数据内存地址的变化
- 开启deep:true, 才能监听对象属性的变化
import { watch } from 'vue'
watch( ref对象, (new, old) => {
// 处理逻辑
... ...
} , {
deep: true
})
5.0精准侦听
不开启deep的前提下, 精准侦听对象某个值的变化
深度侦听可以解决侦听不到的问题, 但是会侦听整个对象的全部属性变化, 可能会出现干扰
生命周期
- 在vue3中, 之前的 beforeCreate 和 created 生命周期函数, 被 setup 函数替代
- 在vue3中, onMounted(()=>{ ... }) 等函数, 可以多次调用, 不会冲突, 而是按照编码顺序依次执行
路由
Vue3中的路由初始化跟之前有所变化, 对new VueRouter的过程进行了封装
- 创建路由实例由 createRouter 实现
- 路由模式
- history 模式使用 createWebHistory()
- hash模式使用 createWebHashHistory()
- 指定路由参数模式时, 传递的参数是路由基础路径, 默认/
- vite 中的环境变量
- vite官网 环境变量和模式 | Vite 官方中文文档
- import.meta.env 是访问 vite 中环境变量的固定方式
- import.meta.env.BASE_URL 部署应用时的基本URL, 它由base配置项决定
export default defineConfig({
plugins: [vue()],
base: '/', // 一般是/, 可以按需配置
... ...
})
- import.meta.env.MODE 访问应用运行的模式 (dev/prod)
- import.meta.env.PROD 判断应用是否运行在生产环境
- import.meta.env.DEV 判断应用是否运行在开发环境
- import.meta.env.SSR 应用是否运行在server上
路由对象
import { useRouter } from 'vue-router'
// 获取路由对象
const router = useRouter()
// 进行路由跳转
router.push(地址)
路由参数
import { useRoute } from 'vue-router'
// 路由参数对象
const route = useRoute()
// 拿到路由参数
route.params.参数
route.query.参数
自定义指令
介绍
在vue3中, 自定义指令的钩子函数有所改变
- inserted->mounted
- update->updated
<script setup>
// 在模板中启用 v-focus
const vFocus = {
mounted: (el) => el.focus()
}
</script>
<template>
<input v-focus />
</template>
其他钩子
defineOptions
使用setup语法糖后, 定义与setup平级的配置项就不方便了, defineOptions主要用来定义Options API 的选项
- 可以定义Options API 的任意选项
- props/emits/expose/slots除外, 因为已经提供了宏函数解决问题