一、一些常用组件效果的实现

1)面包屑导航

主要是使用$route.mathed:一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。

类似的有一个router.getMatchedComponents(location?):返回目标位置或是当前路由匹配的组件数组(是数组的定义/构造类,不是实例)。通常在服务端渲染的数据预加载时时候。

(还记的vue-router中router,route,routes的区别么?)

1)router:是指一个vue-router的实例

2)route:路由信息对象,表示当前激活的路由的状态信息,可以出现

    • 在组件内,即 this.$route

    • 在 $route 观察者回调内

    • router.match(location) 的返回值

    • 导航守卫的参数:

      1. router.beforeEach((to, from, next) => {
      2. // `to` 和 `from` 都是路由对象
      3. })
    • scrollBehavior 方法的参数:

      1. const router = new VueRouter({
      2. scrollBehavior (to, from, savedPosition) {
      3. // `to` 和 `from` 都是路由对象
      4. }
      5. })

3)routes:router的构造配置项

  routes

    • 类型: Array<RouteConfig>

      RouteConfig 的类型定义:

      1. declare type RouteConfig = {
      2. path: string;
      3. component?: Component;
      4. name?: string; // 命名路由
      5. components?: { [name: string]: Component }; // 命名视图组件
      6. redirect?: string | Location | Function;
      7. props?: boolean | string | Function;
      8. alias?: string | Array<string>;
      9. children?: Array<RouteConfig>; // 嵌套路由
      10. beforeEnter?: (to: Route, from: Route, next: Function) => void;
      11. meta?: any;
      12. // 2.6.0+
      13. caseSensitive?: boolean; // 匹配规则是否大小写敏感?(默认值:false)
      14. pathToRegexpOptions?: Object; // 编译正则的选项
      15. }
  1. <template>
  2. <el-breadcrumb class="app-levelbar" separator="/">
  3. <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
  4. <router-link v-if='item.redirect==="noredirect"||index==levelList.length-1' to="" class="no-redirect">{{item.name}}</router-link>
  5. <router-link v-else :to="item.redirect||item.path">{{item.name}}</router-link>
  6. </el-breadcrumb-item>
  7. </el-breadcrumb>
  8. </template>
  9.  
  10. <script>
  11. export default {
  12. created() {
  13. this.getBreadcrumb()
  14. },
  15. data() {
  16. return {
  17. levelList: null
  18. }
  19. },
  20. methods: {
  21. getBreadcrumb() {
  22. // console.log('this.$route.matched', this.$route.matched);
  23. let matched = this.$route.matched.filter(item => item.name);
  24. const first = matched[];
  25. if (first && (first.name !== '首页' || first.path !== '')) {
  26. matched = [{
  27. name: '首页',
  28. path: '/'
  29. }].concat(matched)
  30. }
  31. this.levelList = matched;
  32. }
  33. },
  34. watch: {
  35. $route() {
  36. this.getBreadcrumb();
  37. }
  38. }
  39. }

breadbar

2)历史访问记录TabView

使用vuex记录app全局的一些状态参数,诸如导航栏是否收起,浏览路径等等

  1. import Cookies from 'js-cookie';
  2.  
  3. const app = {
  4. state: {
  5. sidebar: {
  6. opened: !+Cookies.get('sidebarStatus')
  7. },
  8. theme: 'default',
  9. livenewsChannels: Cookies.get('livenewsChannels') || '[]',
  10. visitedViews: []
  11. },
  12. mutations: {
  13. TOGGLE_SIDEBAR: state => {
  14. if (state.sidebar.opened) {
  15. Cookies.set('sidebarStatus', );
  16. } else {
  17. Cookies.set('sidebarStatus', );
  18. }
  19. state.sidebar.opened = !state.sidebar.opened;
  20. },
  21. ADD_VISITED_VIEWS: (state, view) => {
  22. if (state.visitedViews.some(v => v.path === view.path)) return
  23. state.visitedViews.push({ name: view.name, path: view.path })
  24. },
  25. DEL_VISITED_VIEWS: (state, view) => {
  26. let index
  27. for (const [i, v] of state.visitedViews.entries()) {
  28. if (v.path === view.path) {
  29. index = i
  30. break
  31. }
  32. }
  33. state.visitedViews.splice(index, )
  34. }
  35. },
  36. actions: {
  37. ToggleSideBar: ({ commit }) => {
  38. commit('TOGGLE_SIDEBAR')
  39. },
  40. addVisitedViews: ({ commit }, view) => {
  41. commit('ADD_VISITED_VIEWS', view)
  42. },
  43. delVisitedViews: ({ commit }, view) => {
  44. commit('DEL_VISITED_VIEWS', view)
  45. }
  46. }
  47. };
  48.  
  49. export default app;

