一.前奏
vue2.0必须有 根元素,vue3.0可以为代码片段 Fragment
1.vite基本使用
1.1是什么
-
是一个更加轻量级vue脚手架工具
-
相对于vue-cli插件非常少
-
单纯学习使用 vue-cli为主
1.2.使用
-
创建项目 npm init vite-app 项目名称 或 npm create vite-app
-
安装依赖 npm 或 yarn
-
启动项目 npm run dev 或 yarn dev
2.从头创建一个vue3项目
2.1 main.js
主要职责:
-
创建一个vue应用(理解成之前的根实例)
-
导入createApp函数从vue中
// vue2 需要
-
创建一个根组件App.vue 导入至main
-
使用createApp创建应用实例
-
应用实例挂载到#app容器中
// 以前挂载到根组件上,eg: Vue.prototype.$request = request //现在 扩展功能将来都是在#app上进行
二.生命周期
-
vue3 不建议使用 vue2的生命周期钩子
1.回顾vue2.x生命周期钩子函数(八个钩子)
-
beforeCreate
-
created
-
beforeMount
-
mounted
-
beforeUpdate
-
updated
-
beforeDestroy
-
destroyed
2.认识vue3.0 生命周期钩子函数(七个函数)
-
写在setup函数内部
-
记得导入
import {onBeforeMount} from 'vue'
-
setup 创建实例前
-
DOM渲染前钩子
-
onBeforeMount 挂毂DOM前
-
-
DOM渲染后钩子
-
onMounted 挂载DOM后
-
onBeforeUpdate 更新组件前
-
onUpdated 更新组件后
-
onBeforeUnmount 卸载销毁前
-
onUnmounted 卸载销毁后
-
-
在vue3中我们可以定义多个相同的构造函数,实现不同的逻辑
三.API
选项API和组合API
-
vue2为选项API,data写在data中,method写在methods中
-
vue3改为组合API
组合API
1.setup函数
-
setup 是一个新的组件选项,作为组件中使用组合API的起点
-
从组件生命周期来看,它的执行在组件实例创建之前vue2.x的beforecreate 执行(组件实例创建前)
-
这就邀味着在 setup函效中 this还不是组件实例,不能使用this,thts 此时是 undefined
-
模版中需要使用的数据和函数,需要在setup 返回
export default { name: 'App', //组合API的起点,将来的组合API的代码,基本上在这聊 setup() { const obj = { name:'ls', age: 18 } return { obj } //必须在return中返回,不然因为在组件实例创建前执行,msg未定义 } }
定义响应式数据
1.reactive函数
-
只能用来定义对象(当你明确知道你需要的是一个响应式数据对象)
-
定义响应式数据
-
可以定义一个复杂数据类型,成为响应式数据
-
// 不定义reactive,无法实时更改DOM的数据(v-model)
export default { name: 'App', //组合API的起点,将来的组合API的代码,基本上在这聊 setup() { const obj = reactive({ name:'ls', age: 18 }) const updateName = ()=>{ obj.name = 'zs' } return { obj } } }
-
通常用来定义响应式对象
2.ref函数
2.1 toRef函数
-
定义响应式数据
-
toRef是函数,转换响应式对象中某个属性为单独响应式数据,并且值是关联的
-
-
原因:::从响应式数据对象中结构处的属性数据,不再是响应式数据
export default { name: 'App', //组合API的起点,将来的组合API的代码,基本上在这聊 setup() { const obj = reactive({ name:'ls', age: 18 }) const name = toRef(obj,'name') const updateName = ()=>{ name.value = 'zs' //若上面为const name,修改时修改name值value即可,若为let name,可直接修改name值 } return { name,uodateName } } }
***解构
export default{ name:'App', setup(){ const obj = reactive({ name:'ls', age:10 }) const {name,age} = obj //并不是响应式 const obj2 = {...obj} //并不是响应式 return } }
-
以上方式导致数据就不是响应式数据了
2.2 toRefs函数
-
定义响应式数据
-
toRefs是函数,转换响应式对象中所有属性为单独响应式数据,对象成为普通对象
-
export default{ name:'App', setup(){ const obj = reactive({ name:'ls', age:10 }) const obj2 = toRefs(obj) return {...obj2} } }
2.3 ***ref函数
-
一般用于简单类型数据定义,也可定义对象,未知时可以用ref,因为reactive只能定义对象
-
定义响应式数据
-
ref函数 常用于简单数据类型
-
再修改值,获取值的时候需要.value
-
当对未来定义的响应式数据类型未知时可以这样定义
-
const data = ref(null)
-
-
export default{ name:'App', setup(){ //1.name数据 const name = ref('ls') const updateName = ()=>{ name.value = 'zs' } //2.age数据 const age = ref(10) return {name,age,updateName} } }
2.4 ref属性(绑定DOM或组件)
-
获取DOM或组件实例可以使用ref属性,写法和vue2.0需要区分开
2.4.1 vue2写法
-
通过ref属性绑定该元素
-
通过this.$refs.box获取元素
2.4.2 vue3写法
<div ref="box"> //js setup(){ //先定义一个空的响应式数据ref定义的 //setup中返回该数据,想获取哪个dom元素,再该元素上使用ref属性绑定过该数据即可 const box = ref(null) console.log(box) //若想打印元素,必须在onMounted后打印,否则DOM还没加载出,无法获得元素 onMounted(()=>{ console.log(dom.value) }) return {box} }
***数组写法,懒得学
3.cumputed函数
-
定义计算属性
-
计算属性不能修改
-
-
什么时候用到计算属性?
-
当你需要依赖现有的响应式数据,根据一定逻辑得到一个新的数据
setup(){ const age = ref(18) const newAge = computed(()=>{ return age.value+2 }) return {age,newAge} }
-
高级用法(若想v-model可修改计算属性值)
<input v-model="newAge"> const newAge = computed({ get(){ return age.value+2 } set(value) { age.value = value-2 } })
-
计算属性两种用法:
-
给computed传入函数,返回值就是计算属性的值
-
给computed传入对象,get获取计算属性的值,set监听计算属性改变
-
4.watch函数()
setup(){ const count = ref(0) const add = ()=>{ count.value++ } watch(count,(newVal,oldVal)=>{ console.log(newVal,oldVal) }) return {count,add} }
四.父子通讯
1.父传子
-
父组件
<Son :money="money" /> setup(){ const money = ref(100) }
-
子组件
<div> {{money}} </div> export default{ name:'Son', props:{ money:{ type:Number, default:0 } }, setup(props){ //获取父组件数据money console.log(props.money) } }
2.子传父
-
子组件,定义按钮方法,改值
//setup(props,context){ setup(props,{emit})//setup函数中常用 1. props父组件数据 2. emit触发自定义事件的函数 const changeMoney=()=>{ emit('change-money',50) } return {changeMoney} }
-
父组件
<Son @change-money="updateMoney" /> setup(){ const updateMoney = (newMoney)=>{ money.value = newMoney } }
3.扩展
扩展不学
4.依赖注入(后代通讯)
用的少不学
五.从头开始搭建一个项目
使用pnpm
//安装pnpm npm install pnpm //创建项目 pnpm create vue //运行 pnpm dev //打包 pnpm build
1.Pinia
1.1 是什么
-
Pinia 是 Vue 的最新状态管理工具,是Vuex的替代品
-
提供更加简单的API(去掉了 mutation )
-
提供符合,组合式风格的API(和 Vue3 新语法统一)
-
去掉了 modules 的概念,每一个 store 都是一个独立的模块
-
配合 TypeScript 更加友好,提供可靠的类型推断
1.2 手动配置
1.2.1 安装
yarn add pinia npm install pinia
-
注意!!
用 cli 生成的 vue3 项目,如果自己安装 pinia 的话会安装最新版本,即
2.1.x
,pinia默认安装的是vue 2.6版本,已经不支持 vue3.3 以下使用,在进行安装时报错-
解决办法:降低vue版本
npm install vue@3.3.0 --force
-
重新执行安装命令
npm install pinia-plugin-persistedstate
-
1.2.2 配置
import { createApp }from 'vue' import { createPinia }from 'pinia' import App from './App.vue' const pinia = createPinia() const app = createApp(App) app.use(pinia) app.mount("#app')
import { defineStore } from 'pinia' export const useAlertsStore = defineStore('alerts', { // 其他配置... })
1.2.3 state
-
state
-
action
-
getters
2.ElementPlus
2.1 安装
# 选择一个你喜欢的包管理器 # NPM $ npm install element-plus --save # Yarn $ yarn add element-plus # pnpm $ pnpm install element-plus
2.2 记得在main.ts中引入
import './assets/main.css' import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import router from './router' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' const app = createApp(App) app.use(createPinia()) app.use(router) app.use(ElementPlus) app.mount('#app')
2.3 ElNotification弹出框问题
按需导入若没有样式,直接在main.ts添加css样式
import "element-plus/theme-chalk/el-notification.css";
2.4 图标
2.4.1 按需引入
pnpm install unplugin-icons -D
pnpm install unplugin-auto-import(上面有导入,这里可以省略)
vite.config.ts
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' //icon相关 import Icons from 'unplugin-icons/vite' import IconsResolver from 'unplugin-icons/resolver' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ // 自动注册图标组件 IconsResolver({ // 修改Icon组件前缀,不设置则默认为i,禁用则设置为false prefix: 'icon', // 指定collection,即指定为elementplus图标集ep enabledCollections: ['ep'] }), // 这个是组件自动导入 ElementPlusResolver() ] }), // Icons图标自动下载 Icons({ autoInstall: true }) ], // unplugin-icons 和 unplugin-auto-import resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } } }) // vite.config.ts
3.axios
3.1 安装
pnpm install axios
安装类型声明: 对于 TypeScript 项目,你还需要安装 axios
的类型声明文件。这通常通过 @types/axios
包来完成。你可以通过以下命令安装它:
npm install @types/axios --save-dev
3.2 引入
3.2.1 按需引入
npm install -D unplugin-vue-components unplugin-auto-import
// 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()], }), ], })
3.3 配置
3.4 解决中文乱码
qs需要给axios配置请求头
拦截器中
config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
4.ts报错
4.1 路由
ts文件无法引入vue文件
/// <reference types="vite/client" /> declare module '*.vue' { import { ComponentOptions } from 'vue' const componentOptions: ComponentOptions export default componentOptions }
创建一个.d.ts结尾的文件,错误解决
4.2 文件配置
-
An import path can only end with a .ts extension when allowImportingTsExtensions is enabled
@/stores/index //会报错
-
原因:配置错误,这个错误表明 TypeScript 编译器期望在导入路径的末尾看到
.ts
扩展名 -
解决方案: 设置moduleResolution为node
-
在tsconfig-app.json中配置
{
"compilerOptions": { "moduleResolution": "node", // ... 其他编译选项
}
-