从零开始搭建vue项目

一、必要的环境配置

1.安装node.js

Node.js 官方网站下载地址: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': '',
  				// 如果不替换则发送的请求地址如下: 会多余一个 
  			},
  		},
  	},
  },
})

目前配置这么多,以后在增加

项目最终目录结构:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值