文章目录
Vue3 + Vite 项目起步
1.0 Vue官网
- Vue官方文档:快速上手 | Vue.js (vuejs.org)
2.0 淘宝镜像
查看镜像:
npm config get registry
设置淘宝镜像
npm config set registry https://registry.npm.taobao.org/
1.0 创建项目并精细化配置
1.0 创建vite
-
创建vite
npm init vue@latest
-
切换该目录,然后初始化项目,然后运行
cd 目录名 npm install npm run dev
2.0 npm命令依赖冲突问题
--legacy-peer-deps
2.0 增加src子目录
1.0 apis文件夹
API接口文件夹 : 统一管理api接口
2.0 composables文件夹
组合函数文件夹 : 通用的逻辑函数
3.0 directives文件夹
全局指令文件夹 : 自定义指令
4.0 styles文件夹
全局样式文件夹 :存放样式的
5.0 utils文件夹
工具函数文件夹 :存放一些工具的,专门提供api方法
3.0 git管理项目
1. git init
2. git add
3. git commit -m "init"
2.0 配置别名路径联想提示
提升编写代码能力。 即编写代码过程中,输入"@/"就会联想出src下的子目录
1.0 如何在vscode下进行配置
“@/”:vue本来就提供了该功能,我们在vscode配置的目的是vscode能出现代码提示。
在项目的根目录下新增 jsconfig.json文件
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*":[
"src/*"
]
}
}
}
3.0 elementPlus
Vue3 项目中对应的是elementPlus , vue2项目对应的是element-ui
官方文档
官方文档:[快速开始 | Element Plus (gitee.io)](https://element-plus.org/zh-CN/)
1.0 按需导入
-
使用包管理器npm,安装包
/* save指令 :开发和生产都需要 */
npm install element-plus --save
-
需要安装这两款插件unplugin-vue-components 和 unplugin-auto-import
-
安装插件
/* -D指令 仅开发需要 */
npm install -D unplugin-vue-components unplugin-auto-import
-
在vite.config.js中,配置插件
/* 1. 导入3个,2. 在plugins新增两个 */
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()],
}),
],
})
-
在组件栏目下选择一个组件进行测试
<el-button type="primary">Primary</el-button>
2.0 elementPlus主题定制
Q1:为什么需要主题定制?
A:elementPlus默认的主题色是蓝色的,而有些时候项目需要的配色是其他颜色的,所以要修改主题颜色
3.0 主题定制方案 —— scss变量替换方案
-
安装scss
npm i sass -D
-
在styles文件夹新建element,并新建一个index.scss文件
@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, ), ) );
-
在vite.config.js设置配置,自动导入配置
/* 1. 在components新增对象 2. 新增css结点 */
plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ // 1.配置ementPlus采用sass样式配色系统 ElementPlusResolver({importStyle:"sass"}) ], }), ], css:{ preprocessorOptions:{ scss:{ // 2. 自动导入定制化样式文件进行样式覆盖 additionalData:` @use "@/styles/element/index.scss" as *; ` } } }
4.0 axios基础配置
官方文档
官方文档:起步 | Axios 中文文档 | Axios 中文网 (axios-http.cn)
1.0 axios的安装
npm install axios
2.0 axios的基础配置
- 接口基地址 : baseUrl
- 接口超时时间 : timeout
- 请求拦截器 :interceptors.request
- 响应拦截器 :interceptors.response
-
在utils下创建http.js文件,用于配置axios基础封装(全部项目都有这一步)
/* 该文件是产生axios实例的 ,默认导出不需要解构赋值的方式接收 */
import axios from 'axios' // axios基础封装 const $http = axios.create({ baseURL:"http://localhost:5173/api", timeout:5000 //五秒 }) //拦截器 // 请求拦截器 $http.interceptors.request.use(config =>{ return config },e => Promise.reject(e)) // 响应式拦截器 $http.interceptors.response.use(res => res.data, e => { return Promise.reject(e) }) // 默认导出 export default $http
2.在apis文件夹下创建 testAPI.js,用于封装请求接口具体路径等配置
/* 用export导出,导入的时候要用解构赋值的形式接收 */
import $http from '@/utils/http' export function getCategory(){ return $http({ url:'/jieyyds/selectAllMenu' }) }
3.组件中发送API请求测试
<script setup> import { getCategory } from '@/apis/testAPI.js' import { onMounted } from 'vue' onMounted(async () => { const {data} = await getCategory(); console.log(data); }); </script>
3.0 axios跨域配置
-
axios基础配置的baseURL中额外添加 ‘/api’ 路径,供代理拦截
const $http = axios.create({ baseURL:"http://localhost:5173/api", //后面额外添加api路径 timeout:5000 //五秒 })
-
在vite.config.js中添加代理配置,添加server结点
server: { proxy: { // 请求路径含有'/api'就会触发代理 '/api': { target: 'http://localhost:8080', changeOrigin: true, // 把路径中的/api更换成'' rewrite: (path) => path.replace(/^\/api/, '') // 不可以省略rewrite } } }
-
在api中添加具体路径
import $http from '@/utils/http' export function getCategory(){ return $http({ url:'/jieyyds/selectAllMenu' }) }
-
组件就能正常发送请求了
<script setup> import { getCategory } from '@/apis/testAPI.js' import { onMounted } from 'vue' onMounted(async () => { const {data} = await getCategory(); console.log(data); }); </script>
5.0 路由的基础配置
1.0 用npm安装路由
npm install vue-router
2.0 路由的基础配置
在router文件夹下的index.js中
// createRouter : 创建路由实例
// createWebHistory : 创建history模式的路由
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
//路由规则:路径 映射 组件,即path和component对应关系
routes: [
]
})
export default router
3.0 将路由插件添加到Vue中
在main.js中添加路由插件
import router from '@/router/index'
const app = createApp(App)
app.use(router)
app.mount('#app')
4.0 设置路由出口
即组件占位符,html标签的形式
<RouterView />
5.0 区分一级路由与二级路由
一级路由:如果要页面整体切换,那么这个路由就是一级路由
二级路由:如果页面是局部切换,那么该路由是二级路由
6.0 快速上手 - 一级路由与二级路由
小案例:路由切换首页和登录页
-
新建一级路由组件: 登录页Login.vue 和 首页 index.vue
-
新建二级路由组件:家页home.vue 和 分类页 category.vue
-
添加一级路由和二级路由: 路径 和 组件的对应关系
import { createRouter, createWebHistory } from 'vue-router' import Login from '@/views/Login/index.vue' import Layout from '@/views/Layout/index.vue' import Home from '@/views/Home/index.vue' import Category from '@/views/Category/index.vue' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path:'/', component:Layout, // 二级路由 children:[ { // 默认就会显示该二级路由 path:'', component:Home }, { path:'category', component:Category } ] }, { path:'/login', component:Login, }, ] }) export default router
-
添加一级路由出口 与 二级路由出口
<RouterView />
6.0 静态资源的引入
静态资源:图片资源和样式资源
- 图片资源:images文件夹放到 assets目录下
- 样式资源:common.scss文件放到styles目录下
往往样式资源是需要样式重置的,可以使用开源的normalize.css库,或者手写。比如a的默认跳转,margin和padding的默认样式
引入初始化样式文件
-
common.scss文件
// 页面的整体公共样式 //重置样式 * { box-sizing: border-box; } html { height: 100%; font-size: 14px; } body { height: 100%; color: #333; min-width: 1240px; font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif; } body, ul, h1, h3, h4, p, dl, dd { padding: 0; margin: 0; } a { text-decoration: none; color: #333; outline: none; } i { font-style: normal; } input[type='text'], input[type='search'], input[type='password'], input[type='checkbox'] { padding: 0; outline: none; border: none; -webkit-appearance: none; &::placeholder { color: #ccc; } } img { max-width: 100%; max-height: 100%; vertical-align: middle; background: #ebebeb url('@/assets/images/200.png') no-repeat center / contain; } ul { list-style: none; } #app { // background: #f5f5f5; user-select: none; } .container { width: 1240px; margin: 0 auto; position: relative; } .ellipsis { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } .ellipsis-2 { word-break: break-all; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; } .fl { float: left; } .fr { float: right; } .clearfix:after { content: '.'; display: block; visibility: hidden; height: 0; line-height: 0; clear: both; } // reset element .el-breadcrumb__inner.is-link { font-weight: 400 !important; }
2.在main.js中引入
// 1.将默认导入的css注释掉 // import './assets/main.css' // 2.更换我们的scss样式文件 import '@/styles/common.scss'
7.0 scss文件的自动导入
首先在styles目录下创建样式文件,var.scss
$xtxColor: #27ba9b;
$helpColor: #e26237;
$sucColor: #1dc779;
$warnColor: #ffb302;
$priceColor: #cf4444;
1.0 自动导入的配置
在vite.config.js中添加自动导入scss文件的配置
css: {
preprocessorOptions: {
scss: {
additionalData: `
@use "@/styles/element/index.scss" as *;
// 自动导入scss的文件
@use "@/styles/var.scss" as *;
`,
}
}
}
2.0 组件中使用样式
scss相比css来说,是可以使用变量的
/* 自动导入的好处,就是免去了我们自己手动导入 var.scss文件*/
<template>
<div class="text">text</div>
</template>
<style lang="scss">
.text {
color: $xtxColor;
}
</style>
8.0 Pinia的基础配置
官方文档
官方文档:定义 Store | Pinia (vuejs.org)
概念
pinia是Vuex的代替品,是状态管理模式,是集中状态管理工具
在vue项目中,对应的文件夹是stores
1.0 pinia安装
npm install pinia
2.0 vue使用pinia插件
在main.js中
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
3.0 pinia的使用
pinia添加action和state
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
// 类似vuex的state结点,负责存储全局数据的
const count = ref(0)
//定义getter 类似计算属性
const doubleCount = computed(() => count.value * 2)
// 类似vuex的action函数,负责修改store中的数据
// 与vuex不同的是,pinia的action可执行同步和异步
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
组件使用store
<script setup>
// 1. 导入获取实例的方法
import { useCounterStore } from "./stores/counter";
// 2. 获得counterStore实例对象
const counterStore = useCounterStore();
</script>
<template>
<button @click="counterStore.increment">{{ counterStore.count }}</button>
</template>
4.0 pinia数据的响应式解构 storeToRefs函数
如果直接解构pinia的store数据,该数据的响应式就会丢失,函数action解构就没事,所以需要使用storeToRefs函数进行响应式解构。
/* 解构赋值:提高代码开发效率 */
import { storeToRefs } from "pinia";
import { useCounterStore } from "@/stores/counter";
// 实例化store
const counterStore = useCounterStore();
// 解构变量
const { count,doubleCount } = storeToRefs(counterStore)
// 解构函数
const { increment } = counterStore
<template>
// 解构好处:无需通过counterStore.count
{{count}}:{{doubleCount}}
</template>
9.0 基础篇
1.0 消息弹框的配置
-
获取弹框实例的函数 与 引入css
import { ElMessage } from "element-plus"; import "element-plus/theme-chalk/el-message.css";
-
使用弹框
ElMessage({type:"success",message:"挂载成功"})
2.0 响应式函数ref与reactive
ref底层是reactive,他们两个底层是Proxy实现的。
一般ref是声明基本数据类型,reactive是声明对象或者数组的。
ref(1) => reactive({ value : 1 }),所以用ref声明的时候要加.value才能获取该数值。
import { reactive, ref } from "vue";
// 1. 响应式函数ref
const num = ref(0);
const obj = reactive({
"name":"gjj",
"age":18
})
const addNum = () => {
num.value++;
};
3.0 计算属性
函数形式声明,但本质是属性。
属性的值是动态的,是随逻辑变化的,那么就定义在计算属性里
import { computed } from "vue";
const arr = ref([1,2,3,4,5,6])
const filterArr = computed(()=>{
// 筛选数组,筛选后每一项都大于2
return arr.value.filter(item => item > 2)
})
4.0 watch侦听器
侦听器:侦听属性的变化,只要属性发生了变化就会执行的一种函数
import { watch } from "vue";
const obj = ref({ count:0})
// 1. watch 监听一个属性,即obj
watch(obj,(newValue,oldValue)=>{
console.log(`新的值${newValue};旧的值${oldValue}`);
},{
//立即执行监听器,一进到页面就会先触发一次
immediate:true,
// 深度监听对象里面的属性
// 深度监听deep,会造成性能损耗,一般用精度监听
deep:true
}
)
const num = ref(0);
const computedNum = computed(() => {
return num.value + 2;
});
// 2. watch 监听多个属性,即num和computedNum
watch([num,computedNum],([newNum,newcomputedNum],[oldNum,oldcomputedNum])=>{
console.log(`新的count${newNum}和新的计算属性${newcomputedNum}`);
})
// 3. watch 精度监听
// watch两个回调,一个是监听的属性,一个是处理函数
const obj1 = ref({ count:0,name:"gjj"})
watch(
// 精度监听name属性(回调函数形式)
()=>{
obj.value.name
},(newValue)=>{
console.log('数据发生了变化');
})
5.0 组合式API生命函数
没有created和beforeCreate,新增setup,全部加前缀on,即onXXX
生命函数( 钩子函数 )的好处:1. 在指定的时机会自动调用 2. 可多次执行,代码是依次执行的
import { onMounted } from 'vue'
// 两句都会被执行,onMounted一般用于发送ajax请求
onMounted(()=>{
console.log('onMounted被调用');
})
onMounted(()=>{
console.log('onMounted被调用第二次');
})