一个项目初始化要做什么事情?有哪些基础的东西需要处理的?
初始化vue、vuex、router管理、权限配置这些?
1. 项目选型
- 移动端:h5、小程序等等
- pc端
2. git init 初始化
- git init
- 看情况是否要创建开发分支
- git checkout -b 新分支名称 (创建分支的同时,切换到该分支上)
3. 配置vuex 或者 pinia
vuex:
- 新建文件夹store,文件夹下新建index.js文件
- index.js中完成配置:还没有配置数据和事件
js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 用来存储数据
const state = {
}
// 响应组件中的事件
const actions = {
}
// 操作数据
const mutations = {
}
// 用来将state数据进行加工
const getters = {
}
// 新建并暴露store
export default new Vuex.Store({
state,
actions,
mutations,
getters
})
- main.js中引入
js
import Vue from 'vue'
import App from './App.vue'
import store from './store/index';
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store
}).$mount('#app')
- 然后就可以使用
- $store.state.person
- $store.getters.getAllPersonAge
- this.$store.dispatch("addPerson", this.newPerson)
- this.$store.commit("deletePerson", id)
- 四个map写法
js
computed: {
...mapState(["person"]),
...mapGetters(["getAllPersonAge"]),
},
methods: {
...mapActions({
addPerson1: "addPerson", //第一个为本地方法名,第二个参数为actions中的方法名
}),
...mapMutations(["deletePerson"]),//当本地和index.js中的方法名一致时,可以简化成数组写法
},
pinia:
- mian.js中配置
js
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
- 新建文件夹store
js
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
// other options...
})
- 配置 pinia
js
// 定义state
state: () => {
return {
count: 0
}
}
// 定义 getters 是store的计算属性,用来派生出一些状态。它们会接收state作为第一个参数:
getters: {
doubleCount: (state) => state.count * 2
}
// 定义actions 用来执行状态更改的函数,可以是同步的,也可以是异步的:
actions: {
increment() {
this.count++
},
async fetchData() {
const data = await fetchDataFromAPI()
this.someData = data
}
}
- 在使用的地方引入 pinia
js
import { useCounterStore } from '@/stores/counter'
// 使用state
const counterStore = useCounterStore()
console.log(counterStore.count) // 访问count状态
// 使用getters
console.log(counterStore.doubleCount) // 使用doubleCount getter
// 使用actions
counterStore.increment() // 调用increment action
tips: 想要持久化状态,需要一个插件,如pinia-plugin-persist,这样你的store的状态可以在页面刷新后保持不变。
4. 配置axios
- npm install axios;
- 创建文件 api
- 导入配置文件
js
// main.js
import './api/axios-config'
- 编写配置文件
js
// axios-config.js
import axios from 'axios'
import store from '../store'
//单独引入element的Message组件,以使用
import { Message } from 'element-ui'
//配置基础url、超时时间、post请求头
axios.defaults.baseURL = 'http://xxx.xx.xx.xxx:xxxx';
axios.defaults.timeout = 5000;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
//------------------请求拦截-------------------//
//------------在发送请求之前做些什么------------//
axios.interceptors.request.use(config => {
//例:若存在token则带token
const token = store.state.token;
if (token) {
config.headers.Authorization = token
}
return config;
}, err => {
console.log("请求拦截=>", err);
return err;
})
//------------------响应拦截-------------------//
//-------------对响应数据做点什么-------------//
axios.interceptors.response.use(res => {
console.log("响应拦截=>", res.data);
//例:后端数据处理错误,并返回错误原因;前端获取错误原因并展示
if (res.data.success == false) {
Message({
message: res.data.data.message + ',请重试!',
type: 'warning'
});
}
return res ? res.data : res;
}, err => {
console.log(err);
//打印完整的错误信息
console.log("响应拦截错误完整信息=>",err.response)
//也可以在这里对不同的错误码做不同的展示处理
throw err;
})
- 创建配置axios实例
- 创建request.js文件
js
// request.js
import axios from 'axios';
import qs from 'qs';
import { Message } from 'element-ui'
//导出request方法,供其它地方使用
export function request(config) {
const instance = axios.create({
baseURL: 'http://xxx.xx.xx.xxx:xxxx',
timeout: 5000,
// 'transformRequest' 允许在向服务器发送前,修改请求数据
transformRequest: [function (data) {
// 对 data 做序列化处理
return qs.stringify(data);
}],
})
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
//------------------请求拦截-------------------//
//------------在发送请求之前做些什么------------//
instance.interceptors.request.use(config => {
// 若存在token则带token
const token = window.localStorage.getItem('token');
if (token) {
config.headers.Authorization =token;
}
// 放行
return config;
}, err => {
console.log("请求拦截=>", err);
return err;
})
//------------------响应拦截-------------------//
//-------------对响应数据做点什么-------------//
instance.interceptors.response.use(res => {
//例:后端数据处理错误,并返回错误原因;前端获取错误原因并展示
console.log("响应拦截=>", res.data);
if (res.data.success==false) {
Message({
message: res.data.data.message+',请重试!',
type: 'warning'
});
}
return res ? res.data : res;
}, err => {
console.log(err);
console.log("响应拦截错误完整信息=>",err.response)
//也可以在这里对不同的错误码做不同的展示处理
throw err;
})
return instance(config);
}
- 然后就可以写接口函数内容
js
import { request } from './request';
export function login(data) {
return request({
url: '/user/login',
method: 'post',
data,
})
}
- 在页面中导入、传参即可使用
5. 配置router
js
// 还是已刚刚的例子修改
const routes = [
{
// 每次进入默认进入该路由
path: '/',
// redirect属性,如果是默认路由,则跳转
redirect: '/home',
// 可以为路由进行命名,可以通过name进行路由跳转
name: '',
// 可以保存路由里的一些信息,相当于html里的meta元信息,你可以通过$route里来获取
meta: {
},
// 该路由下展示的子路由,必须在路由组件中写router-view标签才能展示
children: [
{
path: '',
component: ''
}
]
},
{
path: '/home',
//component: home
// 按需导入组件,app.js分块打包
component: () => import('./home.js)
},
{
path: '/login',
//component: login
// 当然你也可以给component来实现路由组件的懒加载功能
component: (resolve) => {
require(['./login'], resolve)
},
}
]
- 缓存全部路由
js
// 在router-view外包裹keep-alive
<keep-alive>
<router-view></router-view>
</keep-alive>
// 使用 include 缓存包含的路由-默认就是这种
<keep-alive include="该路由的name名称">
<router-view></router-view>
</keep-alive>
// 使用 exclude来指定该组件不需要缓存
<keep-alive exclude="该路由的name名称">
<router-view></router-view>
</keep-alive>
- 部分路由缓存
js
使用 meta
在路由中添加下面属性
meta: {keepAlive: true // 缓存}
meta: {keepAlive:false // 不缓存 }
例:
{
path:'/Distribution',
name:'Distribution',
component: Distribution,
meta: {keepAlive: true // 缓存}
}
然后在页面
js
<keep-alive >
//当前进入的路由 meta里面 keepAlive为true时走这里
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
//当前进入的路由 meta里面 keepAlive为false时走这里 下面 if 判断进行了取反处理
<router-view v-if="!$route.meta.keepAlive">
</router-view>
6. 权限管理
然后权限配置也是通过router里面的mete设置一个roles
7. 多语言
- 安装 npm install vue-i18n --save
- 创建i18n文件index.js
js
// 在src目录中创建i18n文件夹,在文件夹中创建index.js文件,用于全局配置多语言文件
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { Locale } from 'vant'
// 引入组件的语言包
import zhCN from 'vant/es/locale/lang/zh-CN'
import zhHK from 'vant/es/locale/lang/zh-HK'
import enUS from 'vant/es/locale/lang/en-US'
// 引入业务自定义的语言包
const localCN = require('./locale/zh') // 简体
const localHK = require('./locale/hk') // 繁體
const localUS = require('./locale/en') // English
// 在这里引入moment了,所以不在main.js引入了
import Moment from 'moment'
Vue.prototype.$moment = Moment
Vue.use(VueI18n);
// 语言包的类型合并
const messages = {
'zh_CN': { ...zhCN, ...localCN },
'zh_HK': { ...zhHK, ...localHK },
'en_US': { ...enUS, ...localUS }
}
// localStorage获取当前语言类型(初次本地不存在'lang'字段存储,默认设置为'zh_CN')
const lang = localStorage.getItem('lang') || 'zh_CN'
console.log('初始语言类型', lang);
// 初次加载的语言默认设置
Locale.use(lang, messages[lang])
// 时间类moment语言默认设置
Moment.locale(lang)
export default new VueI18n({
locale: lang, // set locale
messages: messages // set locale messages
});
- 创建业务自定义语言包
js
// src/i18n/locale/en.js
module.exports = {
login: {
'username': 'Please enter the user name',
'password': 'Please enter your password',
'Username': 'Username',
'Password': 'Password'
},
form: {
'submit': 'Submit'
}
}
- main.js引入i18n配置文件
js
// mian.js
import i18n from './i18n/index'
new Vue({
i18n,
render: h => h(App),
}).$mount('#app')
- 然后就可以在页面中使用
js
import language from '../../i18n/index'
<div>{{$t('login.username')}}</div>
8. 统一错误处理
- 创建统一异常处理模块
js
// src/errorHandler.js
export default function errorHandler(error) {
// 根据不同的错误类型进行处理
if (error.response) {
// 后端返回错误
const { status } = error.response;
if (status === 403) {
// 处理权限不足的情况
alert('无权限使用此功能');
} else if (status === 500) {
// 处理服务器内部错误
alert('服务器内部错误');
} else {
// 处理其他错误
alert('请求错误');
}
} else if (error.request) {
// 请求发送失败
alert('请求发送失败');
} else {
// 其他错误
alert('发生错误');
}
}
- 使用axios拦截器处理异常
js
import errorHandler from './utils/errorHandler';
// 设置axios的拦截器
// 通过 axios.interceptors.response.use 方法设置了一个响应拦截器,处理所有的响应异常
axios.interceptors.response.use(
response => response,
error => {
errorHandler(error);
return Promise.reject(error);
}
);
- 在页面中使用异常处理
vue
<template>
<div>
<button @click="handleClick">点击使用功能</button>
</div>
</template>
<script>
import errorHandler from './utils/errorHandler';
export default {
methods: {
handleClick() {
try {
// 发送请求使用功能
} catch (error) {
errorHandler(error);
}
}
}
}
</script>