当前位置: 首页 > news >正文

一般网站后台都是哪里做建设银行网站注册

一般网站后台都是哪里做,建设银行网站注册,网站建设的搜索功能,wordpress修改鼠标文章目录 1. Vue.js 项目创建1.1 vue-cli 安装1.2 使用 vue-cli 创建项目1.3 文件/目录介绍1.4 启动 Web 服务 2. 集成 Vue Router 前端路由2.1 Vue Router 是什么2.2 集成 Vue Router 方法2.3 使 Vue Router 生效 3. 集成 Vuex 组件3.1 Vuex 是什么3.2 集成 Vuex 方法3.3 使 V… 文章目录 1. Vue.js 项目创建1.1 vue-cli 安装1.2 使用 vue-cli 创建项目1.3 文件/目录介绍1.4 启动 Web 服务 2. 集成 Vue Router 前端路由2.1 Vue Router 是什么2.2 集成 Vue Router 方法2.3 使 Vue Router 生效 3. 集成 Vuex 组件3.1 Vuex 是什么3.2 集成 Vuex 方法3.3 使 Vuex 生效3.4 Vuex 使用方式3.4.1 设置 state 值3.4.2 获取 state 值 4. 集成 ElementUI 组件4.1 Element UI 是什么4.2 集成 Element UI 方法4.3 使 ElementUI 生效 5. 设计前端项目目录结构6. layout 设计6.1 Header 部分设计6.2 Side Menu 部分设计6.3 Main Content 部分设计6.3.1 面包屑功能 6.4 Footer 部分设计 7. 集成 Axios 组件7.1 Axios 是什么7.2 集成 Axios 方法7.3 Axios 初始化 8. 权限拦截管理设计9. 菜单后台加载设计10. 前端路由设计11. 登录入口设计12. Mock 数据设计12.1 Mockjs 集成方法12.2 启用 Mockjs 服务 13. 前端代理服务 1. Vue.js 项目创建 Vue.js 是一套用于构建用户界面的渐进式框架。在使用 Vue.js 框架之前如果您还不能灵活的使用 HTML、CSS、JavaScript 语言如果能抽空预习一下 HTML、CSS、JavaScript 这几门语言的用法这样更利于您继续学习 Vue.js。 vue-cli 是开发 Vue.js 的一种官方标准工具我们通过 vue-cli 4.1.2 版本关于 vue-cli 版本问题学习或者技术选型没有历史包袱时建议使用最新版4.1.2 是本场 Chat 时最新版本来创建项目当然没有 vue-cli 也能够使用 Vue.js 开发您的项目但使用 vue-cli 可以更方便您使用 Vue.js 开发项目。 1.1 vue-cli 安装 $ yarn global add vue/cliyarn Facebook、Google 等公司推荐的一款 JavaScript 包管理工具类似于 Java 界的 Maven、Gradle。当然您也可以继续使用 NPM 工具来管理 JavaScript 包。关于 Yarn 和 NPM 的对比不在此处介绍有兴趣的朋友可以在网上搜索 NPM 了解其用法。 global 表示将需要下载的 JavaScript 包存储在全局目录中。这样我们就可以在命令行中直接使用 JavaScript 安装包内的程序。如 Vue 命令就来源于 vue/cli 包。 vue/cli scoped packages。 后边跟随的 Vue 是 scopecli 是包名。意思是下载 Vue 这个组织下 cli 包。 1.2 使用 vue-cli 创建项目 我们使用 vue-cli 创建名称为 web-demo 的项目。操作命令如下所示 $ vue create web-demo在创建项目的过程中中途有一个选项操作如下所示 Vue CLI v4.1.2 ? Please pick a preset: (Use arrow keys) ❯ default (babel, eslint) Manually select features 默认选择第一项。安心等待项目创建完成。当依赖文件下载完成后进入项目所在目录目录内文件如下所示 README.md babel.config.js node_modules package.json public src yarn.lock1.3 文件/目录介绍 README.md 项目介绍说明信息。 babel.config.js Babel 是一个工具链主要用于将 ECMAScript 2015 版本的代码转换为向后兼容的 JavaScript 语法以便能够运行在当前和旧版本的浏览器或其他环境中。babel.config.js 就是 babel 编辑器的配置文件。通常情况下无需过多关注。 node_modules 项目依赖包目录里边存储了当前 Web 项目依赖的 JavaScript 包。 package.json 项目配置信息包括依赖包信息。 public 公共文件目录如 HTML 文件、图片等。 src 当前项目开发的 Vue 代码。 yarn.lock Yarn 工具自动生成的文件里边包含每个依赖文件的确切版本等信息。注意 package.json 中也指定了项目依赖 JavaScript 包的版本信息但 package.json 中可能对于同一个 JavaScript 包指定了多个版本范围选择而 yarn.lock 存储的是确切版本信息。 1.4 启动 Web 服务 下边来启动 Web 服务操作步骤如下所示 $ cd web-demo$ yarn serveWeb 服务启动后打开浏览器输入 Web 服务地址。 http://localhost:8080/8080 是 Web 服务的默认端口如果在启动 Web 服务的时候恰巧 8080 端口已经被占用那么 Web 服务会默认启用 8081 端口。Web 服务启动成功后至此Vue.js 项目便创建完成。 2. 集成 Vue Router 前端路由 2.1 Vue Router 是什么 Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成让构建单页面应用SPA变得易如反掌。 为什么要引入 Vue Router 呢 SPAsingle page application单一页面应用程序即整个 Web 只有一个完整的页面这个页面由非常多个组件组成。当 Web 加载时不会一次性显示整个页面所有的组件而是按需显示局部内容也就是部分组件。SPA 页面中这么多个组件究竟哪个组件要显示哪个组件要隐藏。为了解决这个问题我们引入一种前端路由的工具 Vue Router。 我们给每个组件定义一个 URL从而形成一张前端路由表。当页面上发起请求跳转到指定 URL 时这个 URL 对应的组件以及这个组件引用的组件就会被显示出来不在这个范围内的组件就会被隐藏。 所以前端路由通俗地讲就是给组件取个名字这个名字就是 URL。当页面上发生 URL 跳转时显示这个 URL 对应的组件以及这个组件引用的组件。 { path: /user/details, component: User }上边例子是前端路由的简单定义。path 对应的便是 URLcomponent 对应的便是组件。当页面上发生 /user/details 跳转时便会显示 User 组件。 2.2 集成 Vue Router 方法 首先进入我们在第一步中创建的项目 web-demo 目录中。然后使用 Yarn 工具在线下载 vue-router 包执行下边命令如下所示 yarn add vue-routervue-router 包下载完成后将会被存储到当前项目 node_modules 目录下。 2.3 使 Vue Router 生效 Vue Router 引入项目后使用 Vue.use(plugin) 方法添加插件。在 main.js 内导入 Vue Router 对象关联前端路由组件。 // main.js import Vue from vue import VueRouter from vue-router; import router from /router/router.jsVue.use(VueRouter);new Vue({router,store,render: h h(App), }).$mount(#app) 3. 集成 Vuex 组件 3.1 Vuex 是什么 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。SPA 由多个组件组成组件与组件之间需要共享状态时怎么来实现呢浏览器上常见的几种存储方式如下所示 HTML5 的 localStorage。主要通过本地存储的方式存储数据浏览器关闭后数据仍在在本地。HTML5 的 sessionStorage。主要通过会话保存数据当浏览器关闭后数据丢失。Cookies。每次 HTTP 请求时都会将 Cookies 信息发送给服务端。Cookies 存储大小有限制否则每次 HTTP 请求发送给服务器的数据会占用过多带宽。Vuex 通过内存存储数据。页面刷新时state 状态丢失。 localStorage、sessionStorage 更多的时候用于页面之间数据传递。Cookies 更多用于存储 Web 前端与后台服务端之间的数据。Vuex 更适合于组件之间的状态管理。上述几种存储方式可在一个项目中同时存在主要取决于需求不同的场合选用不同的数据存储方式。 Vuex 模块核心概念如下所示 State 存储的状态变量Getter 获取状态变量Mutation 修改状态变量的值Action 提供入口方法修改存储状态的值Module 状态模块化管理即我们将几百个状态分布到多个文件中每个文件中对应的是一个模块。 修改状态的流程action - mutation - state 修改状态。 获取状态的流程getter - state 获取状态。 3.2 集成 Vuex 方法 使用 Yarn 工具在线下载 Vuex 包下载命令如下所示 yarn add vuexVuex 包下载完成后将会被存储到当前项目 node_modules 目录下。 3.3 使 Vuex 生效 Vuex 组件引入项目后使用 Vue.use(plugin) 方法添加插件。在 main.js 导入 Vuex 的对象来关联状态管理组件。 // main.js import Vue from vue import store from /store/index.js;Vue.use(Vuex);new Vue({router,store,render: h h(App), }).$mount(#app) 3.4 Vuex 使用方式 3.4.1 设置 state 值 this.$store.dispatch({action 名字},{state 新的值})第一个参数是 action 中定义的方法。第二个参数是 state 新的值。如我们需要调整 height 这个变量的值为 100px。假设 action 中定义了一个方法 autoHeight。则使用命令如下所示 this.$store.dispatch(authHeight, 100px)3.4.2 获取 state 值 通过 mapGetters 方法获取到 state 中 height 这个变量或者从 data 中读取 clientHeight 变量。 import { mapGetters } from vuex;export default {computed: {// 从 vuex 中获取浏览器高度实时更新保持左侧菜单栏高度与浏览器高度一致保持垂直方向 100% 高度...mapGetters([height])},data(){return {// 从 vuex 读取 state 状态的第二种方式clientHeight: this.$store.getters.height}}, }4. 集成 ElementUI 组件 4.1 Element UI 是什么 Element一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。这个库集成了大量漂亮的组件如选择框组件、弹框组件、输入框组件、按钮组件等等。集成了 ElementUI 后可以方便我们更快的开发出更漂亮的 Web 页面。 4.2 集成 Element UI 方法 使用 Yarn 工具在线下载 element-ui 包下载命令如下所示 yarn add element-uielement-ui 包下载完成后将会被存储到当前项目 node_modules 目录下。 4.3 使 ElementUI 生效 使用 Vue.use(plugin) 方法添加插件将 ElementUI 添加到项目中。 import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css;Vue.use(ElementUI, {size: small // set element-ui default size });5. 设计前端项目目录结构 项目目录结构 -- public -- src ---- api ---- assets ---- components ------ layout ------ pagination ------ Breadcrumb.vue ---- layout ------ BaseLayout.vue ------ EmptyRouter.vue ---- mock ------ mock.js ------ data ---- router ---- store ---- utils ---- views ---- App.vue ---- main.js ---- permission.js6. layout 设计 在前端页面开发时第一步先规划整体布局如将整个 Web 划分为几个大的区域每个区域负责特定的显示。我们将后台管理系统划分为如下四个部分分别是 Header 头部信息显示栏Side Menu 左侧菜单显示栏目Main Content 内容显示区域Footer 页脚显示信息 6.1 Header 部分设计 头部显示栏主要显示整个系统重要信息如 LOGO 信息、主菜单信息、登录用户信息以及其他重要信息。实现 Header 部分代码如下所示 templatediv classwisrc-headerel-rowel-col :span24!-- Logo 显示--Logo /!--一级主菜单区域--MainMenu /!-- 右侧工具栏包含用户登录信息 --Tools //el-col/el-row/div /templatescript import Logo from /components/layout/Logo.vue; import MainMenu from /components/layout/MainMenu.vue; import Tools from /components/layout/Tools.vue;export default {name: WisrcHeader,components: {Logo,MainMenu,Tools} }; /scriptstyle scoped .wisrc-header {height: 60px;width: 100%;text-align: left;padding: 0px;line-height: 60px;background-color: rgb(84, 92, 100);color: #ffffff; } /style 6.2 Side Menu 部分设计 Side Menu 部分由两个组件组成分别是 Side.vueSideChildrenMenu.vue Side 组件主要实现左侧菜单栏主要布局建构一个紧靠浏览器左侧且横向宽度为 260 像素垂直方向自适应浏览器高度的区域。布局构建完成后通过嵌套 SideChildrenMenu 组件显示具体的菜单信息。Side 组件的代码如下所示 templatediv classwisrc-sideel-menudefault-active2:style{height: (height-60)px}classwisrc-side-menubackground-color#545c64text-color#fffactive-text-color#ffd04bel-scrollbar styleheight: 100%SideChildrenMenu v-bind:childrensideMenuList //el-scrollbar/el-menu/div /templatescriptimport { mapGetters } from vuex; import { getMenu } from /api/menu.js; import SideChildrenMenu from /components/layout/SideChildrenMenu.vue;export default {name: wisrc-side,computed: {// 从 vuex 中获取浏览器高度实时更新保持左侧菜单栏高度与浏览器高度一致保持垂直方向 100% 高度...mapGetters([height])},components: {SideChildrenMenu},data() {return {sideMenuList: [],};},methods: {openPage(url) {this.$router.push(url);}, },mounted(){// 定时获取后台菜单信息getMenu().then(resp {this.sideMenuList resp})} }; /scriptstyle scoped .wisrc-side {width: 260px;height: 100%;float: left;text-align: left; } .wisrc-side-menu {overflow-y: auto; } .el-scrollbar__wrap {overflow-x: hidden; } /styleSideChildrenMenu 组件用来渲染树形层级菜单。树形菜单采用递归渲染的方式实现即在 SideChildrenMenu 组件内嵌套使用组件自身从而实现递归渲染树形菜单的效果。Vue.js 中组件采用递归时该组件一定要设置 name 属性。否则递归无效。 SideChildrenMenu 组件的代码实现如下所示 template divdiv v-for(item, index) in children :keyindex!-- 目录菜单 --el-submenu v-ifitem.menuType 1 :indexindex!-- 目录菜单名称 --template slottitlei :classitem.iconClass/ispan{{item.menuName}}/span/template!-- 目录下子菜单 --SideChildrenMenu v-bind:childrenitem.children //el-submenu!-- 叶子菜单 --el-menu-item v-ifitem.menuType 2 :indexitem.menuId clickopenPage(item.path){{item.menuName}}/el-menu-item/div /div /templatescript export default {props: [children],name: SideChildrenMenu,methods: {openPage(url) {this.$router.push(url);}} } /script自此左侧菜单组件开发完毕我们通过 Axios 组件向后台服务发起请求获取左侧菜单栏信息。菜单信息数据格式见下边 9.1 节。 6.3 Main Content 部分设计 Main Content 用来渲染具体的业务信息。例如当我们在左侧菜单栏点击打开“字段管理”页面字段管理页在前端路由表中配置了相应的组件 Column.vue。也就是点击“字段管理”页面将会打开 Column.vue 组件以及这个组件中引入的其他组件。那问题来了 待显示的组件在哪里显示呢 答案就是 router-view/router-view。 我们在 Main Content 中加入了 router-view/router-view DOM 元素。当左侧菜单栏点击打开“字段管理”页面后其对应的组件 Column.vue 将会在 Main Content 中 router-view/router-view DOM 元素内显示。 templatedivel-cardBreadcrumb/Breadcrumb/el-carddiv classwisrc-content :style{height: (height-138)px}section styleoverflow: auto !importanttransition namefade modeout-inkeep-aliveel-cardstyleoverflow: auto !important; text-align: left:style{height: (height-140)px}router-view/router-view/el-card/keep-alive/transition/section/div/div /template script import { mapGetters } from vuex; import Breadcrumb from /components/Breadcrumb;export default {name: WisrcContent,components: {Breadcrumb},computed: {...mapGetters([height])} }; /scriptstyle scoped .wisrc-content {margin-left: 260px;border: #f6f3f3 solid 1px;background-color: #f6f3f3;overflow-y: auto;padding: 6px 6px; } /style 通过使用 router-view/router-view 渲染待刷新显示的内容实现了局部页面刷新的功能。如果没有 router-view/router-view那么前端路由还能渲染出来吗 答案是不行router-view 就像是个容器没有容器待显示的组件无处安放。 6.3.1 面包屑功能 此处的面包屑不是吃了一半的面包渣渣。面包屑导航Breadcrumbs是一种基于网站层次信息的显示方式。前端路由往往由多层路由组成在页面跳转过程中可能点着点着就不知道现在处于哪个页面中除非每个页面中都设计了标题。引入面包屑导航功能后我们可以很方便的知道当下所在的页面。面包屑实现方式如下所示 templatedivel-breadcrumb separator/el-breadcrumb-item :to{ path: / }首页/el-breadcrumb-itemel-breadcrumb-itemv-for(item,index) in breadcrumb:to{path: item.path}:keyindex{{item.title}}/el-breadcrumb-item/el-breadcrumb/div /template script export default {data() {return {breadcrumb: []};},watch: {$route(to) {// 监听路由跳转每次发生路由跳转时$route 中的值都会发生变化。// to.matched 用来获取匹配成功的路由信息const routers to.matched;this.breadcrumb [];if (routers routers.length 0) {for (let i 1; i routers.length; i) {this.breadcrumb.push({title: routers[i].meta.title,path: routers[i].path});}}}} }; /script前端路由往往由多个层级组成例如现在有如下几个路由信息 /modeller/modeller/column/modeller/column/add 路由 /modeller/column/add 的上一层级路由是 /modeller/column/modeller/column 的上一层路由是 /modeller。 当我们跳转到 /modeller/column/add 时这个组件的所有直系父组件都会被显示。所以 to.matched 返回上边三个值。我们通过这三个返回值便可描绘出路由的层级结构。从而生成面包屑导航。 6.4 Footer 部分设计 Footer 主要显示一些版权信息没有具体的业务逻辑。此部分通常位于系统底部实现代码如下所示 templatediv classwisrc-footerel-footer stylemargin-left: -260px; font-size: 12pxCopyright © 2019 基于 Vue.js ElementUI 后台管理系统/el-footer/div /template script export default {name: WisrcFooter }; /scriptstyle scoped .wisrc-footer {position: fixed;text-align: center;width: 100%;height: 24px;line-height: 24px;bottom: 0px;background-color: #f6f4f4;border-top: #cccccc solid 1px;margin-left: 260px; } /style 7. 集成 Axios 组件 7.1 Axios 是什么 Axios 是一个基于 Promise 的 HTTP 库。HTTP 库提供了浏览器通过 HTTP 协议与后台服务通信的能力。由于网络带宽、后台服务等可能存在不稳定的情况所以有时候请求后台服务很快有时候请求后台服务很慢那当服务请求很慢时前端是否有必要卡着不动等待请求完成呢 如果 Web 页面卡着不动那用户体验一定很糟糕。众所周知 JavaScript 运行在单线程上现在很多语言都讲究多线程、高并发从而实现任务异步处理。那么单线程运行的 JavaScript 怎么来实现异步处理呢主要有两种方法 基于事件监听实现异步处理基于回调函数实现异步处理 基于事件监听实现异步处理存在一定的限制HTML 事件属性有范围如 Window 事件、Form 事件、Keyboard 事件、Mouse 事件、Media 事件。当异步处理的业务不在 HTML 事件属性范围内时将无法使用事件监听来实现异步处理任务。 基于回调函数的异步处理将会吞噬掉 return 值。常见的回调函数使用方法是将需要执行的任务放进 setInterval 或 setTimeout 内来实现任务异步处理。 setTimeout(function(){// 异步处理任务5秒后执行console.log(异步处理任务执行); },5000)setInterval(function(){// 异步处理任务每 5 秒执行一次console.log(每 5 秒钟执行一次异步处理任务); }, 5000)由于 setInterval 和 setTimeout 无法保证执行顺序所以当项目中大量使用回调函数时几十个不知道顺序的任务即将执行不知道哪个先运行哪个后运行谁又在谁前边运行这样对于后期代码维护将会是一场巨大的灾难。 有没有办法既能实现异步处理又能解决顺序问题呢 Axios 库有一个非常有效的特性就是支持 Promise API。使用 Promise 既能实现任务的异步处理又能实现任务的顺序执行。Promise 将多个需要异步处理的任务队列化队列有效的保证了任务执行的有序性。队列中的异步任务顺序执行上一个任务的执行返回值作为下一个异步任务的输入值这样又解决了异步任务吞噬 return 返回值的问题。 但与传统的函数调用使用 return 返回值不同的是Promise 使用 resolve 函数传递正确处理的返回值使用 reject 函数传递错误处理的返回值。举个例子 function asyncDemo(){return new Promise((resolve, reject) {axios.get(/api/demo).then(response {if (response) {// 请求 API 成功将返回结果传递到下一个任务resolve(请求 API 成功);} else {// 请求 API 失败终止异步处理任务reject(请求 API 失败)}})}) }// 运行异步处理任务 asyncDemo().then(response {// 请求成功后上一个任务通过 resolve 函数传递的参数作为当前的输入console.log(response);// 输出信息是 请求 API 成功 }).then(error {// 请求 API 失败上一个任务通过 reject 函数传递的参数作为当前的输入console.log(error)// 输出信息是 请求 API 失败 )7.2 集成 Axios 方法 使用 Yarn 工具在线获取 Axios 包并安装到当前项目中。 yarn add axiosAxios 包下载好之后被存放到当前项目 node_modules 目录中。 7.3 Axios 初始化 项目中使用 Axios 组件请求 API 服务通常需要设置一些统一处理逻辑如异常信息全局处理、token 信息注入等等。那么如何初始化 Axios 组件呢代码示例如下所示 // utils/request.js import axios from axios; import { Message } from element-ui;// 设置远程服务器 IP 地址 // axios.defaults.baseURL process.env.VUE_APP_BASE_API;// 设置请求远程服务器时携带的 token 值信息 // axios.defaults.headers.common[Authorization] AUTH_TOKEN;// 设置 POST 方法请求时默认的请求头信息 axios.defaults.headers.post[Content-Type] application/x-www-form-urlencoded;// 拦截请求发生前可以在此修改请求参数 axios.interceptors.request.use(config {return config; }, error {Message.error(error) })// 拦截请求完成后可以全局处理异常信息 axios.interceptors.response.use(response {if (response response.status 200) {if (response.data.statusCode 200) {// 请求成功return response.data.data;} else {Message.error(response.data.statusMessage)return false;}}Message.error(请求API失败); }, error {Message.error(error)return false; })axios.interceptors.request浏览器向后台服务发起请求之前的处理逻辑。axios.interceptors.response浏览器向后台服务发起请求之后拦截响应值判断是否存在异常如果存在异常拦截处理结果提示请求错误信息。如果请求成功则将请求结果返回给具体的发起请求的函数。 8. 权限拦截管理设计 管理系统通常会针对不同的用户开发不同的权限如超级管理员可以使用管理系统中所有的功能财务部门只能使用财务相关的功能人事部门只能使用员工管理相关功能。为了实现这个需求我们在设计后台管理系统中需要引入权限管理功能。 权限管理通常分为几个形式 API 权限控制数据权限控制前端页面权限控制页面按钮权限控制 API 权限控制 通常 API 的权限管理在后台进行后台服务的入口处会拦截所有的请求当用户发起 API 请求后校验用户是否被授予访问这个 API 的权限用户被授权则允许访问若用户未被授权则用户被拒绝访问。 数据权限控制 数据权限往往基于角色、岗位等维度进行管理。往往针对的是数据的访问控制如哪些角色、岗位的用户能够访问哪些数据。这块的权限控制往往由后台服务控制。 前端页面权限控制 前端页面权限指用户登录系统之后哪些页面可见哪些页面不可见。与数据权限有一点相似之处。通常前端读取后台服务关于用户的权限信息后在渲染菜单的时候将无权限的菜单屏蔽。 页面按钮权限控制 页面按钮控制权限指用户打开页面之后哪些页面按钮可见哪些页面按钮不可见。通常前端读取后台服务关于用户的权限信息后在渲染页面的时候将用户没有权限的按钮屏蔽。 用户在浏览器中打开页面后怎么在每个页面中都加入校验用来拦截判断用户是否有权限访问这个页面呢 在每个页面中加入判断校验用户是否登录全局校验用户是否登录 在每个页面中加入判断用户是否登录的代码显然这种方式对于业务的侵入太大过于笨拙显然不适合。那么怎么设置全局的用户登录校验呢 Vue Router 导航守卫功能。导航守卫主要在如下几个阶段来拦截请求。分别是 beforeEach 全局前置守卫在导航路由触发前拦截beforeRouteUpdatebeforeEnterbeforeRouteEnterbeforeResolveafterEach 上述几种导航守卫我们使用 beforeEach 实现登录校验的判断。实现代码如下所示 import router from /router/router.js; import store from /store/index.js;function checkLogin() {// todo 校验用户是否登录以及用户 token 令牌是否过期return !store.getters.loginStatus; }// param to 到哪里去跳转到哪个路由 // param from 从哪里来从哪个路由跳转过来的 // param next 执行跳转 router.beforeEach((to, from, next) {// 判断用户是否登录// 如果用户已经登录执行 next() 方法// 如果用户未登录则跳转到登录页面if (to.path ! /login checkLogin()) {next({ path: /login })} else {next()}})每次触发路由导航时都会执行这个判断逻辑当发现用户未登录或登录的 token 失效后将会被引导进入登录页面。注意一定要判断目标地址是否为登录地址否则出现死循环。 checkLogin 方法现在只是读取了保存在 vuex 中的用户登录状态这种处理方式并适合生产环境。主要原因是在浏览器执行 F5 刷新时Vuex 存储的状态值会丢失那么用户又要重新登录。 通常生产环境中会将 token 信息存储到 Cookies 中登录状态存储在 Vuex 中判断用户是否登录要结合 Cookies 中的 token 与 Vuex 中的登录状态一起判断。如用户登录状态为 false 时从 Cookies 中读取用户 token 值向后台服务请求验证 token 有效性如果 token 有效则设置 Vuex 中用户登录状态为 true然后跳转到目标路由地址。否则跳转到登录页面。 9. 菜单后台加载设计 字段介绍 menuId 菜单编码每个菜单必须对应一个唯一的菜单编码。menuName 菜单名称。menuType 菜单类型。1 表示目录类型2 表示叶子菜单目录类型菜单表示其下还有菜单信息叶子类型菜单表示达到树底部。path 前端路由值叶子菜单被点击时将会跳转到该路由。目录菜单设置 path 值将会被忽略。iconCLass 目录类型菜单前边的小图标。children 表示目录类型菜单下的子菜单信息。 假设我们要创建一个目录菜单目录菜单下边挂载两个叶子菜单菜单数据格式如下所示 {menuId: 1-1,menuType: 1,menuName: 业务规则,iconClass: el-icon-location,children: [{menuId: 1-1-1,menuType: 2,menuName: 数据集管理,path: /modeller,},{menuId: 1-1-2,menuType: 2,menuName: 内容管理,path: /modeller,}] }Web 中向后台请求菜单信息的方式 // api/menu.js import axios from axiosexport function getMenu(){return axios.get(/menu) }10. 前端路由设计 前端路由粗鲁的解释就是给组件取个名字这个名字采用 URL 的形式来命名。前端路由格式如下所示 path: /foo,name: foo,component: Foo,meta: { title: foo }children: [{path: /foo,name: foo,component: Foo,meta: { title: foo }}]path 路由地址name 路由名称component 路由对应的组件meta 路由元数据如路由标签等children 子路由信息 定义好路由信息后我们在程序中便可以调用路由跳转方法进行路由切换操作。具体方法如下所示 // 字符串 router.push(/foo)// 对象 router.push({ path: /foo })// 命名的路由 router.push({ name: foo, params: { userId: 123 }})// 带查询参数变成 /register?planprivate router.push({ path: /foo, query: { plan: private }})在 HTML 页面元素中实现路由跳转的方法 router-link to/fooGo to Foo/router-link在浏览历史记录中切换跳转方法 router.go(n) // n 表示第几个历史记录n 必须是整数前端路由往往嵌套多层。下边我们来模拟一个复杂的场景构建路由信息详细路由表如下所示 import VueRouter from vue-router import BaseLayout from /layout/BaseLayout import EmptyLayout from /layout/EmptyRouter import Dashboard from /views/Dashboard import Login from /views/Loginimport Modeller from /views/modeller/Modeller import ModelUpdate from /views/modeller/ModelUpdate import ModelColumn from /views/modeller/column/ModelColumn import ModelColumnUpdate from /views/modeller/column/ModelColumnUpdate// 前端路由表 const routes [{path: ,component: EmptyLayout,redirect: dashboard,children: [{path: /login,component: Login,name: login,meta: {title: 登录}}] }, {path: ,component: BaseLayout,redirect: dashboard,children: [{path: dashboard,component: Dashboard,name: dashboard,meta: {title: 首页}}] }, {path: /,component: BaseLayout,children: [{path: modeller,component: Modeller,meta: {title: 数据集管理}}, {path: modeller,component: EmptyLayout,meta: {title: 数据集管理}, children: [{path: add,name: add,component: ModelUpdate,meta: {title: 新增数据集,}}, {path: column,name: column,component: ModelColumn,meta: {title: 字段管理}}, {path: column,component: EmptyLayout,meta: {title: 字段管理},children: [{path: add,name: modeller-column-add,component: ModelColumnUpdate,meta: {title: 新增字段}}]}]}] }]var router new VueRouter({scrollBehavior: () ({ y: 0 }),routes })export default router;路由组件之间嵌套层级比较多例如当用户请求 /modeller/column 时页面渲染顺序是 先打开 BaseLayout 组件然后在这个组件中找到 router-view/router-view接着在打开 EmptyLayout 组件EmptyLayout 组件被嵌入 BaseLayout 组件的 router-view/router-view 内最后打开 ModelColumn 组件此时 ModelColumn 的上级组件即 EmptyLayout 组件内查找 router-view/router-view然后将 ModelColumn 组件嵌入到 EmptyLayout 组件的 router-view/router-view 内。 前端路由定义时如果路由中包含了 children 属性那么这个组件内一定带有 router-view/router-view DOM 元素 否则 children 内的组件无处安放。我们可以查看一下整个项目的入口组件 App.vue。里边就是一个 router-view/router-view。 !--App.vue--templatediv idapprouter-view/router-view/div /templatescript export default {name: app,methods: {autoHeight() {// 初始化浏览器高度this.$store.dispatch(autoHeight);}},beforeCreate() {this.$store.dispatch(autoHeight);},mounted() {window.onresize () {// 浏览器this.autoHeight();};} }; /scriptstyle #app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50; } body {padding: 0px;margin: 0px; } /style 11. 登录入口设计 登录入口主要负责接收用户账号和密码校验用户身份。当用户身份校验通过后进入系统。现在流行的登录方式非常多。常见的几种登录方式如下所示 微信扫码登录支付宝扫码登录手机验证码登录用户账号密码登录微博授权登录 上边的几种登录方式从技术实现的角度来看主要为下边几种 账号密码登录 最常见的登录方式是用户账号密码登录。后台校验用户账号和密码是否正确如果正确则返回有效的 token 信息 Web 端上携带 token 信息请求后台服务。 短信验证码登录 Web 端向后台服务发起请求获取短信验证码短信运营商将验证码发送到用户手机上。用户通过手机号 短信验证码请求后台短信登录接口。后台服务使用手机号 短信验证码到短信运营商或者自己开发的验证接口请求验证如果验证通过则用户使用短信登录成功后台服务向 Web 端下发 token 信息Web 端携带 token 信息进入系统。 二维码扫码登录 实质上是通过手机上已经登录的账号来获取新的登录令牌。二维码通常分为活码和静态码表。 静态码是将文字信息翻译成二维码这种二维码存储信息量有限且不能动态改变。如我们将 hello 这个单词做成一个静态的二维码。这样不论是谁来扫描得到的都是 hello 这个词。活码是将一个 URL 地址做成二维码。扫描二维码时得到这个 URL 地址然后跳转到这个 URL 地址获取真正的内容。 扫码登录的常见流程如下大概流程中间省略一些验证细节 Web 页面上选择扫码登录Web 上显示出二维码此时的二维码中包含一个唯一 ID 信息且这个 ID 信息会被记录到后台服务中。APP 上假设这个 APP 是自己公司开发且支持扫码登录功能扫描二维码读取到二维码中包含的内容包含了第一步中的唯一 ID。APP 点击确认登录此时手机 APP 向后台发送自己的登录信息也就是 APP 扫码登录的前提是 APP 在手机上已经登录并带上第二步读取到的唯一 ID 信息。后台服务收到用户在手机上的登录信息以及唯一 ID 信息。后台服务开始校验用户登录信息是否有效如果有效则修改服务端存储的唯一 ID 对应的状态为 true。Web 端通过唯一 ID 查询到后台服务对应的状态为 true 时后台返回新的登录 token 信息。此时 Web 端携带 token 信息进入系统。 第三方授权登录 第三方授权也是一种比较常见的登录方式如微博账号登录、微信账号登录、QQ 账号登录等等。第三方授权登录流程是 用户点击第三方授权登录请求跳转到微博、QQ、微信的登录页面。微博、QQ、微信校验用户登录信息如果用户登录信息校验通过则回调我们的后台服务地址告诉我们的服务器授权登录成功并返回 token 信息给我们的后台服务我们的服务获取到 token 信息后可以根据这个 token 与微博、QQ或微信建立绑定关系。如果此时的 token 权限过大则后台服务可以根据这个 token 来操作用户微博、QQ、微信部分功能一些小网站上建议不要轻易在上边使用进行第三方授权的方式登录万一不法网站获取到权限过大的授权此时可能存在信息泄露的风险。我们的服务器收到微博、QQ或微信的回调后。我们的后台服务生成的 token 信息并下发给 Web 端Web 端携带我们服务器下发的 token 信息进入系统。 下边我们来实现一个简单的账号密码登录页面示例代码如下所示 templatedivel-row stylemargin-top: 80px;el-col :span8 :offset8el-formel-form-item propusername label用户名el-input nameusername v-modelusername placeholder用户账号 //el-form-itemel-form-item proppassword label密码el-input typepassword namepasswrod v-modelpassword placeholder用户密码 //el-form-item/el-formel-button clickloginSubmit登nbsp;nbsp;录/el-button/el-col/el-row/div /template scriptimport { login } from /api/login.js;export default {name: login,data() {return {username: admin,password: 123456};},methods: {loginSubmit() {login(this.username, this.password).then(resp {if (resp) {// 修改登录状态this.$store.dispatch(loginStatus, true);this.$router.push(/dashboard)}});}} }; /script当用户在 Web 上输入用户名和密码后点击登录按钮。此时将会执行 loginSubmit 方法。这个方法负责调用后台服务登录接口。登录成功后跳转到系统首页。 12. Mock 数据设计 当我们在开发前端 Web 服务时可能对应的后台服务尚未开发完成此时我们可以借助于 Mock 服务来模拟后台服务当 Web 端使用 Axios 向后台服务发起请求时请求将会被 Mock 服务拦截Mock 服务返回预先定义的数据。当后台服务开发完成后只需关闭对应的 Mock 服务此时请求将会被转发到真正的后台服务。所以Mock 服务给我们开发前端 Web 提供了挡板功能在后台服务尚未开发完成的情况下通过使用 Mock 服务从而保障前端开发进度。 12.1 Mockjs 集成方法 使用 Yarn 工具在线下载 mockjs 工具包。下载命令如下所示 yarn add mockjsmockjs 包下载完成后将会被存储在当前项目 node_modules 目录下。 12.2 启用 Mockjs 服务 // mock/mock.js import Mock from mockjsconst mock_source [biz.js, sys.js]function load(mock_source) {for (let i 0; i mock_source.length; i) {let file import(./data/ mock_source[i])file.then(content {if (content content.default) {// 找到目标initMock(content.default)}})} }function initMock(rules) {for (let [rule, resp] of Object.entries(rules)) {const element rule.split( )if (element element.length 2) {const rtype element[0].trim()const rurl element[1].trim()Mock.mock(rurl, rtype.toLowerCase(), resp)} else {Mock.mock(rule, resp)}} }if (mock_source mock_source.length 0) {load(mock_source) }注意事项 Mock 服务启动需要时间有可能首页打开时Mock 服务尚未启动可能出现请求 Mock 服务时出现 404 的情况。比如从 Mock 服务中加载菜单信息。如果加载菜单的时候Mock 服务未初始化完成则很有可能请求菜单时出现 404。 解决办法在 Mock 数据初始化完成后将 Mock 服务状态保存到 store 中存储。 在 store 中 定义 Mock 服务初始化状态的变量变量名称为 mockInitFinished变量定义方式如下所示 // store/modules/basic.js const basic {state: {// mock 服务初始化状态mockInitFinished: false,},mutations: {MOCK_INIT_FINISHED: (state, status) {// mock 初始化完成state.mockInitFinished status;},},actions: {mockInitFinished({ commit }, status) {// 修改 mock 服务初始化状态为已完成commit(MOCK_INIT_FINISHED, status)},} }export default basic;当我们初始化 Mock 服务完成后通过如下方式更新 store 中 Mock 服务的状态为 true。具体方式如下所示 // mock/mock.js import store from /store/index.js;if (mock_source mock_source.length 0) {load(mock_source)// 将 Mock 状态保存到 store 中存储。store.dispatch(mockInitFinished, true) }从后台 API 获取菜单信息方法修改成如下所示 // components/layout/Side.vue// 定时获取后台菜单信息const timer setInterval(() {if (this.mockInitFinished){getMenu().then(resp {this.sideMenuList respclearInterval(timer)})}},1000)setInterval 方法每隔一个固定的频率执行一次任务。上边的代码中我们每隔 1 秒钟获取一次后台 API 中的菜单信息。为什么要在此使用定时循环执行的方式获取菜单信息呢 主要原因是 Mock 服务启动可能晚于我们在 Side 组件中查询后台 API /menu 的时间这样必然会出现请求 404 的错误。 为了解决这个问题我们可以通过引入定时器每隔 1 秒钟定时查询一次 Mock 服务的状态当 Mock 服务启动后再去请求获取 Mock 服务的数据。如果我们请求的是真实的后台环境那么我们就没必要引入 setinterval 这种方式来查询后台服务的菜单信息。 Mock 服务初始化完成后我们开始根据具体的 API 需求编写 Mock 服务。比如编写一个菜单查询的 Mock 服务。详细信息如下所示 // mock/data/sys.js const menu {GET /menu: {statusCode: 200, statusMessage: succcess, data: [{menuId: 2,menuType: 1,menuName: 系统管理,iconClass: el-icon-location,children: [{menuId: 2-1,menuType: 2,menuName: 数据集管理,path: /modeller,},{menuId: 2-2,menuType: 2,menuName: 内容管理,path: /modeller,}]},{menuId: 3-1,menuType: 2,menuName: 数据集管理,path: /modeller,}]} }export default menu;13. 前端代理服务 在前后端分离模式开发中后台服务往往部署在某一个 K8s 集群中Web 与后台服务可能不在一个网络尤其是开发阶段此时 Web 跨域请求后台服务可能出现跨域失败的问题。可以通过设置前端代理的方式来解决这个问题。 在项目根目录创建 vue.config.js 文件。然后添加如下代码 // vue.config.js module.exports {devServer: {port: 8080,proxy: {/: {// process.env.VUE_APP_BASE_API 替换成对应的后台服务地址target: process.env.VUE_APP_BASE_API,changeOrigin: true,secure: false,pathRewrite: {^/: /}}}} } Web 端通过 Axios 发起后台服务请求都会被转发到 process.env.VUE_APP_BASE_API 这个地址通过设置 changeOrigin 为 true有效的解决跨域请求失败的问题。 本篇 Chat 代码地址 https://github.com/hzwy23/vue-admin Vue.js 官方网站地址 https://cn.vuejs.org/ Vue Cli 官网网站地址 https://cli.vuejs.org/zh/ Vue Router 官方网站地址 https://router.vuejs.org/zh/ Vuex 官方网站地址 https://vuex.vuejs.org/zh/ Element UI 官方网站地址 https://element.eleme.cn/#/zh-CN
http://www.pierceye.com/news/956368/

