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 [email protected] [email protected] axios element-ui --save
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
图片如果未添加会编译报错,找一张图片放上去或者删除图片放入自己的文字即可。
src/
目录下找到并打开 App.vue
文件,用以下内容直接覆盖现有内容:<template>
<div id="app">
<router-view>router-view>
div>
template>
<script>
export default {
name: 'App'
}
script>
是 Vue Router 提供的组件,用于在 Vue 应用中展示当前路由对应的组件内容。它作用类似于一个占位符,它定义了一个容器,在路由切换时,会根据不同的路由匹配,动态渲染对应的组件内容。
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)
将滚动条位置重置为顶部,以确保每次路由改变时都会回到顶部。
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')
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
中的方法来修改状态。
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')
在 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
对象作为参数,使用FormData
将file
对象附加到请求体中,并将请求发送到指定的url
。同样,该方法也返回一个Promise
对象,在上传成功时将响应数据作为resolved
状态返回,失败时将错误作为rejected
状态返回。
这些封装的请求方法可以方便地在应用中进行网络请求,并对请求和响应进行统一的处理。
通过下面的方式便可引入调用:
import { methodPost } from '@/api'
methodPost('接口地址', {}).then((res) => {
// 请求成功
}).catch((err) => {
// 请求失败
})
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')
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 组件来显示了。
点击下载步骤 1-7 配置完成的完整 Demo