美文网首页
Vue-混合、自定义指令、插件和过滤介绍

Vue-混合、自定义指令、插件和过滤介绍

作者: 张正yi | 来源:发表于2018-02-08 17:20 被阅读0次

1、混合

混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。

2、自定义指令

除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令

3、插件

插件形式一般有很多种,以下最为常见:

    // 开始一个插件(myplug.js) 
    MyPlugin.install = function (Vue, options) {
        // 1. 添加全局方法或属性
        Vue.myGlobalMethod = function () { ...}
        // 2. 添加全局资源
        Vue.directive('my-directive', {
            bind (el, binding, vnode, oldVnode) { ...}
        })
        // 3. 注入组件
        Vue.mixin({
            created: function () { ...}
        })
        // 4. 添加实例方法
        Vue.prototype.$myMethod = function (methodOptions) { ...}
    }

    // 使用插件
    import MyPlugin from 'xxx';
    Vue.use(MyPlugin)

4、过滤

实现数据的筛选、过滤、格式化。如时间格式化,小写转大写,价格后面都加上¥符号等等。

5、简单例子

5.1、混合

  <script type="text/javascript">
    // 定义一个混合对象
    var myMixin = {
       created:function(){
          this.hello();
       },
       methods:{
          hello:function(){
             console.log('hello mixin');
          }
       }
    }
    // vue对象
    var vm = new Vue({
      el:"#app",
      data:{},
      mixins:[myMixin],
      created:function(){
        console.log("hello");
      }
    });
  </script>
// 执行上面代码会依次打印出:“hello mixin”,“hello” 

5.2、自定义指令:

  // 如:注册一个全局自定义指令 `v-focus` : 
    Vue.directive('focus',{
        // 当被绑定的元素插入到 DOM 中时……
        inserted: function (el) {
          // 聚焦元素
          el.focus()
        }
    })
  // 如:注册一个局部自定义指令 `v-focus` : 
    directives:{
      focus:{
        // 指令的定义
        inserted: function (el) {
          el.focus()
        }
      }
    }

// 在页面中使用如下:<input v-focus>

5.3、插件的用法

// 实现tip弹窗效果
import './tips.css'; // 引入需要的样式文件
const vueTips = {};
vueTips.install = (Vue, options = {}) => {
      //自定义指令实现
      Vue.directive('mytip', {
           bind: function (el, binding, vnode) {
                 // 鼠标移入
                 el.onmouseover = function() {...}
                 // 鼠标离开
                 el.onmouseout = function() {...}
            }
        });
    });
   export default vueTips;

5.4、过滤的用法

1、创建:
    new Vue({
      filters:{
          myCurrency:function(){
            //处理结果
           }
        }
    });
2、使用:
    语法:
    <any>{{表达式 | 过滤器}}</any>
    举个例子:
    <h1>{{price | myCurrency}}</h1>

6、简单应用

6.1、使用自定义指令实现一个水波纹效果:(全局注册)

<script type="text/javascript">
      Vue.directive('waves', {  
          bind: function (el, binding) {
              // 点击产生的效果(点击事件)
              el.addEventListener('click',e=>{
                  //TODO 处理代码...
               },false);            
          }
      });
</script>

html:
  <button v-waves >水波纹效果</button>
  <button v-waves="{type: 'center'}">水波纹效果</button>  

分析:
  上面的 "waves" 为指令的名称,在html中需要使用‘v-waves’命名。
  binding:
    只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    el:指令所绑定的元素,可以用来直接操作 DOM(如button元素)
    binding:一个对象,包含以下属性:
        name:指令名。
        value:绑定的值(如:type: 'center'为最终的值)

