vue-cli3项目创建-配置-发布

首先需要安装vue-cli3,并初始化一个项目官方教程
初始化项目需默认安装router及vuex
源码
项目预览 登录账号密码随意填 项目接口用的是easy-mock的服务,偶尔会500造成接口请求报错,如果遇到就等一会重新试下~~

效果预览

效果预览

一、Vue-cli3安装成功并启动

Vue-cli3安装成功并启动

二、删除替换多余文件及代码

1.修改文件--src/App.vue
<template>
  <div id="app">
    <router-view/>
  </div>
</template>
2.修改文件--src/router.js
import Vue from "vue";
import Router from "vue-router";

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: "/",
      name: "Home",
      component: () => import("./views/Home.vue")
    }
  ]
});
3.修改文件--src/views/Home.vue
<template>
  <div>this is index home</div>
</template>
4.删除文件--src/components/HelloWorld.vue和src/views/About.vue
5.启动项目预览
启动项目预览

三、优化vuex结构

1.删除文件--src/store.js
2.新建文件--src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
import user from "./modules/user";
import getters from "./getters";

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    user
  },
  getters
});

export default store;
3.新建文件--src/store/getters.js
const getters = {
  token: state => state.user.token
};
export default getters;
4.新建文件--src/store/modules/user.js
const user = {
  state: {},

  mutations: {},

  actions: {}
};
export default user;
5.main.js中引入vuex
import store from "./store/index";

四、配置及读取开发生产环境

1.根目录下新建文件--vue.config.js
module.exports = {
  chainWebpack: config => {
    config.plugin("define").tap(args => {
      args[0]["process.env"].BASE_URL = JSON.stringify(process.env.BASE_URL);
      return args;
    });
  }
};
2.根目录下新建开发环境文件--.env.dev
NODE_ENV = "dev"
BASE_URL = "https://easy-mock.com/mock/5c513888582d704670f279b9/dev/api"
3.根目录下新建生产环境文件--.env.prod
NODE_ENV = "prod"
BASE_URL = "https://easy-mock.com/mock/5c51391e582d704670f279bc/prod/api"
4.在package.json中指定mode
"serve": "vue-cli-service serve --mode dev",
"build": "vue-cli-service build --mode prod",
5.测试环境是否配置成功

在main.js中打印环境变量

console.log(process.env)

重启项目

Ctrl + c
npm run serve

控制台中看到dev的url说明配置成功

配置成

五、封装axios添加登录及用户信息等权限

1.配置alias
//vue.config.js
const path = require("path");
module.exports = {
  configureWebpack: () => ({
    resolve: {
      alias: {
        "@": path.resolve("./src")
      }
    }
  }),
  chainWebpack: config => {
    config.plugin("define").tap(args => {
      args[0]["process.env"].BASE_URL = JSON.stringify(process.env.BASE_URL);
      return args;
    });
  }
};
2.安装、封装axios
npm install axios --save
3.新建文件--src/utils/request.js
import axios from "axios";
import store from "../store";

// 创建axios实例
const service = axios.create({
  baseURL: process.env.BASE_URL, // api 的 base_url
  timeout: 5000 // 请求超时时间
});

// request拦截器
service.interceptors.request.use(
  config => {
    if (store.getters.token) {
      config.headers["X-Token"] = store.getters.token;
    }
    if (config.method === "post") {
      config.data = config.params;
      config.params = "";
    }
    return config;
  },
  error => {
    // Do something with request error
    console.log(error); // for debug
    Promise.reject(error);
  }
);

// response 拦截器
service.interceptors.response.use(
  response => {
    let { data, code, result, message } = response.data;
    if (code !== 200) {
      // if(status===500) 处理token过期等
      return Promise.resolve(false);
    } else {
      return { data, result, message };
    }
  },
  error => {
    console.log("err" + error); // for debug
    return Promise.reject(error);
  }
);

export default service;
4.封装localstorage 新建文件--src/utils/storage.js
const storage = {
  get(key) {
    return window.localStorage.getItem(key);
  },
  set(key, val) {
    window.localStorage.setItem(
      key,
      typeof val !== "string" ? JSON.stringify(val) : val
    );
  },
  del(key) {
    window.localStorage.removeItem(key);
  },
  cle() {
    window.localStorage.clear();
  }
};
export default storage;
5.添加路由访问权限 新建文件--src/permission.js
import router from "./router";
import store from "./store";
import Storage from "@/utils/storage"; // 验权