store/modules/app.js

如上所示,通过visitedViews这个state记录浏览历史记录,需要的时候遍历这个数组即可,watch $route 每一次路由更改时,向数组中压入一条记录

  1. <template>
  2. <div class='tabs-view-container'>
  3. <router-link class="tabs-view" v-for="tag in Array.from(visitedViews)" :to="tag.path" :key="tag.path">
  4. <el-tag :closable="true" :type="isActive(tag.path)?'primary':''" @close='closeViewTabs(tag,$event)'>
  5. {{tag.name}}
  6. </el-tag>
  7. </router-link>
  8. </div>
  9. </template>
  10.  
  11. <script>
  12. export default {
  13. computed: {
  14. visitedViews() {
  15. return this.$store.state.app.visitedViews.slice(-)
  16. }
  17. },
  18. methods: {
  19. closeViewTabs(view, $event) {
  20. this.$store.dispatch('delVisitedViews', view)
  21. $event.preventDefault()
  22. },
  23. generateRoute() {
  24. if (this.$route.matched[this.$route.matched.length - ].name) {
  25. return this.$route.matched[this.$route.matched.length - ]
  26. }
  27. this.$route.matched[].path = '/'
  28. return this.$route.matched[]
  29. },
  30. addViewTabs() {
  31. this.$store.dispatch('addVisitedViews', this.generateRoute())
  32. },
  33. isActive(path) {
  34. return path === this.$route.path
  35. }
  36. },
  37. watch: {
  38. $route() {
  39. this.addViewTabs()
  40. }
  41. }
  42. }
  43. </script>
  44.  
  45. <style rel="stylesheet/scss" lang="scss" scoped>
  46. .tabs-view-container {
  47. display: inline-block;
  48. vertical-align: top;
  49. margin-left: 10px;
  50. .tabs-view {
  51. margin-left: 10px;
  52. }
  53. }
  54. </style>

历史浏览路径组件tabViews实现

3)全屏显示

  hmtl5有相关的screenfull的API,只不过兼容性并不好。可以借助第三方库,如https://github.com/sindresorhus/screenfull.js,使用起来其实很简单

  1. <template>
  2. <svg @click='click' class="icon screenfull" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
  3. t="" viewBox="0 0 1024 1024" version="1.1" p-id="" :fill='fill' :width="width" :height="height">
  4. <path d="M604.157933 512l204.484208 204.484208 82.942037-82.942037c10.364045-10.952446 26.498514-13.83817 40.309054-8.067746 13.249769 5.742794 22.465664 18.99154 22.465664 33.977859l0 258.042008c0 20.168342-16.695241 36.863582-36.863582 36.863582L659.452283 954.357873c-14.986319 0-28.236088-9.215896-33.977859-23.025413-5.770424-13.249769-2.885723-29.384237 8.067746-39.748283l82.942037-82.942037L512 604.157933 307.515792 808.642141l82.942037 82.942037c10.952446 10.364045 13.83817 26.498514 8.067746 39.748283-5.742794 13.809517-18.99154 23.025413-33.977859 23.025413L106.504686 954.357873c-20.168342 0-36.863582-16.695241-36.863582-36.863582L69.641103 659.452283c0-14.986319 9.215896-28.236088 23.025413-33.977859 13.249769-5.770424 29.384237-2.8847 39.748283 8.067746l82.942037 82.942037 204.484208-204.484208L215.357859 307.515792l-82.942037 82.942037c-6.890944 6.918573-16.10684 10.952446-25.911136 10.952446-4.593622 0-9.804297-1.14815-13.83817-2.8847-13.809517-5.742794-23.025413-18.99154-23.025413-33.977859L69.641103 106.504686c0-20.168342 16.695241-36.863582 36.863582-36.863582L364.546693 69.641103c14.986319 0 28.236088 9.215896 33.977859 23.025413 5.770424 13.249769 2.8847 29.384237-8.067746 39.748283l-82.942037 82.942037 204.484208 204.484208L716.484208 215.357859l-82.942037-82.942037c-10.952446-10.364045-13.83817-26.498514-8.067746-39.748283 5.742794-13.809517 18.99154-23.025413 33.977859-23.025413l258.042008 0c20.168342 0 36.863582 16.695241 36.863582 36.863582l0 258.042008c0 14.986319-9.215896 28.236088-22.465664 33.977859-4.593622 1.736551-9.804297 2.8847-14.397918 2.8847-9.804297 0-19.020192-4.033873-25.911136-10.952446l-82.942037-82.942037L604.157933 512z"
  5. p-id="" />
  6. </svg>
  7. </template>
  8.  
  9. <script>
  10. import screenfull from 'screenfull';
  11. export default {
  12. name: 'hamburger',
  13. props: {
  14. width: {
  15. type: Number,
  16. default:
  17. },
  18. height: {
  19. type: Number,
  20. default:
  21. },
  22. fill: {
  23. type: String,
  24. default: '#48576a'
  25. }
  26. },
  27. data() {
  28. return {
  29. isFullscreen: false
  30. }
  31. },
  32. methods: {
  33. click() {
  34. if (!screenfull.enabled) {
  35. this.$message({
  36. message: 'you browser can not work',
  37. type: 'warning'
  38. });
  39. return false;
  40. }
  41. screenfull.toggle();
  42. }
  43. }
  44. }
  45. </script>
  46.  
  47. <style scoped>
  48. .screenfull {
  49. display: inline-block;
  50. cursor: pointer;
  51. vertical-align: -.15em;
  52. }
  53. </style>

