文章目录
 
 
前言(很重要哦)
 
| 管理系统后端(java)请参考:https://blog.csdn.net/grd_java/article/details/121925792 | 
|---|
 
| 本项目源码,码云:https://gitee.com/yin_zhipeng/vue-backstage-scaffolding.git | 
|---|
 
后台管理系统,一般都是内部人员使用,所以对界面要求不高,一般都使用模板开发。而前台系统,是给游客使用,要凸显个性,所以一般自己开发,不使用模板 | 
|---|
 
 - 如果你
GitHub进不去,可以到这里下载(码云):https://gitee.com/panjiachen/vue-admin-template.git 
 
 
| 下载完成后,我们用它来当做项目,执行npm install --save 来下载相关依赖,然后通过npm run dev启动项目,最后浏览器查看项目 | 
|---|
 
一、概念和技术总结(重点,一定要搞懂)
 
 
1. vue
 
 
 - 自定义事件:适用于子组件给父组件传递数据, $ on、和$ emit
 - 全局事件总线$bus:适用于任何场景,Vue.prototype. $bus = this;
 - pubsub-js发布和订阅:适用于任何场景,但是Vue用的不多,一般React框架经常使用
 - Vuex:适用于任何场景,用的非常多
 - solt插槽:使用于针对结构(标签)的父子组件通信,常用的有默认插槽,具名插槽和作用域插槽
 
 
 
2. vue-admin-template模板文件解析
 
| 文件目录解析(注意:以下所有文件夹和文件,你自己写效果也一样,并不是必须在这个模板文件中才能用) | 
|---|
build 
	
mock
	
node_modules
	
p ublic
	
src 
	
	
	
	
	
	
	
	
	
	
App.vue
	
main.js
	
permission.js
	
settings
	
.editorconfig
	
.env.development
	
.env.production
	
.env.staging
	
.eslintignore
	
.eslintrc.js
	
.gitignore
	
.travis.yml
	
babel.config.js
	
jest.config.js
	
LICENSE
	
jsconfig.json
	
package.json
	
postcss.config.js
	
vue.config.js
	
 
 
| jsconfig.json文件配置src别名为@解析 | 
|---|
 
| 3个环境配置文件,可以通过webpack对外暴露的函数process获取,注意配置文件中内容,要以VUE_APP_*****开头(就和,java类名首字母要大写一样,大家要共同遵守) | 
|---|
 
console.log(process)
console.log(process.env)
 
 
 
a =>  return a;
 
 
3. 异步相关,前后端交互
 
| 1. 当年PanJiaChen开发此模板时,还没有async函数(ES6的语法),所以使用传统Promise处理异步,我们后面统一将其改造为使用async函数,对于Promise和async请参考文章:https://blog.csdn.net/grd_java/article/details/105384601 | 
|---|
 
 
 
4. 导航守卫
 
| 不知道的参考官方文档https://router.vuejs.org/zh/guide/advanced/navigation-guards.html | 
|---|
 
 
二、单点登录实现
 
| 登录页面直接使用模板提供的即可,我们对其样式进行一些修改,以让你知道如何对其自定义 | 
|---|
 
 
1. 后端接口和响应结果分析
 
 
2. 解决跨域,以及请求头.几乎所有项目都需要的配置,背下来吧。
 
| 1. 首先,我们知道环境配置文件中,有VUE_APP_BASE_API这个东西,我们通过这个来规定请求路径,我们可以规定它.改完记得重启项目(我们是开发环境,所以修改.env.development文件) | 
|---|
 
| 2. 然后我们通过修改webpack的配置文件vue.config.js,配置跨域代理,主要位置,别写错位置,同样,配置完记得重启项目 | 
|---|
 
    
    proxy: {
      [process.env.VUE_APP_BASE_API]: {
        target: `http://localhost:8001`, 
        
        pathRewrite: {
          ['^'+process.env.VUE_APP_BASE_API]: ''
        }
      }
    },
 
| 3. token请求头这种东西,直接配置到请求拦截器中就好了,request.js,注意token请求头的key必须为authorization | 
|---|
 
