一、必要的环境配置
1.安装node.js

跟着安装导航一直下一步即可,它会自动帮你配置环境变量。注意修改一下安装路径,安装成功后,cmd中查看node.js版本号,看是否安装成功。
node -v

2.安装vue/cli 脚手架
安装node.js后就可以使用npm指令了,在cmd中使用以下指令安装vue-cli 脚手架
//安装vue-cli
npm install -g @vue/cli
//版本升级
npm update -g @vue/cli
查看版本,看是否安装成功
vue --version

二、创建vue项目
在需要创建vue项目下的目录打开cmd,执行以下命令
//vue create 项目名
vue create testue

通过上下键选择项目模板,选中后按回车键。这里直接选的vue2的项目模板

创建成功后的项目目录结构如下:

还可以自定义创建vue项目,上下键选中Manually select features选项后回车

上下键移动光标,空格选中所需要的插件 带 * 表示已被选中 
上下键选择版本,回车进入下一步,这里选择vue2

router路劲选择直接选 n,语法代码格式检测选标准standard,语法检查时间选保存时检查



第三方插件配置在放在package.json

选择y 把以上配置保存为一个模板,再给模板取个名字,以后创建可以直接用这个模版创建了
最终选项图

之后回车,创建vue项目

最终项目目录结构

三、 手动引入vue项目需要的一些插件
router的引入
在项目目录下打开终端,执行npm install vue-router --save安装router插件
//安装最新版本
npm install vue-router --save
//安装指定版本
npm i vue-router@3.4.9
安装成功后会在package.json的dependencies里生成一个router版本属性

在src文件夹下创建一个router文件夹,并在router文件夹下创建一个index.js文件配置router信息