screenFull组件实现

二、一些常用的第三方库

1)富文本编辑器:tinyMCE

2)markdown编辑器:simplemde-markdown-editor,markdown的转换使用了shutdown

3)json编辑器(代码编辑器): CodeMirror

4)列表拖拽:vue.draggalbe(基于sortable)

三、一些常用的文本过滤方法(包括时间格式化方法等)

  1. function pluralize(time, label) {
  2. if (time === ) {
  3. return time + label
  4. }
  5. return time + label + 's'
  6. }
  7. export function timeAgo(time) {
  8. const between = Date.now() / - Number(time);
  9. if (between < ) {
  10. return pluralize(~~(between / ), ' minute')
  11. } else if (between < ) {
  12. return pluralize(~~(between / ), ' hour')
  13. } else {
  14. return pluralize(~~(between / ), ' day')
  15. }
  16. }
  17.  
  18. export function parseTime(time, cFormat) {
  19. if (arguments.length === ) {
  20. return null;
  21. }
  22.  
  23. if ((time + '').length === ) {
  24. time = +time *
  25. }
  26.  
  27. const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  28. let date;
  29. if (typeof time == 'object') {
  30. date = time;
  31. } else {
  32. date = new Date(parseInt(time));
  33. }
  34. const formatObj = {
  35. y: date.getFullYear(),
  36. m: date.getMonth() + ,
  37. d: date.getDate(),
  38. h: date.getHours(),
  39. i: date.getMinutes(),
  40. s: date.getSeconds(),
  41. a: date.getDay()
  42. };
  43. const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
  44. let value = formatObj[key];
  45. if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - ];
  46. if (result.length > && value < ) {
  47. value = '' + value;
  48. }
  49. return value || ;
  50. });
  51. return time_str;
  52. }
  53.  
  54. export function formatTime(time, option) {
  55. time = +time * ;
  56. const d = new Date(time);
  57. const now = Date.now();
  58.  
  59. const diff = (now - d) / ;
  60.  
  61. if (diff < ) {
  62. return '刚刚'
  63. } else if (diff < ) { // less 1 hour
  64. return Math.ceil(diff / ) + '分钟前'
  65. } else if (diff < * ) {
  66. return Math.ceil(diff / ) + '小时前'
  67. } else if (diff < * * ) {
  68. return '1天前'
  69. }
  70. if (option) {
  71. return parseTime(time, option)
  72. } else {
  73. return d.getMonth() + + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'
  74. }
  75. }
  76.  
  77. /* 数字 格式化*/
  78. export function nFormatter(num, digits) {
  79. const si = [
  80. { value: 1E18, symbol: 'E' },
  81. { value: 1E15, symbol: 'P' },
  82. { value: 1E12, symbol: 'T' },
  83. { value: 1E9, symbol: 'G' },
  84. { value: 1E6, symbol: 'M' },
  85. { value: 1E3, symbol: 'k' }
  86. ];
  87. for (let i = ; i < si.length; i++) {
  88. if (num >= si[i].value) {
  89. return (num / si[i].value + 0.1).toFixed(digits).replace(/\.+$|(\.[-]*[-])+$/, '$1') + si[i].symbol;
  90. }
  91. }
  92. return num.toString();
  93. }
  94.  
  95. export function html2Text(val) {
  96. const div = document.createElement('div');
  97. div.innerHTML = val;
  98. return div.textContent || div.innerText;
  99. }
  100.  
  101. export function toThousandslsFilter(num) {
  102. return (+num || ).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{})+$)/g, ','));
  103. }