service.interceptors.request.use(
  config => {
    
    if (store.getters.token) {
      
      
      
      config.headers['authorization'] = getToken()
    }
    return config
  },
  error => {
    
    console.log(error) 
    return Promise.reject(error)
  }
)
 
3. 验证码展示
 
| 后端直接返回一张图片给我们,我们可以通过window.URL.createObjectURL(response)来获取图片的一个url地址 | 
|---|
| window.URL.createObjectURL用于创建一个新的对象URL,该对象URL可以代表某一个指定的File对象或Blob对象 | 
 
 
| 1. 首先,我们后端的验证码功能没有响应码,而我们使用的模板,在request.js中封装了请求拦截器和响应拦截器,致命的是,响应拦截器直接拦截所有响应码不是20000的响应 | 
|---|
 
| 2. 封装api请求,注意一定要将响应类型设置为’blob’(responseType:‘blob’) | 
|---|
 
export function captcha() {
  return request({
    url: 'captcha',
    method: 'get',
    responseType:'blob'
  })
}
 
| 3. login页面,login/index.js文件引入api,然后展示验证码 | 
|---|
 
    
    async getImgCode () {
      await captcha().then(response => {
        this.codesrc = window.URL.createObjectURL(response)
      })
    },
 
 
      <el-form-item prop="code" class="code">
        <span class="svg-container">
<!--          <svg-icon icon-class="el-icon-s-flag" />-->
          <i class="el-icon-edit"></i>
        </span>
        <el-input
          class="code-input"
          ref="code"
          type="text"
          v-model="loginForm.code"
          placeholder="验证码"
          name="code"
          tabindex="2"
          auto-complete="on"
          @keyup.enter.native="handleLogin"
        />
      </el-form-item>
      <img :src="codesrc" class="code-img" @click="getImgCode">
  .code{
    width: 70%;
    float: left;
  }
  .code-img{
    float: right;
    width: 29.6%;
    
  }
 
4. 单点登录,退出登录,根据后端API实现
 
 
1. api接口
 
| api文件夹user.js文件,修改login,getInfo和logout三个接口 | 
|---|
 
2. 路由组件编写登录函数逻辑
 
| 我们发现,此模板所有登录逻辑都在view/login/index.vue文件中的handleLogin方法中,对其进行修改 | 
|---|
 
    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true
          
          this.$store.dispatch('user/login', this.loginForm).then(() => {
            this.$router.push({ path: this.redirect || '/' })
            this.loading = false
          }).catch(() => {
            this.loading = false
            this.getImgCode()
          })
        } else {
          console.log('error submit!!')
          this.getImgCode()
          return false
        }
      })
    }
 
3. 修改store(vuex)异步逻辑
 
| 所有操作都在store/user.js中,我们需要修改login和getInfo以及logout | 
|---|
 
  
  
  async login({ commit },userInfo) {
    
    const { username,password,code} = userInfo;
    
    let result = await login({username: username.trim(),password:password,code:code});
    if (result.code==20000){
      
      const token = result.data.tokenHead+' '+result.data.token;
      
      commit("SET_TOKEN",token);
      
      setToken(token)
    }else{
      
      return Promise.reject(new Error(result.message));
    }
  },
  
  async getInfo({ commit, state }) {
    
    let result = await getInfo(state.token);
    if(result.code === 20000){
      const { loginInfo } = result.data
      if (!loginInfo) {
        return reject('验证失败,请重新登录.');
      }
      const {username} = loginInfo;
      commit('SET_NAME',username);
      commit('SET_AVATAR','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif')
    }else{
      
      return Promise.reject(new Error(result.message));
    }
  },
  
  async logout({ commit, state }) {
    let result = await logout(state.token);
    if(result.code === 20000){
      removeToken() 
      resetRouter()
      commit('RESET_STATE')
    }else{
      
      return Promise.reject(new Error(result.message));
    }
  },
 
三、后台管理系统实现
 
| 由于篇幅原因,我将其放在另一篇文章中:@TODO 还没写完 | 
|---|