1Vue3介绍
Vue 3是Vue.js框架的最新版本,于2020年9月正式发布。它在Vue 2的基础上进行了重大改进和增强,为开发者提供了更好的性能、开发体验和功能。主要体现在以下方面:
- 响应式系统
- Vue 3引入了基于ES6 Proxy的响应式系统,取代了Vue 2中基于Object.defineProperty的实现。这种改变使得Vue 3的响应式系统更强大和灵活,能够捕获更多类型的变更,提供更好的性能,并且支持动态添加和删除属性。
- Composition API
- Vue 3引入了组合式API(Composition API),作为选项式API(Options API)的补充。组合式API允许开发人员以更模块化、更函数式的方式来组织组件逻辑,提高了代码的可维护性和复用性。它通过使用函数来组织代码,而不仅仅依靠选项,从而提供了更灵活、组合性更强的组件开发方式。
- 性能优化
- Vue 3采用了虚拟DOM算法的改进,通过静态提升(Static Nodes Hoisting)和基于模块的编译优化,提供了更好的性能。它具有更高的渲染速度、更小的包大小,以及更好的Tree-shaking支持,使应用程序更高效。
- Teleport组件
- Vue 3引入了Teleport组件,它使得在DOM树中的任何位置渲染组件变得更容易。Teleport组件在处理跨组件层级的弹出窗口、对话框和模态框等场景时非常有用。
- TypeScript支持
- Vue 3更好地集成了TypeScript,并提供了更准确的类型推断和类型检查。这使得在Vue应用程序中使用TypeScript变得更加流畅和安全。
- 全局API重构
- Vue 3对全局API进行了重构,以提高可用性和一致性。例如,全局的Vue.observable()方法现在更名为reactive(),全局的Vue.set()方法更名为app.$set()。
- 其他新特性
- Vue 3还支持组件的多个根节点,这意味着可以在一个组件内返回多个顶级元素,而不必包裹它们在一个额外的容器内。
- 引入了Suspense组件,用于处理异步数据加载和代码拆分,可以在等待异步数据时显示占位符或加载指示器,以提供更好的用户体验。
2 vue3 项目创建
3 vue3 的项目结构
4 语法糖写法


5 reactive和ref函数
举例
bash
<script setup>
import { reactive } from 'vue'
const state = reactive({
count: 0
})
</script>
<template>
<button @click="state.count++">{{state.count}}</button>
</template>
<style scoped lang='less'>
</style>

举例

6 计算属性
和 Vue2 不同,Vue2 中是选项式API,Vue3 中是组合式API。


7 watch

举例



8 深度监听


9 vue3生命周期



10 组件间通信
10.1父传子

10.2 子传父

11 模板引用

举例

12 defineExpose
13 provide和inject



14 Pinia
之前学了父子组件之间传递数据,通过 属性
及回调函数
的形式来传递。但是如果涉及到多级组件嵌套,各个组件之间传递数据会非常麻烦。尤其是遇到没有父子关系的组件,在其间传递数据会更麻烦。
Pinia 就是为了保存组件之间的共享数据,如果组件之间有要共享的数据,可以把数据保存到 Pinia 中,Pinia 就是提供一个全局的共享数据存储区域,相当于一个数据仓库,各个组件都可以从中读取和修改数据。
在 Vue2 中我们使用 Vuex 做状态管理,在 Vue3 中使用 Pinia。
14.1 安装Pinia
bash
# npm方式安装
npm install pinia
# yarn方式安装
yarn add pinia
14.2挂载数据存储对象
在项目的 main.ts
中引入 pinia
并挂载到Vue实例上。
bash
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
// 1.引入pinia
import { createPinia } from 'pinia'
const app = createApp(App)
// 2.创建pinia
const pinia = createPinia()
// 3. 安装pinia
app.use(pinia)
// 安装路由
app.use(router)
app.mount('#app')
举例


14.3 使用示例

可看官方文档
14.4 getters

14.5 action

14.6 storeToRefs
就是pinia数据使用时直接进行解构赋值,那么会丢失响应性,就需要用到storeToRefs来辅助解构,保持数据的响应性。方法则不需要。

15 src目录

16 别名路径联想设置

17 elementPlus
官网如下:快速开始 | Element Plus (element-plus.org)
安装
bash
# 选择一个你喜欢的包管理器
# NPM
npm install element-plus --save
# Yarn
yarn add element-plus
# pnpm
pnpm install element-plus
安装插件
bash
npm install -D unplugin-vue-components unplugin-auto-import
添加配置:
bash
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
17.1 自定义主题

安装
基于vite的项目默认不支持css预处理器,需要开发者单独安装
bash
npm i sass -D
准备定制化的样式文件
bash
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
// 主色
'base': #27ba9b,
),
'success': (
// 成功色
'base': #1dc779,
),
'warning': (
// 警告色
'base': #ffb302,
),
'danger': (
// 危险色
'base': #e26237,
),
'error': (
// 错误色
'base': #cf4444,
),
)
)

自动导入配置
这里自动导入需要深入到elementPlus的组件中,按照官方的配置文档来
自动导入定制化样式文件进行样式覆盖
按需定制主题配置 (需要安装 unplugin-element-plus)
bash
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// 导入对应包
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver({importStyle: 'sass'})],
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
css: {
preprocessorOptions: {
scss: {
// 自动导入定制化样式文件进行样式覆盖
additionalData: `
@use "@/styles/element/index.scss" as *;
`,
}
}
}
})

18 axios基础封装

bash
import axios from 'axios'
// 创建一个新的axios实例
const request = axios.create({
baseURL: 'http://smart-shop.itheima.net/index.php?s=/api',
timeout: 5000
})
// 添加请求拦截器
request.interceptors.request.use(function (config) {
// 在发送请求之前做些什么,
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
// 添加响应拦截器
request.interceptors.response.use(
function (response) {
// 对响应数据做点什么
const res = response.data
if (res.status !== 200) {
return Promise.reject(res.message)
}
return res
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error)
})
export default request
19 router配置
bash
import { createRouter, createWebHistory } from 'vue-router'
import Login from '@/views/login/index.vue'
import Home from '@/views/layout/index.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [{
path: '/',
component: Home,
},
{
path: '/login',
component: Login
},
]
})
export default router
配置路由出口
