【vue】vue项目初始化及vuex/router/axios/代理/强刷vuex数据丢失/强刷token验证等配置

本篇为个人总结,有不对的地方请指正

一、创建项目

目前有两种常见的创建方式

1.控制台创建项目

//vue-cli 2.x+ 版本
vue init webpack '文件名'
//vue-cli 3.x+ 版本
vue create '文件名'

可能会出现以下问题

输入命令后出现错误:原因是脚手架在创建的时候从github里下载webpack失败了

在这里插入图片描述

解决方法:

采用离线创建项目:在github下载 vuejs-templates/ webpack 包,解压到用户目录。比如C:\Users\Administrator\.vue-templates\webpack,没有.vue-templates\webpack文件就自行创建

在这里插入图片描述

命令加上--offline表示离线创建

vue init webpack '文件名' --offline

在这里插入图片描述

具体步骤参考:https://blog.csdn.net/qq_45731083/article/details/114921816

2.可视化创建项目

vue ui

在这里插入图片描述
在这里插入图片描述

3.vue-cli脚手架的区别

创建命令不一

//vue-cli 2.x+ 版本
vue init webpack '文件名'
//vue-cli 3.x+ 版本
vue create '文件名'

文件目录不一

vue-cli 2.x+ 版本:

在这里插入图片描述

vue-cli 3.x+ 版本:
在这里插入图片描述

还有很多区别,不做详细讲解…

二、初始化与运行

安装依赖

创建或下拉git的项目第一件事就是安装依赖,以防项目跑不起来

新建终端,输入以下命令

npm install

在这里插入图片描述

命令

运行之前先要看package.json文件里的scripts运行命令是什么

vue-lic 3.x+为例:

在script里的有serve和build两个命令

  • serve:运行命令
  • build:打包命令

在这里插入图片描述

运行项目

npm run serve

// vue-lic 2.x+
// npm run dev 或 npm start

三、文件目录解析

以vue-cli2.x +为例,以下就项目文件夹中的各文件的作用进行介绍:

├── build/               # Webpack 配置目录
├── dist/                # build 生成的生产环境下的项目
├── config/               # Vue基本配置文件,可以设置监听端口,打包输出等
├── node_modules/                # 依赖包,通常执行npm i会生成
├── src/                 # 源码目录(开发的项目文件都在此文件中写)
│   ├── assets/            # 放置需要经由 Webpack 处理的静态文件,通常为样式类文件,如css,sass以及一些外部的js
│   ├── components/        # 公共组件
│   ├── filters/           # 过滤器
│   ├── store/         # 状态管理
│   ├── routes/            # 路由,此处配置项目路由
│   ├── services/          # 服务(统一管理 XHR 请求)
│   ├── utils/             # 工具类
│   ├── views/             # 路由页面组件
│   ├── App.vue             # 根组件
│   ├── main.js             # 入口文件
├── index.html         # 主页,打开网页后最先访问的页面
├── static/              # 放置无需经由 Webpack 处理的静态文件,通常放置图片类资源
├── .babelrc             # Babel 转码配置
├── .editorconfig             # 代码格式
├── .eslintignore        # (配置)ESLint 检查中需忽略的文件(夹)
├── .eslintrc            # ESLint 配置
├── .gitignore           # (配置)在上传中需被 Git 忽略的文件(夹)
├── package.json         # 本项目的配置信息,启动方式
├── package-lock.json         # 记录当前状态下实际安装的各个npm package的具体来源和版本号
├── README.md         # 项目说明(很重要,便于其他人看懂)

四、配置常见插件与工具类文件

vue项目常用三大插件:vuex、router、axios

vuex配置

安装

//具体安装命令看官方文档
npm install vuex 

创建一个store目录,目录里创建一个index.js文件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
      //共享数据
  },
  getters: {
  },
  mutations: {
      //同步
      //通过commit调用
  },
  actions: {
      //异步
      //通过dispatch调用
  },
  modules: {
      //其他vuex模块
  }
})

实际项目中的基础配置:

import Vue from 'vue'
import Vuex from 'vuex' //vuex文件
import { queryByToken } from '@/api/user' //接口文件
import { Message } from 'element-ui' //element-ui
import route from '@/router/index' //route文件

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    loginInfo: { //用户登录信息
      token: sessionStorage.getItem('token') ?? ''
    },
  },
  getters: {
  },
  mutations: {
    setLoginInfo(state, data) {
      state.loginInfo = data
      // console.log(data)
      if (data.token) window.sessionStorage.setItem("token", data.token)
      else state.loginInfo.token = window.sessionStorage.getItem("token")
    },
  },
  actions: {
    getLoginInfo(context) {
      // 发送token验证请求
      function toLogin(str = '') {
        Message({ type: 'error', message: str || '登录超时' })
        sessionStorage.removeItem("token")
        route.push({name:'login'})
      }
      queryByToken().then(res => {
        if (res.code == 200) context.commit('setLoginInfo', res.data)
        else toLogin(res.msg)
      }).catch(err => toLogin(err.response.data.msg || err.message))
    },
  },
  modules: {
  }
})