相关文章:

  • ps学做翻页相册网站wordpress导航图标
  • 模板网站的弊端在哪杨家平网站建设
  • 网站模板带手机站手表网站十大品牌
  • 物流网站功能设计师招聘网站有哪些
  • 知名网站开发哪里有重庆公司网站建设价格
  • 南头做网站公司重庆建设厂招聘信息网站
  • 网站建设的基本条件外贸建设网站制作
  • 移动电子商务平台就是手机网站奉化首页的关键词优化
  • 公司怎么建立一个网站展示型网站模板代码
  • 益阳网页设计十堰seo优化服务
  • discuz论坛建站教程微商城开发小程序开发
  • 饰品网站建设炫丽的网站
  • 网站建设制作介绍河南企业建站多站点管理系统
  • 网站盗号怎么做设计说明模板200字
  • 赣州人才网站搜索引擎广告是什么
  • 广州app开发网站建设与网站优化销售
  • 做淘客哪个网站好点如何做好网站建设销售
  • 手机端网站开发视频wordpress删除评论
  • 台州网站建设推广公司随州有哪些网站建设的公司
  • 定制商品的网站建设word超链接网站怎样做
  • 南昌做网站流程安徽省建设厅网站打不开
  • 雄安智能网站建设方案做涉黄的视频网站用什么服务器
  • 公司网站必须做可信认证吗免费关键词排名优化软件
  • 基金公司网站建设网站有哪几种
  • 广州住房和城乡建设部网站首页福建建站公司
  • 福州网站制作有限公司可玩儿小程序代理
  • 佛山市企业网站建设平台注册公司多少钱起步
  • 网站开发好的语言网站维护上海
  • 民宿网站建设网站如何添加统计代码
  • 哪里培训做网站wordpress plugin development