第六步 Vue2 集成全家桶 vue-router vuex axios 和 element-ui

介绍

  • Vue Router
    是Vue.js官方提供的路由管理库,用于实现前端应用的路由功能。它可以将前端路由映射到Vue组件,实现页面的切换和导航等功能。Vue Router支持嵌套路由、路由参数、路由守卫等高级功能,能够满足各种复杂的路由需求。

  • Vuex
    是Vue.js官方提供的状态管理库,用于集中管理应用程序中的状态。它将应用程序中的数据存储在一个全局的store中,并提供了一些API来改变状态和获取状态。Vuex的核心概念包括state(存储应用程序的状态)、mutations(用于改变状态的方法)、actions(用于异步操作和提交mutations的方法)等。通过Vuex,可以实现状态在组件间的共享和管理,提供了更好地组织和协调组件间的通信和数据流动。

  • Axios
    是一个基于Promise的HTTP客户端库,用于在浏览器和Node.js中发起HTTP请求。它提供了一系列的API来发送请求、拦截请求和响应、处理错误等。Axios支持浏览器的XMLHttpRequest和Node.js的http模块,提供了更简洁、易用和可配置的接口。在Vue.js开发中,Axios通常用于与后端API进行通信,发送异步请求获取数据。

  • Element UI
    是一套基于 Vue.js 的桌面端 UI 组件库,它提供了丰富的可复用组件,方便开发者快速构建现代化、美观的 Web 应用程序。

安装

项目根目录下打开终端或命令行工具,运行以下命令来安装相关依赖包:

npm install vue-router@3.0.1 vuex@3.0.1 axios element-ui --save

vue-router

1. 在 src/ 目录下新建 views 目录。在此目录中新建一个名为 404.vue 的文件,并添加以下内容:
<template>
  <div class="error">
    <div class="imgWrapper">
      <img src="@img/errorPages/404.png" alt="404">
    </div>
  </div>
</template>

<style lang="less" scoped>
  .error {
    display: grid;
    place-items: center;
    height: 100vh;
  }
</style>

404.png 图片如果未添加会编译报错,找一张图片放上去或者删除图片放入自己的文字即可。

2. 在 src/ 目录下找到并打开 App.vue 文件,用以下内容直接覆盖现有内容:
<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<router-view> 是 Vue Router 提供的组件,用于在 Vue 应用中展示当前路由对应的组件内容。它作用类似于一个占位符,它定义了一个容器,在路由切换时,会根据不同的路由匹配,动态渲染对应的组件内容。

3. 在 src/ 目录下新建 router 目录。在此目录中新建一个名为 index.js 的文件,并添加以下内容:
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const pages = [
  {
    path: '/home',
    component: (resolve) => require(['@/components/HelloWorld.vue'], resolve)
  },
  {
    path: '/errorPage/404',
    component: (resolve) => require(['@/views/404.vue'], resolve)
  }
]

const router = new VueRouter({
  routes: [
    // 默认路由
    {
      path: '/',
      redirect: '/home'
    },
    // 页面路由
    ...pages,
    // 没有匹配的路由重定向到404页面
    {
      path: '*',
      redirect: '/errorPage/404'
    }
  ]
})

// 路由跳转前
router.beforeEach((to, from, next) => {
  // 可用于拦截导航并执行一些操作,例如验证用户身份、权限控制等。
  next()
})

// 路由跳转后
router.afterEach((to, from) => {
  window.scrollTo(0, 0) // 每次路由改变滚动条都回到顶部
})

export default router

这段代码是一个基于Vue Router的路由配置。