配置完vuex文件需要全局使用:

main.js文件中

import Vue from 'vue'
import App from './App.vue'
import router from './router' //引入store
import store from './store' //引入vuex

Vue.config.productionTip = false

import 'element-ui/lib/theme-chalk/index.css' //element-ui 样式
import ElementUI from 'element-ui' //element-ui
Vue.use(ElementUI) //全局使用


new Vue({
  router, //全局使用
  store, //全局使用
  render: h => h(App)
}).$mount('#app')

router配置

安装

//具体安装命令看官方文档
npm install vue-router

创建一个router目录,目录里创建一个index.js文件

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = new VueRouter({
  routes
})

export default router

实际项目中的基础配置:

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '../store/index'
import { Message } from 'element-ui'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'login',
    component: () => import('@/views/Login.vue')
  },
  {
    path: '/home',
    component: () => import('@/views/HomeView.vue'),
    //局部路由拦截
    beforeEnter: (to, from, next) => {
      if (!store.state.loginInfo.token) {
        Message({
          type: 'warning',
          message: '请先登录'
        })
        next({ name: 'login' })
      } else
        next()
    },
    children: []
  }
]

const router = new VueRouter({
  routes
})

//如果在局部路由拦截了就不要打开以下代码
//全局路由拦截
//router.beforeEach((to, from, next) => {
//  if (!store.state.loginInfo.token) {
//        Message({
//          type: 'warning',
//          message: '请先登录'
//        })
//        next({ name: 'login' })
//      } else
//  next()
//})

export default router

配置完router文件需要全局使用:

main.js文件中

import Vue from 'vue'
import App from './App.vue'
import router from './router' //引入store
import store from './store' //引入vuex

Vue.config.productionTip = false

import 'element-ui/lib/theme-chalk/index.css' //element-ui 样式
import ElementUI from 'element-ui' //element-ui
Vue.use(ElementUI) //全局使用


new Vue({
  router, //全局使用
  store, //全局使用
  render: h => h(App)
}).$mount('#app')

axios配置

安装

//具体安装命令看官方文档
npm install axios

实际项目中的基础配置:

在src下创建api目录,创建axios.js文件

import axios from 'axios'
import store from '@/store/index'

axios.defaults.timeout = 1000 * 60 //最迟响应事件 60s

//请求拦截
axios.interceptors.request.use((config) => {
  //把token放入请求头中
  const token = store.state.token || window.sessionStorage.getItem('token') || '' 
  if (token) {
    config.headers.token = token
    return config
  }
  return config
})

//响应拦截
axios.interceptors.response.use((response) => {
  if (response.status === 200) {
    return Promise.resolve(response.data)
  }
  else {
    return Promise.reject(response)
  }
})

export default axios

使用

写接口:

在axios同级目录下,创建user.js文件

import axios from "./axios"; //引号里是刚刚配置的axios.js地址
import urls from '@/utils/urls' //基础地址,后续出详解

export const login = (data) => {
  return axios.post(urls.baseUrl + '/ty-user/login', data)
}

使用接口:

import { login } from "@/api/user";
export defefault{
    ...,
    methods:{
        onSubmit(){
			login(this.form).then((res) => {
				res.data = res.data || {};
					if (res.code == 200) {
						let data = {
							...res.data,
							token: res.token,
						};
						//把token和usename保存到vuex
						this.$store.commit("setLoginInfo", data);
                        //跳转路由
						this.$router.push("/home");
						this.$message({ message: '登录成功', type: "success", });
					} else {
					this.$message({ message: res.msg, type: "error", });
				}
			});            
        }
    }            
}

工具类文件

一般项目中会有一个工具类,是全局多次使用的,可以配置全局使用的。

在这里插入图片描述

├── src/             # 源码目录(开发的项目文件都在此文件中写)
│   ├── utils/       # 工具类
│   │   /──mixins/     # 混合文件
│   │   /──aixos.js    # 网络请求拦截
│   │   /──urls.js     # 路径配置(开发路径/打包路径等),用于接口/图片路径等
│   │   /──utils.js     # 工具类
│   │   /──utils/    # 工具类文件
│   │   /──utils/13123.js    # 个人工具类
│   │   /──utils/43242.js    # 个人工具类

urls路径配置

在utils文件下,创建urls.js文件

// const location = window.location.protocol + '//' + window.location.host // 打包路径

const location='/api'  //虚拟机 开发路径

const baseUrl = location + '/directory' //虚拟机 接口路径

const resources = location + '/upload/' // 资源路径

export default {
  baseUrl, resources
}

在main.js文件下全局声明:

import urls from './utils/urls'
Vue.prototype.$urls = urls

使用:

//图片拼接
<img src="imgUrl?$urls.resources+imgUrl:'../../default.png'" alt="图片">

注意:全局使用仅包括在vue文件下,其他js文件中需单独引入后使用

utils工具类配置

在utils文件下,创建utils.js文件

1.多人开发下的配置

function gutils(){
    return this
}

const utils=new gutils()
export default utils