index.js内容:
import Vue from 'vue'
import Router from 'vue-router'
import login from '../views/login.vue'
Vue.use(Router)
//路由数组里的第一路由对象就是vue项目的启动的显示的第一个页面
export const constantRoutes = [
{
path:'/',
//redirect 是重定向
redirect:'/login'
},
{
path: '/login',
name:'login',
component: login,
},
{
path: '/404',
component: (resolve) => require(['@/views/error/404'], resolve),
hidden: true
},
{
path: '/401',
component: (resolve) => require(['@/views/error/401'], resolve),
hidden: true
}
]
export default new Router({
mode: 'history', // 去掉url中的#
scrollBehavior: () => ({
y: 0
}),
routes: constantRoutes
})
在main.js中全局引入router
import Vue from 'vue'
import App from './App.vue'
import router from './router/index.js'
new Vue({
el: '#app',
router,
render: h => h(App),
})
vuex的引入
项目使用的vue2,应安装vuex3的版本,vue3的话要用vuex4版本
查询可安装版本:
E:\桌面\tes\testue> npm view vuex versions --json
[
"0.1.0",
"0.2.0",
"0.3.0",
"0.4.0",
"0.4.1",
"0.4.2",
"0.5.0",
"0.5.1",
"0.6.1",
"0.6.2",
"0.6.3",
"0.7.0",
"0.7.1",
"0.8.0",
"0.8.1",
"0.8.2",
"1.0.0-rc",
"1.0.0-rc.2",
"1.0.0",
"1.0.1",
"2.0.0-rc.1",
"2.0.0-rc.3",
"2.0.0-rc.4",
"2.0.0-rc.5",
"2.0.0-rc.6",
"2.0.0",
"2.1.0",
"2.1.1",
"2.1.2",
"2.1.3",
"2.2.0",
"2.2.1",
"2.3.0",
"2.3.1",
"2.4.0",
"2.4.1",
"2.5.0",
"3.0.0",
"3.0.1",
"3.1.0",
"3.1.2",
"3.1.3",
"3.2.0",
"3.3.0",
"3.4.0",
"3.5.0",
"3.5.1",
"3.6.0",
"3.6.1",
"3.6.2",
"4.0.0-alpha.1",
"4.0.0-beta.1",
"4.0.0-beta.2",
"4.0.0-beta.3",
"4.0.0-beta.4",
"4.0.0-rc.1",
"4.0.0-rc.2",
"4.0.0",
"4.0.1",
"4.0.2"
]
安装指定版本的vuex
npm install vuex@3.6.0
同样可以在package.json中看到安装的vuex的版本信息
在src文件夹下创建一个storage文件夹,创建一个index.js对localstorage进行封装,可以用localstorage存储token
// 封装操作localstorage本地存储的方法 模块化
var storage = {
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
// localStorage.key = value;
// localStorage[key] = value;
},
get(key) {
return JSON.parse(localStorage.getItem(key));
},
getForIndex(index) {
return localStorage.key(index);
},
getKeys(){
let items = this.getAll();
let keys = [];
for (let index=0;index<items.length;index++){
keys.push(items[index].key);
}
return keys;
},
getLength() {
return localStorage.length;
},
getSupport() {
return (typeof (Storage) !== "undefined") ? true : false;
},
remove(key) {
localStorage.removeItem(key);
},
removeAll() {
localStorage.clear();
},
getAll() {
let len = localStorage.length; // 获取长度
let arr = new Array(); // 定义数据集
for (var i = 0; i < len; i++) {
// 获取key 索引从0开始
var getKey = localStorage.key(i);
// 获取key对应的值
var getVal = localStorage.getItem(getKey);
// 放进数组
arr[i] = {
'key': getKey,
'val': getVal,
}
}
return arr;
}
}
export default storage;
在src文件夹下创建store文件夹,在index.js里配置vuex的store
import Vue from 'vue'
import Vuex from 'vuex'
import storage from '../storage/storage.js'
import {login,logout,getInfo} from '@/api/login'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
token: '',
userName: '',
uuid: '',
avatar: '',
roles: [],
permissions: []
},
//通常用来对state的属性进行计算
getters: {
getToken(state) {
return state.token || storage.get("token") || "";
},
getUserName(state) {
return state.userName || storage.get("userName") || "";
},
getUuid(state) {
return state.uuid || storage.get("uuid") || "";
}
},
//通常用来操作state的属性值,但只能用同步函数,异步请求不能写在这
mutations: {
SET_TOKEN: (state, token) => {
state.token = token;
storage.set('token', token);
console.log('store、localstorage保存token成功!');
},
DEL_TOKEN: (state) => {
state.token = '';
storage.remove('token');
},
SET_USERNAME: (state, userName) => {
state.userName = userName;
storage.set('userName', userName);
},
DEL_USERNAME: (state) => {
state.userName = '';
storage.remove('userName');
},
SET_UUID: (state, uuid) => {
state.uuid = uuid;
storage.set('uuid', uuid);
},
DEL_UUID: (state) => {
state.uuid = '';
storage.remove('uuid');
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
}
},
//通常用来操作state的属性值,可以在这写异步请求
actions: {
//用户登录
Login({commit}, userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
console.log("token="+res.token);
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.user
//获取用户头像
const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions)
}
commit('SET_USERNAME', user.userName)
commit('SET_AVATAR', avatar)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('DEL_TOKEN')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('DEL_TOKEN')
resolve()
})
}
}
});
export default store;
在main.js中引入store
import Vue from 'vue'
import App from './App.vue'
import store from './store/index.js'
import Element from 'element-ui';
import router from './router/index.js'
Vue.use(Element);
new Vue({
el: '#app',
router,
store: store,
render: h => h(App),
})
axios的引入
axios是对ajax的封装,安装指令
npm install axios -s
在src文件夹下创建一个utlis文件夹,utils文件夹下创建一个request.js文件来对前端发起的请求进行操作,在这里设置请求拦截器把token塞进每个请求的请求头
import axios from 'axios'
import store from '../store/index.js'
// 创建一个axios实例 axios是对ajax的封装
const service =axios.create({
baseURL:"/dev-api",
timeout:10000
})
//对后台请求的request的拦截器,在这里实现每个request带token
service.interceptors.request.use(
config=>{
config.headers.Authorization=store.getters.getToken;
return config;
},
error=>{
console.log("在request拦截器显示错误:", error.response)
return Promise.reject(error);
}
);
//respone拦截器
service.interceptors.response.use(
response => {
// 在status正确的情况下,code不正确则返回对应的错误信息(后台自定义为200是正确,并且将错误信息写在message),正确则返回响应
return response.data.code == 200 ? response.data : Promise.reject(response.data.message);
},
error => {
// 在status不正确的情况下,判别status状态码给出对应响应
if (error.response) {
console.log("在respone拦截器显示错误:", error.response)
switch (error.response.status) {
case 401:
//可能是token过期,清除它
store.commit("DEL_TOKEN");
case 403:
store.commit("DEL_TOKEN");
router.replace({ //跳转到登录页面
path: '/login',
// 将跳转的路由path作为参数,登录成功后跳转到该路由
query: { redirect: router.currentRoute.fullPath }
});
}
}
return Promise.reject(error.response.data);
}
);
export default service
再在src下创建api文件夹,这个文件夹下js文件写请求函数
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return request({
url: '/login',
method: 'post',
data: data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
})
}
// 退出方法
export function logout() {
return request({
url: '/logout',
method: 'post'
})
}
// 获取验证码
export function getCodeImg() {
return request({
url: '/captchaImage',
method: 'get'
})
}
引入Element-ui
指令
npm i element-ui -S
在main.js引入Element-ui
import Vue from 'vue'
import App from './App.vue'
import store from './store/index.js'
import Element from 'element-ui';
import router from './router/index.js'
Vue.use(Element);
new Vue({
el: '#app',
router,
store: store,
render: h => h(App),
})
vue.config.js文件
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false ,//关闭语法检查
// devServer :开发 服务器
devServer: {
port: '8888',
open: true,
//proxy: 代理
proxy: {
// 必须重启服务器, 配置才能生效
// 如果请求地址是 /dev-api 开头的, 则被当前代理处理
'/dev-api': {
// target: 由服务器帮助到此域名中请求数据 -- 代理
target: 'http://localhost:8080',
changeOrigin: true, //代表 域名不同,需要启动代理模式
// 路径重写: 真正发送的请求地址中, 要去掉/dev-api 开头
pathRewrite: {
// ^ :正则中的 字符串开头 的意思
'^/dev-api': '',
// 如果不替换则发送的请求地址如下: 会多余一个
},
},
},
},
})
目前配置这么多,以后在增加
项目最终目录结构:

1327

被折叠的 条评论
为什么被折叠?