const whiteList = ["/login"]; // 不重定向白名单
router.beforeEach((to, from, next) => {
  if (Storage.get("token")) {
    if (to.path === "/login") {
      next({ path: "/" });
    } else {
      if (!store.getters.userInfo) {
        store.dispatch("getUserInfo");
        next();
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next();
    } else {
      next(`/login?redirect=${to.path}`); // 否则全部重定向到登录页
    }
  }
});
6.完善axios请求api 新建文件--src/api/userApi.js
import request from "@/utils/request";

const user = {
  //登录
  login({ name, password }) {
    return request({
      url: "/login",
      method: "post",
      params: {
        name,
        password
      }
    });
  },
  //用户信息
  getInfo({ token }) {
    return request({
      url: "/userInfo",
      method: "post",
      params: {
        token
      }
    });
  },
  //登出
  logOut({ token }) {
    return request({
      url: "/userLogout",
      method: "post",
      params: {
        token
      }
    });
  }
};
export default user;
7.vuex中getter调用及用户信息登出操作

(1) 修改getter -- src/store/getters.js

//src/store/getters.js
const getters = {
  token: state => state.user.token,
  userInfo: state => state.user.userInfo
};
export default getters;

(2) 修改user module -- src/store/module/user.js

//src/store/module/user.js
import Storage from "@/utils/storage";
import userApi from "@/api/userApi";
const user = {
  state: {
    token: Storage.get("token") || null,
    userInfo: ""
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      Storage.set("token", token);
      state.token = token;
    },
    SET_USER_INFO: (state, userInfo) => {
      state.userInfo = userInfo;
    }
  },

  actions: {
    setToken({ commit }, token) {
      commit("SET_TOKEN", token);
    },
    //用户信息
    getUserInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        userApi
          .getInfo({ token: state.token })
          .then(res => {
            if (res.result) {
              commit("SET_USER_INFO", res.result.userInfo);
            }
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //登出
    logOut({ commit, state }) {
      return new Promise((resolve, reject) => {
        userApi
          .logOut({ token: state.token })
          .then(() => {
            commit("SET_TOKEN", "");
            Storage.cle();
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    }
  }
};
export default user;
8.添加首页及登录页

(1) 修改路由 -- src/router.js

import Vue from "vue";
import Router from "vue-router";

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: "/login",
      name: "Login",
      component: () => import("./views/Login.vue")
    },
    {
      path: "/",
      name: "Home",
      component: () => import("./views/Home.vue")
    }
  ]
});

(2) 添加登录页 新建文件 -- src/views/Login.vue

<template>
  <div>
    <div>test</div>
    <div>
      <div>
        <label for="name">用户名</label>
        <input type="text" name="name" v-model="user.name">
      </div>
      <div>
        <label for="password">密码</label>
        <input type="password" name="password" v-model="user.password">
      </div>
      <button @click="userLogin">登录</button>
      <div>{{token}}</div>
    </div>
  </div>
</template>

<script>
import userApi from "@/api/userApi";
import { mapGetters } from "vuex";
export default {
  data() {
    return {
      user: {
        name: "",
        password: ""
      }
    };
  },
  computed: {
    ...mapGetters(["token"])
  },
  methods: {
    async userLogin() {
      let res = await userApi.login(this.user);
      if (res) {
        this.$store.dispatch("setToken", res.result.token);
        this.$router.push({ path: this.redirect || "/" });
      }
    }
  }
};
</script>

(3) 添加首页 新建文件 -- src/views/Home.vue

<template>
  <div>
    <div>Home</div>
    <div>
      <div>
        <span>用户名:</span>
        {{userInfo.name}}
      </div>
      <div>
        <span>权限:</span>
        {{userInfo.auth}}
      </div>
      <div>
        <span>账户创建时间:</span>
        {{userInfo.time}}
      </div>
    </div>
    <button @click="userLogout">退出登陆</button>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
export default {
  computed: {
    ...mapGetters(["userInfo"])
  },
  methods: {
    userLogout() {
      this.$store.dispatch("logOut").then(() => {
        location.reload(); // 为了重新实例化vue-router对象 避免bug
      });
    }
  }
};
</script>
9.引入权限--最终效果预览
//main.js
import "@/permission";

效果预览

效果预览

六、打包部署

npm run build

部署可选择手动打包也可以用jenkins自动打包
jenkins自动打包教程
源码
项目预览 登录账号密码随意填 项目接口用的是easy-mock的服务,偶尔会500造成接口请求报错,如果遇到就等一会重新试下~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • vue-cli3项目搭建配置以及性能优化 在之前的开发中主要用的是vue-cli2,最近空闲时间比较多,接下来有新...
    bayi_lzp阅读 19,427评论 16 68
  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 2,855评论 1 4
  • 项目地址https://github.com/hongchh/timeline-x 一、成品展示 二、项目需求 添...
    前端杨肖阅读 9,300评论 0 10
  • 从18年7月16号入职到现在已经5个月多了,入职之后就一直使用vue,来这边温习记录下使用的步骤。在我的理解中vu...
    拖孩阅读 1,841评论 2 12
  • 我们每个人都是一个系统,角色是我这个系统的表象之一,从角色引入来看我这个世界。 为什么要有系统思维? 秘诀崇拜,如...
    EmmaJW阅读 481评论 0 0