//妹子1的接口
import kUtils from "./utils/k_utils"
kUtils(utils)

//妹子2的接口
import tUtils from "./utils/t_utils"
tUtils(utils)

在utils文件下,创建utils/k_utils.js文件

import urls from "../urls"

const kUtils = (utils) => {
  // 打印
  utils.printSomething = function (str) {
    console.log(str)
    return str
  }
}
export default kUtils

同理可得utils/t_utils.js文件。

在main.js文件下全局声明:

//全局方法
import gfn from "./utils/utils.js"
Vue.prototype.$gfn = gfn

使用:

export default{
    ...,
    methods:{
        toPrint(){
            this.$gfn.printSomething('123')
        }
    }
}

2.单人开发配置

export default {
	printSomething (str) {
    	console.log(str)
    	return str
  	},
}

在main.js文件下全局声明:

//全局方法
import utils from './utils/utils'
Vue.prototype.$utils = utils

使用:

export default{
    ...,
    methods:{
        toPrint(){
            this.$urls.printSomething('123')
        }
    }
}

注意

  • 不管是安装什么插件,需要注意当前vue-cli版本是否能支持,若不支持可考虑插件降级。
  • 全局使用仅包括在vue文件下,其他js文件中需单独引入后使用

五、打包与部署

项目完成后进行打包部署前,需要修改url和webpck文件。

打包前的配置

1.修改url

在url文件中修改基础路径改为打包路径:

  • 开发时路径
// const location = window.location.protocol + '//' + window.location.host // 打包路径

const location='/api'  //虚拟机 开发路径

const baseUrl = location + '/directory' //虚拟机 接口路径

const resources = location + '/upload/' // 资源路径

export default {
  baseUrl, resources
}
  • 打包路径
const location = window.location.protocol + '//' + window.location.host // 打包路径

// const location='/api'  //虚拟机 开发路径

const baseUrl = location + '/directory' //虚拟机 接口路径

const resources = location + '/upload/' // 资源路径

export default {
  baseUrl, resources
}

2.webpack添加公共路径

在vue.config.js中添加publicPath: process.env.NODE_ENV === 'production' ? './' : '/'

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
  },
  devServer: {
    //代理
    proxy: {
      '^/api': {
        target: 'http://192.168.5.6',
        ws: true,
        changeOrigin: true,
        pathRewrite: { // 重写路径: 去掉路径中开头的'/api'
          '^/api': ''
        },
      },
    }
  }
})

打包

npm run build //命令不固定,根据package.json中的打包命令进行打包

打包后在根目录下生产dist文件,把文件放在虚拟机的Nginx的html下。

六、其他配置

代理

在vue.config.js中添加devServer

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
  },
  devServer: {
    //代理
    proxy: {
      '^/api': {
        target: 'http://192.168.5.6',
        ws: true,
        changeOrigin: true,
        pathRewrite: { // 重写路径: 去掉路径中开头的'/api'
          '^/api': ''
        },
      },
    }
  }
})

Vuex刷新页面数据丢失

在App.vue的created周期中:

//刷新后获取本地缓存中的数据
if (window.sessionStorage.getItem("list") ) {
    this.$store.replaceState(Object.assign({},this.$store.state,JSON.parse(window.sessionStorage.getItem("list"))))
} 
//监听刷新前beforeunload事件,把数据存储到本地缓存
window.addEventListener("beforeunload",()=>{
    window.sessionStorage.setItem("list",JSON.stringify(this.$store.state))
})

可参考资料:https://blog.csdn.net/qq_51441159/article/details/128047610

页面刷新的token验证及用户信息存储

在App.vue的watch中:

watch: {
  $route: {
      handler(newV) {
        let routerList = ["/login"];
        if (routerList.indexOf(newV.path) == -1) {
          this.init();
        }
      },
      deep: true,
  },
}

methods中:

methods: {
    init() {
      let token = window.sessionStorage.getItem("token");
      if (token) {
        this.$store.dispatch("getLoginInfo");
      }
    },
},

在vuex中:

import Vue from 'vue'
import Vuex from 'vuex'
import { queryByToken } from '@/api/user'
import { Message } from 'element-ui'
import route from '@/router/index'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    loginInfo: {
      token: sessionStorage.getItem('token') ?? ''
    },
  },
  getters: {
  },
  mutations: {
    //个人信息存储到本地
    setLoginInfo(state, data) {
      state.loginInfo = data
      if (data.token) window.sessionStorage.setItem("token", data.token)
      else state.loginInfo.token = window.sessionStorage.getItem("token")
    },
  },
  actions: {
    // 发送token验证请求,获取个人信息
    getLoginInfo(context) {
      function toLogin(str = '') {
        Message({ type: 'error', message: str || '登录超时' })
        sessionStorage.removeItem("token")
        route.push({name:'login'})
      }
      queryByToken().then(res => {
        if (res.code == 200) context.commit('setLoginInfo', res.data)
        else toLogin(res.msg)
      }).catch(err => toLogin(err.response.data.msg || err.message))
    },
  },
  modules: {
  }
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值