从零开始搭建vue项目
一、使用vue-cli搭建项目
$ npm install -g vue-cli
注意:在mac执行该命令会报错
改用管理员权限执行以下命令即可
$ sudo npm install -g vue-cli
$ vue init webpack tcloud
$ cd tcloud
$ npm run dev
完成了利用脚手架创建并启动一个vue的项目,可访问http://localhost:8080 看到下图界面说明项目启动成功。
二、引入vuex并实现数据持久化
1.首先对目录结构调整后如下:
- assets 前端静态资源 包括图片、样式、和js插件
- components 可复用的组件
- lang 国际化/多语言环境配置文件 cn.js 业务相关文本翻译-简体 tw.js 业务相关文本翻译-繁体
- pages 业务组件
- router 路由配置文件
- vuex store相关配置
- app.vue 根组件
- main.js 入口文件
2.安装vuex
$ npm install vuex --save
3.创建store文件
import vue from 'vue' import vuex from 'vuex' vue.use(vuex) const state = { test: 1, lang: 'cn' } const mutations = { add: (state, data) => { state.selectgoods.push(data) state.test++ } } const actions = { addtest: ({ commit }, data) => { commit('add', data) } } export default new vuex.store({ state, mutations, actions })
4.在入口文件main.js中引入store
import store from './store/store'
// 并挂载到根实例中
new vue({ el: '#app', store, router, components: { app }, template: '<app/>' })
5.vuex-persistedstate实现数据持久化
vuex可以进行全局的状态管理,但刷新后刷新后数据会消失
- 安装
$ npm install vuex-persistedstate --save
- 在store.js中引入及配置
import createpersistedstate from "vuex-persistedstate" const store = new vuex.store({ // ... plugins: [createpersistedstate({ storage: window.sessionstorage, // 不设置默认存储到localstorage reducer(val) { return { // 指定需要持久化的state lang: val.lang } } })]
- 生效后在浏览器storage中展示效果
三、实现多语言环境-简繁体转换
1.安装vue-i18n
$ npm install vue-i18n --save
2.准备业务相关文本的翻译文件
3.创建vuei18n 实例
代码如下
import vue from 'vue' import vuei18n from 'vue-i18n' import cnlocale from './cn' import twlocale from './tw' import store from '@/vuex/store' vue.use(vuei18n) const i18n = new vuei18n({ locale: store.state.lang || 'cn', messages: { cn: { ...cnlocale }, tw: { ...twlocale } } }) export default i18n
4.在main.js中引入vue-i18n
import i18n from './lang/index' // 把 i18n 挂载到 vue 根实例上 new vue({ el: '#app', i18n, axios, store, router, components: { app }, template: '<app/>' })
5.引用
// 在html模板中引用 <van-button @click="logout" type="default">{{$t('log.out')}}</van-button> // 在 js 模板中使用 this.$t('log.in')
6.解决切换语言后刷新界面时出现一瞬间白屏的问题
利用在app.vue的<router-view></router-view>加上v-if属性和provide/inject,具体代码实现如下:
// app.vue文件 <template> <div id="app"> <router-view v-if="isalive" /> </div> </template> <script> export default { name: 'app', provide () { return { reload: this.reload } }, data () { return { isalive: true } }, methods: { reload () { this.isalive = false this.$nexttick(function () { this.isalive = true }) } } } </script>
接下来在需要刷新的组件中注入reload函数
<template> <button @click="refresh"></button> </template> <script> export default{ name: 'refresh', inject: ['reload'], methods: { refresh () { this.reload() } } } </script>
四、实现登录拦截
1.路由拦截
首先在定义路由的时候就需要多添加一个自定义字段requireauth
,用于判断该路由的访问是否需要登录。如果用户已经登录(token存在),则顺利进入路由, 否则就进入登录页面。
const routes = [ { path: '/', name: '/', component: index }, { path: '/repository', name: 'repository', meta: { requireauth: true, // 添加该字段,表示进入这个路由是需要登录的 }, component: repository }, { path: '/login', name: 'login', component: login } ];
定义完路由后,我们主要是利用vue-router
提供的钩子函数beforeeach()
对路由进行判断
router.beforeeach((to, from, next) => { if (to.meta.requireauth) { // 判断该路由是否需要登录权限 if (store.state.token) { // 通过vuex state获取当前的token是否存在 next(); } else { next({ path: '/login', query: {redirect: to.fullpath} // 将跳转的路由path作为参数,登录成功后跳转到该路由 }) } } else { next(); } })
每个钩子方法接收三个参数:
- to: route: 即将要进入的目标 路由对象
- from: route: 当前导航正要离开的路由
- next: function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
- next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
- next(false): 中断当前的导航。如果浏览器的 url 改变了(可能是用户手动或者浏览器后退按钮),那么 url 地址会重置到 from 路由对应的地址。
- next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航
2.axios拦截器
当前token失效了,但是token依然保存在本地,这时候你去访问需要登录权限的路由时,实际上应该让用户重新登录。 这时候就需要结合 http 拦截器 + 后端接口返回的http 状态码来判断
// http request 拦截器 axios.interceptors.request.use( config => { if (store.state.token) { // 判断是否存在token,如果存在的话,则每个http header都加上token config.headers.authorization = `token ${store.state.token}`; } return config; }, err => { return promise.reject(err); }); // http response 拦截器 axios.interceptors.response.use( response => { return response; }, error => { if (error.response) { switch (error.response.status) { case 401: // 返回 401 清除token信息并跳转到登录页面 store.commit(types.logout);
path: 'login', query: {redirect: router.currentroute.fullpath} }) } } return promise.reject(error.response.data) // 返回接口返回的错误信息 });
上一篇: JavaScript 拖拽翻页效果代码
下一篇: DDL数据库对象管理