vue项目搭建(二)


前言

上一章已经搭好了基本的vue项目,现在来对他进行拓展吧。


一、vue全家桶

在之前的步骤中,我们的项目vue全家桶只装了vue-router,接下来我要将全家桶剩下的家人都安装下去,同时对他们进行一点点改动。

1、vue-router

这是默认创建的router文件夹,router的所有内容都在index.js里面。在之后的应用中,我们需要在路由中设立守卫,判断是否退回登录页、无页面是否跳转404,同时路由的列表也写在这里会显得臃肿,不好阅读。所以在统一级文件夹下创建一个"routes"文件夹来专门存放路由列表,而index则存放路由守卫的行为
在这里插入图片描述
创建routes.js文件,并把路由列表填上

import HelloWorld from '@/components/HelloWorld'

const menuRouter = [
  {
    path: '/',
    name: 'HelloWorld',
    component: HelloWorld
  }
]

export default menuRouter

在index.js中引入,同时写上路由守卫。

import Vue from 'vue'
import Router from 'vue-router'
import routes from './routes'
// import HelloWorld from '@/components/HelloWorld'

Vue.use(Router)

// export default new Router({
//   routes: [
//     {
//       path: '/',
//       name: 'HelloWorld',
//       component: HelloWorld
//     }
//   ]
// })
const createRouter = () => new Router({
  scrollBehavior: () => ({ y: 0 }), //滚动条置0
  routes: routes
})

const router = createRouter()
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
  /*防止重复点击导航报错*/
  return originalPush.call(this, location).catch(err => err)
}

router.beforeEach((to, from, next) => {
  /* 必须调用 `next` */
  const flag= true
  if (!flag && to.path !== '/login') {
    return next({ name: 'login' })
  }
  if (flag && to.path === '/login') {
    return next({ name: 'home' })
  }
  return next()
})

router.afterEach((to, from, next) => {
  if (to.matched.length === 0) {
    router.push({ path: '/404' })
  }
})

export default router

到这里vue-router暂时配置成这样,之后添加路由则到routes.js配置,添加登录状态判断或者其他路由配置,则到index.js中配置。

2、vuex

npm install vuex --save或者yarn add vuex --save
安装完成后,创建一个"store"文件夹,把index.js放进去。同样的,我们需要使用vuex保存各种状态。
例如:登录用户的各种状态、信息,项目所需要的各种状态、信息,甚至可以把字典放进去。这里我们分两个出来,一个放用户的,一个放项目的。
在这里插入图片描述

//index.js
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  modules: {app,user}
})

export default store

//modules下app.js  
const app = {
  state: {
    appLoading: {
      tip: '加载中',
      loading: false
    },
    navList: []
  },
  mutations: {
    setAppLoading (state, data) {
      state.appLoading = { ...state.appLoading, ...data }
    },
    setNavList (state, payload) {
      state.navList = payload
    }
  }
}

export default app


const user = {
  namespace: true,
  state: {
    token: null,
    userInfo: null,
    departmentList: null
  },
  mutations: {
    setToken (state, token) {
      state.token = token
    },
    // 设置用户信息
    setLoginUser (state, loginUser) {
      state.userInfo = loginUser
    //   location.reload()
    },
    // 设置用户部门信息
    setUserDepartment (state, data) {
      state.departmentList = data
    }
  },
  actions: {
    // 登录
    async login ({ commit, state }, data) {
      const res = {data: {name: 'zz'}} // 登录接口
      if (!res) {
        return false
      }
      commit('setLoginUser', res.data)
      return true
    },
    async logout ({ commit, state }, data) {
      // 登出接口
      commit('setToken', '')
      commit('setLoginUser', '')
      commit('setUserDepartment', [])
    },
    // 获取用户部门list
    async getUserDepartment ({ commit, state }, data) {
      const res = null // 获取部门接口
      if (!res) {
        return false
      }
      commit('setUserDepartment', res.data)
    }
  }
}

export default user

创建好后,在main.js中引入vuex


import store from './store'
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

这就配置完成了,我们在HellowWorld中试一下吧

<template>
  <div class="hello">{{ msg }}
    <button @click="login">登录</button>
    <button @click="changeMsg">store改变msg</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  computed: {
    getUserInfo () {
      return this.$store.state.user.userInfo
    }
  },
  methods: {
    login () {
      this.$store.dispatch('login', '')
    },
    changeMsg () {
      this.msg = this.getUserInfo ? this.getUserInfo.name : 'null'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

当vuex中没有用户的name时,点击改变信息将会返回null。而登录后改变了vuex的状态,这时候点击改变信息按钮,将会返回vuex中的用户名
在这里插入图片描述

vuex拓展

在这里你会发现一个问题,就是当你刷新页面以后,vuex里存储的数据就都没了,我们有两种方法可以解决,一种是存储在浏览器缓存里面,一种是重新请求接口获取,甚至可以把这两种方法合起来。这里我用vuex-persistedstate插件帮我存储。


3、axios

npm install axios -g或者用yarn也行。
对于请求,我们需要做一些拦截和配置。例如发送前所需的配置以及加密,发送后的拦截,常见的600无登录跳转登录页处理,默认的错误处理等等。我们创建一个utils文件夹,存放各种工具,然后创建一个request.js来处理axios。

import axios from 'axios'
import store from '../store'

const reqArr = []
const reqStart = (config) => (config.loading && reqArrProxy.push(config))
const reqEnd = (res) => reqArrProxy.pop()

const reqArrProxy = new Proxy(reqArr, {
  get: function (target, key, receiver) {
    return Reflect.get(target, key, receiver)
  },
  set (target, key, value, receiver) {
    if (key === 'length' && value === 0) {
      store.commit('setAppLoading', { loading: false })
    } else {
      store.commit('setAppLoading', { loading: true })
    }
    return Reflect.set(target, key, value, receiver)
  }
})

// 创建一个AXIOS实例 (请求不同服务器地址或超时时长等等可以创建不同的实例)
const request = axios.create({
  withCredentials: true, // 跨域请求时发送cookies
  timeout: 1000 * 30 // 请求超时
})

// config 代表发起请求的参数的实体
request.interceptors.request.use(
  config => {
    reqStart(config)
    config.baseURL = config.baseURL || window.baseURL || 'api'
    config.headers['Content-Type'] = 'application/json;charset=UTF-8'
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 请求到结果的拦截处理
request.interceptors.response.use(
  response => {
    reqEnd(response)
    const { data } = response
    if (data.code === '200' || data.code === '911') {
      return data
    } else if (data.code === '600') {
      // 未登录或登录过期
      // 进行返回登录页的操作
      return false
    } else {
      // 其他错误操作
      return false
    }
  },
  error => {
    // 请求错误需要自行处理
    console.info(error)
    reqEnd(error)
    if (error.config.isHandleError && error.config.isHandleError === true) {
      return error
    } else {
      return false
    }
  }
)

export default request

之后引入他就能够使用了

import request from "@/utils/request.js"

export const loginUser = (data) => request({
  url: "url",
  method: "POST",
  data
})

总结

全家桶大概就到这里了,有什么写错的地方接受批评,有补充的地方大家一起交流交流。漫漫前端路,大家一起努力吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值