-
不要为了用vuex而用vuex!
-
后来发现其实可以简单的在 router-view上加上一个唯一的key,来保证路由切换时都会重新渲染触发钩子。
-
后台项目区别于做其它的项目,权限验证与安全性是非常重要的,可以说是一个后台项目一开始就必须考虑和搭建的基础核心功能。我们所要做到的是:不同的权限对应着不同的路由,同时侧边栏也需根据不同的权限,异步生成。
-
当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(将这个token存贮到cookie中,保证刷新页面后能记住用户登录状态),前端会根据token再去拉取一个 user_info 的接口来获取用户的详细信息(如用户权限,用户名等等信息)。
-
通过token获取用户对应的 role,动态根据用户的 role 算出其对应有权限的路由,通过 router.addRoutes 动态挂载这些路由。
-
登录思路:
-
使用element form组件,提交用户和密码信息。交给后台进行验证,并且获得token,保存token到本地cookie,保证刷新和再次打开页面时不用进行登录。本地cookie生命周期按需求定制。
-
token有效期(Expires/Max-Age)都是Session,就是当浏览器关闭了就丢失了。重新打开游览器都需要重新登录验证,后端也会在每周固定一个时间点重新刷新token,让后台用户全部重新登录一次,确保后台用户不会因为电脑遗失或者其它原因被人随意使用账号。
-
login和get_user_info两件事分开比较好。 -
权限控制:
-
前端来控制页面级的权限,不同权限的用户显示不同的侧边栏和限制其所能进入的页面(也做了少许按钮级别的权限控制),后端则会验证每一个涉及请求的操作,验证其是否有该操作的权限,每一个后台的请求不管是 get 还是 post 都会让前端在请求
header里面携带用户的 token,后端会根据该 token 来验证用户是否有权限执行该操作。若没有权限则抛出一个对应的状态码,前端检测到该状态码,做出相对应的操作。 -
最早没用addRoute整个权限控制代码里都是各种if/else的逻辑判断,代码相当的耦合和复杂。
-
创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。
-
当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
-
调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。
-
使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。
-
通过meta标签来标示改页面能访问的权限有哪些。
-
代码重新进入
router.beforeEach这个钩子,这时候再通过next()来释放钩子,就能确保所有的路由都已经挂在完成了。 -
代码说白了就是干了一件事,通过用户的权限和之前在router.js里面asyncRouterMap的每一个页面所需要的权限做匹配,最后返回一个该用户能够访问路由有哪些。
-
侧边栏:
-
遍历之前算出来的
permission_routers,通过vuex拿到之后动态v-for渲染而已。不过这里因为有一些业务需求所以加了很多判断 比如我们在定义路由的时候会加很多参数。 -
:default-active="$route.path" 将
default-active一直指向当前路由就可以了,就是这么简单。(就可以实现侧边栏更随路由进行高亮) -
真正需要按钮级别控制的地方不是很多,现在是通过获取到用户的role之后,在前端用v-if手动判断来区分不同权限对应的按钮的。
-
项目里面真正的布局页面是layout。
-
request拦截器在每个请求头里面塞入token,好让后端对请求进行权限验证。并创建一个respone拦截器,当服务端返回特殊的状态码,我们统一做处理,如没权限或者token失效等操作。
-
这里的两部验证有点名不副实,其实就是账号密码验证过之后还需要一个绑定的第三方平台登录验证而已。 写起来也很简单,在原有登录得逻辑上改造一下就好。
-
我们通过
window.opener.location.href的方式改变hash,在login.js里面再监听hash的变化。当hash变化时,获取之前第三方登录成功返回的code与第一步账号密码登录之后返回的uid一同发送给服务端验证是否正确,如果正确,这时候就是真正的登录成功。 -
换肤怎么实现?
-
先把默认主题文件中涉及到颜色的 CSS 值替换成关键词。
-
根据用户选择的主题色生成一系列对应的颜色值。
-
把关键词再换回刚刚生成的相应的颜色值。
-
直接在页面上加 style 标签,把生成的样式填进去。
-
自己实现换肤:
-
可以通过element提供的自定义主题工具生成自定义主题——element-theme。
-
也可以通过官网的工具自己在线定制需要的主题,下载,引入。
-
利用gulp-css-wrap给主题里的元素加上同一个class,方便后面切换class。
-
然后通过命名空间不停切换class(添加或者删除)就可以切换主题了,但是如果存在多种主题需要自定义多个模板,比较麻烦。
-
动态的加载css:动态在head元素下面添加link元素,变化不同的href来切换css。
-
新的换肤思路:
-
待补充。
-
侧边栏:
-
构了一下侧边栏,使用了递归组件。
-
就是在组件中使用自己,形成递归组件。
-
但现在 spa 就不一样了,用户点击当前高亮的路由并不会刷新view,因为
vue-router会拦截你的路由,它判断你的url并没有任何变化,所以它不会触发任何钩子或者是view的变化。 -
单页面:单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。JS会感知到url的变化,通过这一点,可以用js动态的将当前页面的内容清除掉,然后将下一个页面的内容挂载到当前页面上,这个时候的路由不是后端来做了,而是前端来做,判断页面到底是显示哪个组件,清除不需要的,显示需要的组件。这种过程就是单页应用,每次跳转的时候不需要再请求html文件了。
多页面:每一次页面跳转的时候,后台服务器都会给返回一个新的html文档,这种类型的网站也就是多页网站,也叫做多页应用。
-
这里主要是基于Sortable实现拖拽表格内容效果。
-
由于 JavaScript 的限制, Vue 不能检测以下变动的数组: * 当你利用索引直接设置一个项时。使用数组原型对象上面的slice方法来触发数组的变化,进而触发view层变化。
-
通过splice 替换数据 触发视图更新。
-
赋值的数据是一个objec引用类型共享一个内存区域的。所以我们就不能直接连等复制,需要重新指向一个新的引用。
-
keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 它是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。可以减少内存和请求时间,提供效率。
-
回显数据其实就是根据后台实时返回的数据渲染dom,例如select的选项。
-
官方说明了所有的原生事件必须添加 .native 修饰符。
-
scoped也没有很神秘的,它就是基于PostCss的,加了一个作用局的概念。
-
由于element-ui的样式我们是在全局引入的,所以你想在某个view里面覆盖它的样式就不能加scoped,但你又想只覆盖这个页面的element样式,你就可在它的父级加一个class,以用命名空间来解决问题。
-
给一个诀窍其实大部分诡异的问题都可以通过加一个key或者 Vue.nextTick来解决。
-
如果你的业务需求对导出文件的格式没有什么要求,不建议导出成xlsx格式的,直接导出成csv的就好了,真的会简单很多。创建一个a标签,写上
data:text/csv;charset=utf-8头,再把数据塞进去,encodeURI(csvContent)一下就好了。 -
Echarts实时回显数据:第一种 watch options变化 利用vue的深度 watcher,options一有变化就重新setOption watch: { options: { handler(options){this.chart.setOption(this.options) }, deep: true }, } //第二种 只watch 数据的变化 只有数据变化时触发ECharts watch: { seriesData(val) { this.setOptions({series:val}) } }。
-
创建和编辑页面是不能被 keep-alive 缓存的,因为keep-alive 的 include 目前不支持根据路由来缓存,所以目前都是基于 component name 来进行缓存的。如果你想类似的实现缓存效果,可以使用 localStorage 等浏览器缓存方案。或者不要使用 keep-alive 的 include,直接缓存所有页面。
-
大部分创建页面与编辑页面字段和ui几乎是一样的,可以用一个component来对应不同的页面。通过meta来区分 比较推荐这种方式来区分。也可以写不同的component来路由到不同的页面。
-
路由懒加载应该是写大一点的项目都会用的一个功能,只有在使用这个component的时候才会加载这个相应的组件,这样写大大减少了初始页面 js 的大小并且能更好的利用游览器的缓存。
-
可能是异步加载导致 webpack 每次的 cache 失效了,所以每次的rebuild 才会这么的慢。
-
由于侧边栏导航和面包屑亦或是权限,你会发现其实都是和router密切相关的,所以基于vue-router路由信息对象上做了一下小小的拓展,自定义了一些属性。
-
配置 eslint 对多人协作的项目有很大的好处,同时配置好lint 在加 ide 的 lint 插件写代码简直要起飞。
-
PostCSS插件解析CSS和添加供应商前缀的CSS规则使用值从Can I Use。
-
PostCSS (平台,提供CSS处理服务)提供了一个解析器,它能够将 CSS 解析成抽象语法树(AST)。
-
在 .vue 文件中引入你要的样式就可以了,或者你可以改变 vue-cli的文件在 css-loader 前面在加一个 postcss-loader。
-
工程化的东西:打包工具-webpack,配置一系列插件和加载器,用于打包工程。
-
Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如
Object.assign)都不会转码。 -
或者更简单暴力 polyfill.io 使用它给的一个 cdn 地址,引入这段js之后它会自动判断浏览器,加载缺少的那部分 polyfill,但国内速度肯能不行,大家可以自己搭 cdn。
-
Cross Origin Resource Sharing(跨域资源共享)为推荐的跨域解决方案。需要后端配合完成。
-
前端解决跨域问题,不管是 proxy 和 nginx 的原理都是一样的通过搭建一个中转服务器来转发请求规避跨域的问题。(服务器没有跨域问题)
-
axios拦截器来拦截请求的发出和返回。
-
V4.0版本更新:
-
这次更新基本上就是基于 webpack-chain 把之前的 webpack 配置迁移了一遍,因为
vue-cli帮你做了很多默认配置,所有可以省去一些代码。 -
它的实现逻辑和原理与之前还是一样的,还是基于 plugins babel-plugin-dynamic-import-node 来实现的。(懒加载)
-
之所以在
vue-cli中只需要设置一个变量就可以了,是借用了vue-cli它的默认配置,它帮你代码都写好了。通过阅读 源码 可知,vue-cli会通过VUE_CLI_BABEL_TRANSPILE_MODULES这个环境变量来区分是否使用babel-plugin-dynamic-import-node。 -
当遇到你需要刷新页面的情况,你就手动重定向页面到`redirect`页面,它会将页面重新`redirect`重定向回来,由于页面的 key 发生了变化,从而间接实现了刷新页面组件的效果。(利用了一个间接页面进行跳转) -
Mockjs会重写浏览器的
XMLHttpRequest对象,从而才能拦截所有请求,代理到本地。 -
我推荐你可以安装如 Vue 2 Snippets
VS Code插件。 这种代码片段在平时工作中还是能提升不少开发效率的。 -
异步有些地方用
async/await来代替promise。
-
你可以添加
immediate属性,这样初始化的时候Watch也会触发。 -
这时候我们就可以使用
v-bind="$attrs":传递所有属性、v-on="$listeners"传递所有方法。 -
为了优化有了
image sprite就是所谓的雪碧图,就是将多个图片合成一个图片,然后利用 css 的 background-position 定位显示不同的 icon 图标。 -
它的主要原理其实是和
unicode一样的,它只是多做了一步,将原先这种写法换成了.icon-QQ,它在每个 class 的 before 属性中写了unicode,省去了人为写的麻烦。如.icon-QQ:before { content: "\e604"; }。 -
你不能保证你所有的 svg 都是用来当做 icon的,有些真的可能只是用来当做图片资源的。
-
不能确保你使用的一些第三方类库会使用到 svg。