构建完成之后的目录展示
1、创建项目
npm init vite@latest
- 输入项目名称,选择vue,需要支持TypeScript就选择vue-ts,不选ts也没关系
- 下载依赖包,使用npm run dev命令启动项目
- 项目启动完毕
2、修改Vite配置文件
- 主要是配置路径别名和配置跨域代理
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 如果这里飘红则安装下依赖。
// pnpm add @types/node -D
// npm install @types/node -D
// yarn add @types/node -D
import { resolve } from "path"
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
// 配置别名
alias: {
"@": resolve(__dirname, "src")
},
extensions: [".js", ".json", ".ts", ".vue"] // 使用路径别名时想要省略的后缀名
},
server: {
proxy: {
'/devApi': {
target: 'https://10.194.98.123', // 所要代理的目标地址
secure: false,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/devApi/, '') // 重写传过来的path路径
}
}
}
})
- 修改tsconfig.json文件,使路径别名配置生效
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
}
}
3、创建路由
- 下载依赖
npm install vue-router@4
- 在src目录下新建router.ts文件;新建pages文件夹,在文件夹下新建home.vue文件
// createWebHistory:history路由
// createWebHashHistory:hash路由
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
const routes = [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'Home',
component: () => import('@/pages/Home.vue'), // 配置路径别名后,可以使用@
},
]
const router = createRouter({
history: createWebHashHistory(),
routes,
})
export default router
- 在main.ts中注册路由
import { createApp } from 'vue'
import App from './App.vue'
// 引入路由
import router from './router'
// 创建vue实例
const app = createApp(App)
app.use(router)
app.mount('#app')
- app.ts中添加 router-view,至此路由大功告成
<template>
<router-view />
</template>
4、集成Stylus/Sass/Less
- 直接安装相关依赖包就可以使用了,这里安装sass
npm install sass -D
<style lang="scss" scoped>
</style>
5、集成element-plus
- vue3中,element-plus替代了element-ui,安装依赖
npm install element-plus --Save
- main.ts中引入
// 引入element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
- 代码里直接使用
<el-button type="primary">Primary</el-button>
6、axios封装
npm install axios --Save
- 在src文件夹下新建api文件夹,创建httpInstance.js文件
import axios from 'axios'
import { ElMessage } from 'element-plus'
const REFRESH_BY_HEADER = 'pleaseRefreshByHeader'
const REQUEST_SUCCESS = '0'
const http = axios.create({
timeout: 20000,
withCredentials: true,
headers: { 'X-Requested-With': 'XMLHttpRequest' },
})
// 相应拦截器
http.interceptors.response.use(
function (response) {
// 请求多语言的json文件
if (/.*\.json$/.test(response.config.url)) {
return response
}
// 根据响应数据判断是否登录过期
if (response.data.errorCode === REFRESH_BY_HEADER) {
let refreshUrl = response.headers['refresh-url'].split('?')[0]
refreshUrl =
refreshUrl +
'?service=' +
location.protocol +
'//' +
location.host +
location.pathname +
encodeURIComponent(location.search)
location.href = refreshUrl
return
}
// 对错误进行统一处理
if (response.data.code !== REQUEST_SUCCESS) {
if (!response.config.noMsg && response.data.msg) {
ElMessage.error(response.data.msg)
}
return Promise.reject(response)
} else if (
response.data.code === REQUEST_SUCCESS &&
response.config.successNotify &&
response.data.msg
) {
// 弹出成功提示
ElMessage.success(response.data.msg)
}
return Promise.resolve({
code: response.data.code,
msg: response.data.msg,
data: response.data.data,
})
},
function (error) {
if (error.ElMessage.indexOf('timeout') > -1) {
// 多语言需要自己在项目中配置
ElMessage.error('请求超时,请重试!')
}
return Promise.reject(error)
}
)
export default http
- 新建index.js文件
import http from './httpInstance.js'
// /devApip配合跨域代理使用
const baseUrl = process.env.NODE_ENV === 'development' ? '/devApi' : ''
export function getPlacePage(data) {
return http({
method: 'post',
url: baseUrl + '/pointatps/place/page',
data,
})
}
- 代码中使用
<script setup lang="ts">
import { onMounted } from "vue"
import { getArea } from '@/api'
onMounted(() => {
getData()
})
const getData = async () => {
const { data } = await getArea()
console.log(data)
}
</script>
- 配合跨域代理,成功获取到数据
7、安装pinia
- 使用大菠萝pinia替代vuex,尤大大也更加推荐使用pinia~~
npm install pinia --Save
- main中注册
// 引入pinia
import { createPinia } from 'pinia'
// 创建 Pinia 实例
const pinia = createPinia()
// 挂载
app.use(pinia)
- 新建store文件夹,在store文件夹下新建index.js
import { defineStore } from "pinia";
export const useMainStore = defineStore("main", {
// 类似于Vue2组件中的data,用于存储全局状态数据,但有两个要求
// 1. 必须是函数,目的是为了在服务端渲染的时候避免交叉请求导致的数据状态污染
// 2. 必须是箭头函数,这样是为了更好的 TS 类型推导
state: () => {
return {
msg: "安徽黄山期待您的到来",
count: 0
};
},
getters: {
getCount(state) {
return state.count + 100;
}
},
actions: {
changeState() {
this.msg = "安徽黄山祝您工作愉快";
this.count += 10;
}
}
});
- 基本使用
<template>
<div class="home">
<div>{{msg}}</div>
<el-button type="primary"
@click="addCount">count+1</el-button>
<div>{{count}}</div>
<!-- getter 和 Vuex中的getter一样,在获取 State值之前做一些逻辑处理,具有缓存作用 -->
<div>{{store.getCount}}</div>
</div>
</template>
<script setup lang="ts">
import { useMainStore } from '@/store/index'
// 当store中的多个参数需要被使用到的时候,为了更简洁的使用这些变量,采用结构的方式一次性获取所有的变量名
// ES传统方式解构(能获取到值,但是不具有响应性)
// Pinia解构方法:storeToRefs
import { storeToRefs } from 'pinia'
const store = useMainStore()
// 解构store中的值
const { msg, count } = storeToRefs(store)
const addCount = () => {
// 通过`store.属性名`来直接修改值
store.count++
// 通过store.方法名来调用action中的方法
store.changeState()
}
</script>
至此脚手架构建基本结束~