具体实现代码:
js

               const customOpts = Object.assign({}, binding.value);
                // 处理点击操作
                const opts = Object.assign({
                    ele: el, // 波纹作用元素
                    type: 'hit', // hit点击位置扩散,center中心点扩展
                    color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
                }, customOpts);
                const target = opts.ele;
                if (target) {
                    target.style.position = 'relative';
                    target.style.overflow = 'hidden';
                    // 获取元素高宽,坐标,上下左右间距
                    const rect = target.getBoundingClientRect();
                    let ripple = target.querySelector('.waves-ripple');
                    // 如果没有找到,开始创建一个节点
                    if (!ripple) {
                        ripple = document.createElement('span');
                        ripple.className = 'waves-ripple';
                        ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px';
                        target.appendChild(ripple);
                    } else {
                        ripple.className = 'waves-ripple';
                    }
                    switch (opts.type) {
                        case 'center':
                            ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px';
                            ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px';
                            break;
                        default:
                            ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px';
                            ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px';
                    }
                    ripple.style.backgroundColor = opts.color;
                    ripple.className = 'waves-ripple z-active';
                    return false;

css:

.btn {
        background-color: #0094ff;
        color: #fff;
        font-size: 16px;
        user-select: none;
        border: none;
        border-radius: 5px;
        padding: 10px;
        outline: none;
        height: 100px;
        width: 200px;
    }

    .btn:hover {
        background-color: #5eb0ff;
    }

    .waves-ripple {
        position: absolute;
        border-radius: 100%;
        background-color: rgba(0, 0, 0, 0.15);
        background-clip: padding-box;
        pointer-events: none;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        -webkit-transform: scale(0);
        -ms-transform: scale(0);
        transform: scale(0);
        opacity: 1;
    }

    .waves-ripple.z-active {
        opacity: 0;
        -webkit-transform: scale(2);
        -ms-transform: scale(2);
        transform: scale(2);
        -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
        transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
        transition: opacity 1.2s ease-out, transform 0.6s ease-out;
        transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
    }

6.2、实现一个全局时间格式化过滤器

1)全局js文件,多个过滤操作都可以放在这里,这里以时间过滤为例如下:

 /**
 * 时间转化时间戳
 * @param time
 * @param cFormat
 */
export function timeFormatting(time, cFormat) {
  // 转化为时间戳
  let timestamp = Date.parse(new Date(time));
  return parseTime(timestamp,cFormat);
}

/**
 * 
 * @param date
 * @param cFormat
 * @returns {*}
 */
export function formatTotime(date, cFormat) {
  date = new Date(Date.parse(date.replace(/-/g, '/')));
  // 转化为时间戳
  date = date.getTime();
  return parseTime(date, cFormat);
}

/**
 * 
 * @param time
 * @param cFormat
 * @returns {*}
 */
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;
}

2)注册:

import * as filters from './filters'; // 全局vue filter
// register global utility filters.
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
});
  1. 使用:
<span>{{ xxx_time | timeFormatting('{y}-{m}-{d} {h}:{i}') }}</span>
如 xxx_time = '2018-02-09T12:08:21.000Z' 最终结果为:2018-02-09 20:08

如时间格式为2018/02/09需要转化为2018-01-09可以这样实现
<span>{{'2018/02/09' | formatTotime('{y}-{m}-{d}') }}</span> 结果为:2018-02-09

上面最终的结果都是将某种格式的时间转化为时间戳,再由parseTime函数转化为固有格式。
所以如果得到的是时间戳可以直接这么写就可以了:
<span>{{'需要转化的时间戳' | parseTime('{y}-{m}-{d}') }}</span>

相关文章

  • Vue-混合、自定义指令、插件和过滤介绍

    1、混合 混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。 2、自定义指令 除了核心...

  • Vue.js与其他框架的区别

    1.与AngularJS的区别 相同点: 都支持指令:内置指令和自定义指令。 都支持过滤器:内置过滤器和自定义过滤...

  • Vue与Angular以及React的区别?

    1、与AngularJS的区别 相同点:都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;...

  • Vue与Angular、React的区别

    Angular的区别 相同点:都支持指令:内置指令和自定义指令。都支持过滤器:内置过滤器和自定义过滤器。都支持双向...

  • 2017-5-25 AngularJs

    service 自定义服务 1.指令 内置指令 自定义指令 2.过滤器 内置过滤器 自定义过滤器 3.服务 内置服...

  • vue.js与angular.js的异同点

    相同点:1.都支持指令:内置指令和自定义指令2.都支持过滤器:内置过滤器和自定义过滤器3.都支持数据双向绑定4.都...

  • 复写VUE.JS第四天

    过滤器 自定义指令

  • angularJS总结

    内置指令 自定义指令 控制器 作用域 内置过滤器 自定义过滤器 路由 ui.router 项目搭建 建议:继...

  • 4.Vue之自定义过滤器

    介绍 类似于自定义指令,可以用全局方法 Vue.filter() 注册一个自定义过滤器,它接收两个参数:过滤器 I...

  • Vue-指令、自定义过滤器

    最近做的项目,一直用的Angular6.0框架,期间陆陆续续完成了三四个项目。业务知识有一定的提升,但是一直用一个...

网友评论

      本文标题:Vue-混合、自定义指令、插件和过滤介绍

      本文链接:https://www.haomeiwen.com/subject/gzazzxtx.html