以下是对代码的解释:

  • Vue.use(VueRouter) 是通过Vue.use()方法来全局注册 Vue Router 插件,使得我们可以在 Vue 实例中使用 Vue Router 的功能。

  • const pages = [... ] 定义了一个数组变量pages,用于存储页面路由配置。每个页面路由配置以对象表示,对象中包括一个路由路径path和对应的组件component
    这里使用了一个按需加载的方式,可以在需要时异步加载组件:
    (resolve) => require(['xxx.vue'], resolve) 表示在路由激活时动态加载组件,并将解析后的组件传递给resolve回调函数。换言之,当访问对应的路由路径时,路由系统会动态加载组件并渲染到匹配的路由视图中。

  • const router = new VueRouter({...}) 是创建一个 Vue Router 实例,并配置其中的路由。在这里,路由配置包含三部分:
    默认路由:将根路径/重定向到/home路径。
    页面路由:使用展开运算符...pages数组中的页面路由配置添加到路由配置中。
    没有匹配的路由重定向到404页面:当用户访问不存在的路径时,将自动重定向到/errorPage/404路径。

  • router.beforeEach((to, from, next) => {...}) 是路由跳转前的钩子函数。在其中可以执行一些操作,例如验证用户身份、权限控制等。在这段代码中,钩子函数逻辑为空,即不执行任何操作。

  • router.afterEach((to, from) => {...}) 是路由跳转后的钩子函数。在这里,使用window.scrollTo(0, 0)将滚动条位置重置为顶部,以确保每次路由改变时都会回到顶部。

4. 打开 src/main.js 文件,挂载到Vue实例:
import router from './router'

new Vue({
  router
})

修改后的代码如下:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import '@css/index.less'

// 禁用生产环境提示
Vue.config.productionTip = false

new Vue({
  router,
  render: (h) => h(App)
}).$mount('#app')

vuex

1. 在 src/ 目录下新建 store 目录。在此目录中新建一个名为 index.js 的文件,并添加以下内容:
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 本地存储-修改
const storageSet = (key, value) => {
  localStorage.setItem(key, JSON.stringify(value))
}

// 本地存储-获取
const storageGet = (key) => {
  return JSON.parse(localStorage.getItem(key))
}

export default new Vuex.Store({
  // 数据源 使用:this.$store.state.xxx
  state: {
    user: {} // 用户信息
  },
  // 派生数据 使用:this.$store.getters.xxx
  getters: {
    // 获取当前-用户对象
    GET_USER(state) {
      state.user = storageGet('STORE_USER') || {}
      return state.user
    }
  },
  // 更改数据-同步 使用:this.$store.commit('xxx', data)
  mutations: {
    // 保存当前-用户对象
    SET_USER(state, data) {
      state.user = data
      storageSet('STORE_USER', data)
    }
  },
  // mutations装饰器-异步
  actions: {
  }
})

这段代码是一个基于 Vue 和 Vuex 的状态管理工具的配置。以下是对代码的解释:

  • Vue.use(Vuex) 是通过Vue.use()方法来全局注册 Vuex 插件,使得我们可以在 Vue 实例中使用 Vuex 的功能。

  • const storageSet = (key, value) => {...} 和 const storageGet = (key) => {...} 是两个辅助函数,用于将数据存储在本地的localStorage中,并且可以在需要时获取该数据。

  • new Vuex.Store({...}) 是创建一个 Vuex 的 Store 实例。这个实例将包含 Vuex 的核心架构和一些选项来定义应用程序的状态管理。

  • state 属性用于定义仓库store的初始状态,其中user是一个空对象,用于存储用户信息。

  • getters 属性是派生状态的计算属性,允许我们从仓库的数据中获取一些衍生状态。GET_USER getter用于获取当前用户对象。

  • mutations 属性定义了一些同步方法,用来修改仓库的状态。在这里,只有一个SET_USER mutation方法用于保存当前用户对象,并同时将其存储在本地localStorage中。

  • actions 属性中可以定义一些异步方法,在需要时执行异步操作,并最终调用mutations中的方法来修改状态。

2. 打开 src/main.js 文件,挂载到Vue实例:
import store from './store'

new Vue({
  store
})

修改后的代码如下:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@css/index.less'

// 禁用生产环境提示
Vue.config.productionTip = false

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

axios

src/目录下新建 api 目录。在此目录中新建一个名为 index.js 的文件,并添加以下内容:

import Vue from 'vue'
import axios from 'axios'

// 设置超时时长
axios.defaults.timeout = '60000'

// request拦截器
axios.interceptors.request.use((config) => {
  return config
}, (error) => {
  return Promise.reject(error)
})

// responese拦截器
axios.interceptors.response.use((res) => {
  return res
}, (error) => {
  return Promise.reject(error)
})

/**
 * 设置请求header
 * @param {Object} headers
 */
