• vue后台_实战篇


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

    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) 的返回值

      • 导航守卫的参数:

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

        const router = new VueRouter({
          scrollBehavior (to, from, savedPosition) {
            // `to` 和 `from` 都是路由对象
          }
        })

    3)routes:router的构造配置项

      routes

      • 类型: Array<RouteConfig>

        RouteConfig 的类型定义:

        declare type RouteConfig = {
          path: string;
          component?: Component;
          name?: string; // 命名路由
          components?: { [name: string]: Component }; // 命名视图组件
          redirect?: string | Location | Function;
          props?: boolean | string | Function;
          alias?: string | Array<string>;
          children?: Array<RouteConfig>; // 嵌套路由
          beforeEnter?: (to: Route, from: Route, next: Function) => void;
          meta?: any;
        
          // 2.6.0+
          caseSensitive?: boolean; // 匹配规则是否大小写敏感?(默认值:false)
          pathToRegexpOptions?: Object; // 编译正则的选项
        }

     

    <template>
    <el-breadcrumb class="app-levelbar" separator="/">
      <el-breadcrumb-item v-for="(item,index)  in levelList" :key="item.path">
        <router-link v-if='item.redirect==="noredirect"||index==levelList.length-1' to="" class="no-redirect">{{item.name}}</router-link>
        <router-link v-else :to="item.redirect||item.path">{{item.name}}</router-link>
      </el-breadcrumb-item>
    </el-breadcrumb>
    </template>
    
    <script>
    export default {
      created() {
        this.getBreadcrumb()
      },
      data() {
        return {
          levelList: null
        }
      },
      methods: {
        getBreadcrumb() {
          // console.log('this.$route.matched', this.$route.matched);
          let matched = this.$route.matched.filter(item => item.name);
          const first = matched[0];
          if (first && (first.name !== '首页' || first.path !== '')) {
            matched = [{
              name: '首页',
              path: '/'
            }].concat(matched)
          }
          this.levelList = matched;
        }
      },
      watch: {
        $route() {
          this.getBreadcrumb();
        }
      }
    }
    breadbar

     

    2)历史访问记录TabView

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

     

    import Cookies from 'js-cookie';
    
    const app = {
      state: {
        sidebar: {
          opened: !+Cookies.get('sidebarStatus')
        },
        theme: 'default',
        livenewsChannels: Cookies.get('livenewsChannels') || '[]',
        visitedViews: []
      },
      mutations: {
        TOGGLE_SIDEBAR: state => {
          if (state.sidebar.opened) {
            Cookies.set('sidebarStatus', 1);
          } else {
            Cookies.set('sidebarStatus', 0);
          }
          state.sidebar.opened = !state.sidebar.opened;
        },
        ADD_VISITED_VIEWS: (state, view) => {
          if (state.visitedViews.some(v => v.path === view.path)) return
          state.visitedViews.push({ name: view.name, path: view.path })
        },
        DEL_VISITED_VIEWS: (state, view) => {
          let index
          for (const [i, v] of state.visitedViews.entries()) {
            if (v.path === view.path) {
              index = i
              break
            }
          }
          state.visitedViews.splice(index, 1)
        }
      },
      actions: {
        ToggleSideBar: ({ commit }) => {
          commit('TOGGLE_SIDEBAR')
        },
        addVisitedViews: ({ commit }, view) => {
          commit('ADD_VISITED_VIEWS', view)
        },
        delVisitedViews: ({ commit }, view) => {
          commit('DEL_VISITED_VIEWS', view)
        }
      }
    };
    
    export default app;
    store/modules/app.js

     

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

    <template>
      <div class='tabs-view-container'>
        <router-link class="tabs-view" v-for="tag in Array.from(visitedViews)" :to="tag.path" :key="tag.path">
          <el-tag :closable="true" :type="isActive(tag.path)?'primary':''" @close='closeViewTabs(tag,$event)'>
            {{tag.name}}
          </el-tag>
        </router-link>
      </div>
    </template>
    
    <script>
      export default {
        computed: {
          visitedViews() {
            return this.$store.state.app.visitedViews.slice(-6)
          }
        },
        methods: {
          closeViewTabs(view, $event) {
            this.$store.dispatch('delVisitedViews', view)
            $event.preventDefault()
          },
          generateRoute() {
            if (this.$route.matched[this.$route.matched.length - 1].name) {
              return this.$route.matched[this.$route.matched.length - 1]
            }
            this.$route.matched[0].path = '/'
            return this.$route.matched[0]
          },
          addViewTabs() {
            this.$store.dispatch('addVisitedViews', this.generateRoute())
          },
          isActive(path) {
            return path === this.$route.path
          }
        },
        watch: {
          $route() {
            this.addViewTabs()
          }
        }
      }
    </script>
    
    <style rel="stylesheet/scss" lang="scss" scoped>
      .tabs-view-container {
        display: inline-block;
        vertical-align: top;
        margin-left: 10px;
        .tabs-view {
          margin-left: 10px;
        }
      }
    </style>
    历史浏览路径组件tabViews实现

    3)全屏显示

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

    <template>
      <svg @click='click' class="icon screenfull" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
        t="1497503607356" viewBox="0 0 1024 1024" version="1.1" p-id="4109" :fill='fill' :width="width" :height="height">
        <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"
          p-id="4110" />
      </svg>
    </template>
    
    <script>
      import screenfull from 'screenfull';
      export default {
        name: 'hamburger',
        props: {
           {
            type: Number,
            default: 22
          },
          height: {
            type: Number,
            default: 22
          },
          fill: {
            type: String,
            default: '#48576a'
          }
        },
        data() {
          return {
            isFullscreen: false
          }
        },
        methods: {
          click() {
            if (!screenfull.enabled) {
              this.$message({
                message: 'you browser can not work',
                type: 'warning'
              });
              return false;
            }
            screenfull.toggle();
          }
        }
      }
    </script>
    
    <style scoped>
    .screenfull {
      display: inline-block;
      cursor: pointer;
      vertical-align: -0.15em;
    }
    </style>
    screenFull组件实现

    二、一些常用的第三方库

    1)富文本编辑器:tinyMCE

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

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

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

     

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

    function pluralize(time, label) {
      if (time === 1) {
        return time + label
      }
      return time + label + 's'
    }
    export function timeAgo(time) {
      const between = Date.now() / 1000 - Number(time);
      if (between < 3600) {
        return pluralize(~~(between / 60), ' minute')
      } else if (between < 86400) {
        return pluralize(~~(between / 3600), ' hour')
      } else {
        return pluralize(~~(between / 86400), ' day')
      }
    }
    
    export function parseTime(time, cFormat) {
      if (arguments.length === 0) {
        return null;
      }
    
      if ((time + '').length === 10) {
        time = +time * 1000
      }
    
      const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
      let date;
      if (typeof time == 'object') {
        date = time;
      } else {
        date = new Date(parseInt(time));
      }
      const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
      };
      const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
        let value = formatObj[key];
        if (key === 'a') return ['', '', '', '', '', '', ''][value - 1];
        if (result.length > 0 && value < 10) {
          value = '0' + value;
        }
        return value || 0;
      });
      return time_str;
    }
    
    export function formatTime(time, option) {
      time = +time * 1000;
      const d = new Date(time);
      const now = Date.now();
    
      const diff = (now - d) / 1000;
    
      if (diff < 30) {
        return '刚刚'
      } else if (diff < 3600) { // less 1 hour
        return Math.ceil(diff / 60) + '分钟前'
      } else if (diff < 3600 * 24) {
        return Math.ceil(diff / 3600) + '小时前'
      } else if (diff < 3600 * 24 * 2) {
        return '1天前'
      }
      if (option) {
        return parseTime(time, option)
      } else {
        return d.getMonth() + 1 + '' + d.getDate() + '' + d.getHours() + '' + d.getMinutes() + ''
      }
    }
    
    /* 数字 格式化*/
    export function nFormatter(num, digits) {
      const si = [
            { value: 1E18, symbol: 'E' },
            { value: 1E15, symbol: 'P' },
            { value: 1E12, symbol: 'T' },
            { value: 1E9, symbol: 'G' },
            { value: 1E6, symbol: 'M' },
            { value: 1E3, symbol: 'k' }
      ];
      for (let i = 0; i < si.length; i++) {
        if (num >= si[i].value) {
          return (num / si[i].value + 0.1).toFixed(digits).replace(/.0+$|(.[0-9]*[1-9])0+$/, '$1') + si[i].symbol;
        }
      }
      return num.toString();
    }
    
    export function html2Text(val) {
      const div = document.createElement('div');
      div.innerHTML = val;
      return div.textContent || div.innerText;
    }
    
    export function toThousandslsFilter(num) {
      return (+num || 0).toString().replace(/^-?d+/g, m => m.replace(/(?=(?!)(d{3})+$)/g, ','));
    }
    filters.js

     

    在main.js中引入:

    import * as filters from './filters'; // 全局vue filter
    Object.keys(filters).forEach(key => {
      Vue.filter(key, filters[key])
    });
  • 相关阅读:
    嵌入式C程序基础与编程结构
    英特尔图形处理器第8代架构
    用servlet打内容到网页上
    servlet获取多个同名参数
    JAVA之复制数组
    用JAVA写一个简单的英文加密器
    Tomcat使用
    JAVA,字符串替换
    使用自己的域名解析博客园地址(CSDN也可以)
    错误笔记20181124
  • 原文地址:https://www.cnblogs.com/bobodeboke/p/9046914.html
Copyright © 2020-2023  润新知