filters.js

在main.js中引入:

  1. import * as filters from './filters'; // 全局vue filter
  2. Object.keys(filters).forEach(key => {
  3. Vue.filter(key, filters[key])
  4. });

vue后台_实战篇的更多相关文章

  1. vue后台_登录权限

    登录权限控制包含着这么几个方面的含义: 1)不同的权限对应不同的路由 2)侧边栏需要根据不同的权限,异步生成 登录:使用用户名和密码,登录成功后返回用户的token(防止XSS攻击),将此token存 ...

  2. vue后台_纯前端实现excel导出/csv导出

    之前的文件下载功能一般是由前后端配合实现,由于项目需要,纯前端实现了一把excel的导出功能: 一.excel导出 1.安装依赖库 xlsx:这是一个功能强大的excel处理库,但是上手难度也很大,还 ...

  3. vue+uni-app商城实战 | 第一篇:【有来小店】微信小程序快速开发接入Spring Cloud OAuth2认证中心完成授权登录

    一. 前言 本篇通过实战来讲述如何使用uni-app快速进行商城微信小程序的开发以及小程序如何接入后台Spring Cloud微服务. 有来商城 youlai-mall 项目是一套全栈商城系统,技术栈 ...

  4. 一步步带你做vue后台管理框架(三)——登录功能

    系列教程<一步步带你做vue后台管理框架>第三课 github地址:vue-framework-wz 线上体验地址:立即体验 <一步步带你做vue后台管理框架>第一课:介绍框架 ...

  5. caffe框架下目标检测——faster-rcnn实战篇操作

    原有模型 1.下载fasrer-rcnn源代码并安装 git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git 1) ...

  6. 新书上线:《Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统》,欢迎大家买回去垫椅子垫桌脚

    新书上线 大家好,笔者的新书<Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统>已上线,此书内容充实.材质优良,乃家中必备垫桌脚 ...

  7. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  8. 二、Redis基本操作——String(实战篇)

    小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...

  9. 无线安全专题_攻击篇--MAC泛洪攻击

    上一篇讲解了无线安全专题_攻击篇--干扰通信,没在首页待多长时间就被拿下了,看来之后不能只是讲解攻击实战,还要进行技术原理和防御方法的讲解.本篇讲解的是局域网内的MAC泛洪攻击,这种攻击方式主要目的是 ...

随机推荐

  1. .NET Core 常用第三方包

    .NET Core 常用第三方包 作者:高堂 原文地址:https://www.cnblogs.com/gaotang/p/10845370.html 写在前面 最近在学习.NET Core 中经常用 ...

  2. 前端开发 Vue -2npm

    npm介绍 说明:npm(node package manager)是nodejs的包管理器,用于node插件管理(包括安装.卸载.管理依赖等) 使用npm安装插件:命令提示符执行npm instal ...

  3. koa-router学习笔记

    koa-router 是koa框架的一个路由处理级别的中间件. 目录结构 ├── app.js ├── middleware │ ├── m1.js │ └── m2.js ├── package-l ...

  4. 适配方案(七)iPhone各种系统分辨率、屏幕分辨率

  5. 将两个数组相同index的value合并成一个新的value组成一个新的数组

    将两个数组相同index的value合并成一个新的value组成一个新的数组 前提: 这两个数组的长度相同 生成后的新数组长度也相同 返回值都是对象 把rows对象的key和value弄成两个数组, ...

  6. MysqL之数值函数

    1.CEIL() 用法:向上取整 举例: mysql> select CEIL(3.5); +-----------+ | CEIL(3.5) | +-----------+ | +------ ...

  7. http服务详解(2)——httpd的配置文件常见设置

    HTTP服务器应用 http服务器程序 httpd apache nginx lighttpd 应用程序服务器 IIS .asp tomcat .jsp jetty 开源的servlet容器,基于Ja ...

  8. 测试某网站的SMS验证码

    to=18911121211&sms_type=sms_registration&captcha_num=9JCMw4yN5EjI6ISYoNGdwF2YiwiIw5WNwlmb3xm ...

  9. notify()和 notifyAll()有什么区别?(未完成)

    notify()和 notifyAll()有什么区别?(未完成)

  10. 全排列 递归方法(permutation原理

    https://blog.csdn.net/axiqia/article/details/50967863  原博客 (一)递归的全排列算法 (A.B.C.D)的全排列为 1.A后面跟(B.C.D)的 ...