const setHeader = (headers) => {
  for (const key in headers) {
    axios.defaults.headers[key] = headers[key]
  }
}

/**
 * POST请求
 * @param {String} url 地址
 * @param {Object} params 参数
 * @param {Object} headers headers
 */
export const methodPost = (url, params, headers = {}) => {
  return new Promise((resolve, reject) => {
    setHeader(headers)
    axios.post(url, params).then((response) => {
      resolve(response.data)
    }).catch((error) => {
      reject(error)
    })
  })
}

/**
 * 文件上传
 * @param {String} url 地址
 * @param {File} file 文件
 */
export const methodUpload = (url, file) => {
  return new Promise((resolve, reject) => {
    const formData = new FormData()
    formData.append('file', file)
    formData.append('currentDate', Date.now())
    axios.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    }).then((response) => {
      resolve(response.data)
    }).catch((error) => {
      reject(error)
    })
  })
}

这段代码是一个配置了axios 网络请求库的请求拦截器和响应拦截器,以及一些封装的请求方法。
以下是对代码的解释:

  • axios.defaults.timeout = '60000' 设置了axios的默认超时时长为60秒。

  • axios.interceptors.request.use((config) => {...}, (error) => {...}) 是请求拦截器,用于在发送请求之前对请求进行一些处理。在这里,通过config来获取请求配置,可以对请求进行一些修改或处理,然后返回修改后的请求配置。如果在请求发送过程中发生错误,将会被catch到并返回一个rejected状态的Promise

  • axios.interceptors.response.use((res) => {...}, (error) => {...}) 是响应拦截器,用于在接收到响应后对响应进行一些处理。在这里,通过res来获取响应数据,可以对响应进行一些修改或处理,然后返回修改后的响应数据。如果在响应过程中发生错误,将会被catch到并返回一个rejected状态的Promise

  • const setHeader = (headers) => {...} 是一个工具函数,用于设置请求的header。将传入的header参数遍历,并将其设置到axios的默认headers中。

  • export const methodPost = (url, params, headers = {}) => {...} 是一个封装的POST请求方法。该方法接收一个url、一个params对象和一个可选的headers对象作为参数,使用axios.post方法发送POST请求,并返回一个Promise对象。如果请求成功,将会将响应数据作为resolved状态返回;如果请求失败,将会将错误作为rejected状态返回。

  • export const methodUpload = (url, file) => {...} 是一个文件上传方法。该方法接收一个url和一个file对象作为参数,使用FormDatafile对象附加到请求体中,并将请求发送到指定的url。同样,该方法也返回一个Promise对象,在上传成功时将响应数据作为resolved状态返回,失败时将错误作为rejected状态返回。

这些封装的请求方法可以方便地在应用中进行网络请求,并对请求和响应进行统一的处理。

通过下面的方式便可引入调用:

import { methodPost } from '@/api'

methodPost('接口地址', {}).then((res) => {
  // 请求成功
}).catch((err) => {
  // 请求失败
})

element-ui

1. 打开 src/main.js 文件,挂载到Vue实例:
import Element from 'element-ui'
import "element-ui/lib/theme-chalk/index.css"

// Element挂载到Vue
Vue.$message = Element.Message
Vue.use(Element)

修改后的代码如下:

import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import App from './App.vue'
import router from './router'
import store from './store'
import '@css/index.less'

// 禁用生产环境提示
Vue.config.productionTip = false

// Element挂载到Vue
Vue.$message = Element.Message
Vue.use(Element)

new Vue({
  router,
  store,
  render: (h) => h(App)
}).$mount('#app')
2. 打开之前创建的 src/api/index.js 文件,找到以下代码块:
// responese拦截器
axios.interceptors.response.use((res) => {
  return res
}, (error) => {
  return Promise.reject(error)
})

在添加 Vue.$message.error(error.toString())代码, 如下:

// responese拦截器
axios.interceptors.response.use((res) => {
  return res
}, (error) => {
  Vue.$message.error(error.toString())
  return Promise.reject(error)
})

这样响应时的错误信息就能通过 Element 的 Message 组件来显示了。

更多组件的使用方式,可到 element-ui 官方文档 中查看。



框架搭建整体流程

点击下载步骤 1-7 配置完成的完整 Demo

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

推荐阅读更多精彩内容