Vue-自定义过滤器的使用

Posted qq_31387691

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue-自定义过滤器的使用相关的知识,希望对你有一定的参考价值。

1.自定义过滤器对日期进行格式化

(1)日期时间格式,大致可以分为以下四种情况:

        ① 年月日:yyyy-M-d

        ② 年月日(小于两位数时补0):yyyy-MM-dd

        ③ 年月日时分秒:yyyy-M-d H:m:s

        ④ 年月日时分秒(小于两位时补0):yyyy-MM-dd HH:mm:ss

(2)针对上述的四种情况,对日期进行格式化处理:

a):局部过滤器

<template>
    <div>
        <p>time</p>
        <p>[yyyy-M-d]:time|formatDate('yyyy-M-d')</p>
        <p>[yyyy-MM-dd]:time|formatDate('yyyy-MM-dd')</p>
        <p>[yyyy-M-d H:m:s]:time|formatDate('yyyy-M-d H:m:s')</p>
        <p>[yyyy-MM-dd HH:mm:ss]:time|formatDate('yyyy-MM-dd HH:mm:ss')</p>
    </div>
</template>
<script>
export default 
    name: 'TimeDemo',
    data() 
        return 
            time:new Date()
        
    ,
    filters:
        formatDate: function(value,args) 
            var dt = new Date(value);
            if(args == 'yyyy-M-d') // yyyy-M-d
            let year = dt.getFullYear();
            let month = dt.getMonth() + 1;
            let date = dt.getDate();
            return `$year-$month-$date`;
         else if(args == 'yyyy-M-d H:m:s')// yyyy-M-d H:m:s
            let year = dt.getFullYear();
            let month = dt.getMonth() + 1;
            let date = dt.getDate();
            let hour = dt.getHours();
            let minute = dt.getMinutes();
            let second = dt.getSeconds();
            return `$year-$month-$date $hour:$minute:$second`;
         else if(args == 'yyyy-MM-dd') // yyyy-MM-dd
            let year = dt.getFullYear();
            let month = (dt.getMonth() + 1).toString().padStart(2,'0');
            let date = dt.getDate().toString().padStart(2,'0');
            return `$year-$month-$date`;
         else // yyyy-MM-dd HH:mm:ss
            let year = dt.getFullYear();
            let month = (dt.getMonth() + 1).toString().padStart(2,'0');
            let date = dt.getDate().toString().padStart(2,'0');
            let hour = dt.getHours().toString().padStart(2,'0');
            let minute = dt.getMinutes().toString().padStart(2,'0');
            let second = dt.getSeconds().toString().padStart(2,'0');
            return `$year-$month-$date $hour:$minute:$second`;
        
        
    

</script>
<style scoped>
p
    text-align: left;

</style>

备注:formatDate被定义为接收两个参数的过滤器函数,其中 time 的值作为第一个参数,日期格式字符串(如:'yyyy-MM-dd')作为第二个参数。

b):router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import TimeDemo from '@/components/TimeDemo'

Vue.use(Router)

export default new Router(
  routes: [
    
      path: '/time',
      name: 'TimeDemo',
      component: TimeDemo
    ,
    
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    
  ]
)

c):日期转化效果

 2.将时间过滤器注册到全局

考虑到代码的复用性,可以将自定义的日期过滤器函数注册到全局。

(1)在common文件夹下新建一个filter.js文件

(2)在filter.js中定义需要使用的过滤器函数

const filter = 
  formatDate: function(value,args) 
    var dt = new Date(value);
    if(args == 'yyyy-M-d') // yyyy-M-d
      let year = dt.getFullYear();
      let month = dt.getMonth() + 1;
      let date = dt.getDate();
      return `$year-$month-$date`;
     else if(args == 'yyyy-M-d H:m:s')// yyyy-M-d H:m:s
      let year = dt.getFullYear();
      let month = dt.getMonth() + 1;
      let date = dt.getDate();
      let hour = dt.getHours();
      let minute = dt.getMinutes();
      let second = dt.getSeconds();
      return `$year-$month-$date $hour:$minute:$second`;
     else if(args == 'yyyy-MM-dd') // yyyy-MM-dd
      let year = dt.getFullYear();
      let month = (dt.getMonth() + 1).toString().padStart(2,'0');
      let date = dt.getDate().toString().padStart(2,'0');
      return `$year-$month-$date`;
     else // yyyy-MM-dd HH:mm:ss
      let year = dt.getFullYear();
      let month = (dt.getMonth() + 1).toString().padStart(2,'0');
      let date = dt.getDate().toString().padStart(2,'0');
      let hour = dt.getHours().toString().padStart(2,'0');
      let minute = dt.getMinutes().toString().padStart(2,'0');
      let second = dt.getSeconds().toString().padStart(2,'0');
      return `$year-$month-$date $hour:$minute:$second`;
    
  

export default filter;

 (3)在main.js文件中引入filter.js并全局定义过滤器

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import filter from './common/filter'

Vue.config.productionTip = false

for (const key in filter) 
  Vue.filter(key,filter[key]);

/* eslint-disable no-new */
new Vue(
  el: '#app',
  router,
  components:  App ,
  template: '<App/>'
)

这样我们就可以在项目中的任意一个文件中使用过滤器函数啦。

例如在HelloWorld.vue中引用日期格式化函数

 效果如图

 

vue基本使用

MVC 和 MVVM 的区别

MVC 是后端的分层开发概念;

MVVM是前端视图层的概念,主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分 Model, View , VM ViewModel

技术图片

Vue最基本代码的结构

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <!-- 1. 导入Vue的包 -->
  <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js">
</head>
<body>
  <!-- 将来 new 的Vue实例,会控制这个 元素中的所有内容 -->
  <!-- Vue 实例所控制的这个元素区域,就是我们的 V  -->
  <div id="app">
    <p>{{ msg }}</p>
  </div>
  <script>
    // 2. 创建一个Vue的实例
    // 当我们导入包之后,在浏览器的内存中,就多了一个 Vue 构造函数
    //  注意:我们 new 出来的这个 vm 对象,就是我们 MVVM中的 VM调度者
    var vm = new Vue({
      el: '#app',  // 表示,当前我们 new 的这个 Vue 实例,要控制页面上的哪个区域
      // 这里的 data 就是 MVVM中的 M,专门用来保存 每个页面的数据的
      data: { // data 属性中,存放的是 el 中要用到的数据
        msg: 'hello,Vue' // 通过 Vue 提供的指令,很方便的就能把数据渲染到页面上,程序员不再手动操作DOM元素了【前端的Vue之类的框架,不提倡我们去手动操作DOM元素了】
      }
    })
  </script>
</body>
</html>

插值表达式

  • v-cloak

  • v-text

  • v-html

  • v-bind(缩写是:)

  • v-on(缩写是@)

  • v-model

  • v-for

  • v-if(使用时会频繁生成元素,经常使用消耗大)

  • v-show(使用时只是隐藏元素)

事件修饰符(.stop .prevent .capture .self .once)

  • .stop 阻止冒泡(阻止事件向外层扩散)

  • .prevent 阻止默认行为(阻止标签原本定义的默认事件)

  • .capture 实现捕获触发事件的机制(优先触发机制,因内层元素而被触发,优先于内层元素事件)

  • 正常情况下,先触发内层元素事件,再触发外层元素事件。

  • .self 实现只有点击当前元素时候,才会触发事件处理函数(点击内层元素不触发外层事件,点击外层元素除去内层元素区域才会触发事件)

  • .once 只触发一次事件处理函数

  • .stop 和 .self 的区别

  • .stop会阻止事件向外扩散

  • .self 只会阻止事件扩散到自己身上引起的冒泡行为的触发,并不会真正阻止冒泡行为的继续传递

vue对象

  • el 指定要控制的区域

  • data 是个对象,指定了控制的区域内要用到的数据

  • methods 虽然带个s后缀,但是是个对象,这里可以自定义了方法

注意点

  • 在 VM 实例中,如果要访问 data 上的数据,或者要访问 methods 中的方法, 必须带 this

  • 在 v-for 要会使用 key 属性 (只接受 string / number)

  • v-model 只能应用于表单元素

  • 在vue中绑定样式两种方式 v-bind:class v-bind:style

过滤器

概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化

过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;

私有过滤器

<td>{{item.ctime | dataFormat('yyyy-mm-dd')}}</td>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js">
<script>
new Vue({
        el:"#app",
        data:{},
        methods:{},
        mounted:{},
        filters: {// 私有局部过滤器,只能在 当前 VM 对象所控制的 View 区域进行使用
           dataFormat(input, pattern = "") { // 在参数列表中 通过 pattern="" 来指定形参默认值,防止报错
             var dt = new Date(input);
             // 获取年月日
             var y = dt.getFullYear();
             var m = (dt.getMonth() + 1).toString().padStart(2, '0');
             var d = dt.getDate().toString().padStart(2, '0');
             // 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
             // 否则,就返回  年-月-日 时:分:秒
             if (pattern.toLowerCase() === 'yyyy-mm-dd') {
               return `${y}-${m}-${d}`;
             } else {
               // 获取时分秒
               var hh = dt.getHours().toString().padStart(2, '0');
               var mm = dt.getMinutes().toString().padStart(2, '0');
               var ss = dt.getSeconds().toString().padStart(2, '0');
               return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
             }
           }
        }
}
</script>

全局过滤器

// 定义一个全局过滤器
Vue.filter('dataFormat', function (input, pattern = '') {
  var dt = new Date(input);
  // 获取年月日
  var y = dt.getFullYear();
  var m = (dt.getMonth() + 1).toString().padStart(2, '0');
  var d = dt.getDate().toString().padStart(2, '0');
  // 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
  // 否则,就返回  年-月-日 时:分:秒
  if (pattern.toLowerCase() === 'yyyy-mm-dd') {
    return `${y}-${m}-${d}`;
  } else {
    // 获取时分秒
    var hh = dt.getHours().toString().padStart(2, '0');
    var mm = dt.getMinutes().toString().padStart(2, '0');
    var ss = dt.getSeconds().toString().padStart(2, '0');
    return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
  }
});

键盘修饰符以及自定义键盘修饰符

1.x中自定义键盘修饰符【了解即可】

Vue.directive('on').keyCodes.f2 = 113;

2.x中自定义键盘修饰符

1. 通过`Vue.config.keyCodes.名称 = 按键值`来自定义案件修饰符的别名:
Vue.config.keyCodes.f2 = 113;
2. 使用自定义的按键修饰符:
<input type="text" v-model="name" @keyup.f2="add">

自定义指令

自定义全局和局部的 自定义指令:

    // 自定义全局指令 v-focus,为绑定的元素自动获取焦点:
    Vue.directive('focus', {
      inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用
        el.focus();
      }
    });

    // 自定义局部指令 v-color 和 v-font-weight,为绑定的元素设置指定的字体颜色 和 字体粗细:
      directives: {
        color: { // 为元素设置指定的字体颜色
          bind(el, binding) {
            el.style.color = binding.value;
          }
        },

        'font-weight': function (el, binding2) { // 自定义指令的简写形式,等同于定义了 bind 和 update 两个钩子函数
          el.style.fontWeight = binding2.value;
        }
      }

2. 自定义指令的使用方式:


<input type="text" v-model="searchName" v-focus v-color="'red'" v-font-weight="900">

Vue 1.x 中 自定义元素指令【已废弃,了解即可】


Vue.elementDirective('red-color', {

  bind: function () {

    this.el.style.color = 'red';

  }

});

使用方式:


<red-color>1232</red-color>

vue实例的生命周期

技术图片

什么是生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!

生命周期钩子:就是生命周期事件的别名而已;

生命周期钩子 = 生命周期函数 = 生命周期事件

主要的生命周期函数分类

创建期间的生命周期函数:

  • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性

  • created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板

  • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中

  • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示

运行期间的生命周期函数:

  • beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点

  • updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!

销毁期间的生命周期函数:

  • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。

  • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

vue-resource 实现 get, post, jsonp请求

除了 vue-resource 之外,还可以使用 axios 的第三方包实现实现数据的请求

常见的数据请求类型? get post jsonp

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <!-- 注意:vue-resource 依赖于 Vue,所以先后顺序要注意  -->
  <!-- this.$http.jsonp -->
  <script src="./lib/vue-resource-1.3.4.js"></script>
</head>
<body>
  <div id="app">
    <input type="button" value="get请求" @click="getInfo"> 
    <input type="button" value="post请求" @click="postInfo">
    <input type="button" value="jsonp请求" @click="jsonpInfo">
  </div>
  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        getInfo() { // 发起get请求
          //  当发起get请求之后, 通过 .then 来设置成功的回调函数
          this.$http.get('http://vue.studyit.io/api/getlunbo').then(function (result) {
            // 通过 result.body 拿到服务器返回的成功的数据
            // console.log(result.body);
          })
        },
        postInfo() { // 发起 post 请求   application/x-wwww-form-urlencoded
          //  手动发起的 Post 请求,默认没有表单格式,所以,有的服务器处理不了
          //  通过 post 方法的第三个参数, { emulateJSON: true } 设置 提交的内容类型 为 普通表单数据格式
          this.$http.post('http://vue.studyit.io/api/post', {}, { emulateJSON: true }).then(result => {
            console.log(result.body);
          })
        },
        jsonpInfo() { // 发起JSONP 请求
          this.$http.jsonp('http://vue.studyit.io/api/jsonp').then(result => {
            console.log(result.body);
          })
        }
      }

    });
  </script>
</body>
</html>

JSONP的实现原理

由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;

可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称作JSONP(注意:根据JSONP的实现原理,知晓,JSONP只支持Get请求);

具体实现过程:

- 先在客户端定义一个回调方法,预定义对数据的操作;

- 再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;

- 服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;

- 客户端拿到服务器返回的字符串之后,当作Script脚本去解析执行,这样就能够拿到JSONP的数据了;

手动实现一个JSONP的请求例子;


   const http = require('http');
   // 导入解析 URL 地址的核心模块
   const urlModule = require('url');
   const server = http.createServer();
   // 监听 服务器的 request 请求事件,处理每个请求
   server.on('request', (req, res) => {
     const url = req.url;
     // 解析客户端请求的URL地址
     var info = urlModule.parse(url, true);
     // 如果请求的 URL 地址是 /getjsonp ,则表示要获取JSONP类型的数据
     if (info.pathname === '/getjsonp') {
       // 获取客户端指定的回调函数的名称
       var cbName = info.query.callback;
       // 手动拼接要返回给客户端的数据对象
       var data = {
         name: 'zs',
         age: 22,
         gender: '男',
         hobby: ['吃饭', '睡觉', '运动']
       }
       // 拼接出一个方法的调用,在调用这个方法的时候,把要发送给客户端的数据,序列化为字符串,作为参数传递给这个调用的方法:
       var result = `${cbName}(${JSON.stringify(data)})`;
       // 将拼接好的方法的调用,返回给客户端去解析执行
       res.end(result);
     } else {
       res.end('404');
     }
   });
   server.listen(3000, () => {
     console.log('server running at http://127.0.0.1:3000');
   });

vue-resource 的配置步骤

  • 直接在页面中,通过script标签,引入 vue-resource 的脚本文件;

  • 注意:引用的先后顺序是:先引用 Vue 的脚本文件,再引用 vue-resource 的脚本文件;

发送get请求

getInfo() { // get 方式获取数据
    this.$http.get('http://127.0.0.1:8899/api/getlunbo').then(res => {
    console.log(res.body);
  })
}

发送post请求


postInfo() {
  var url = 'http://127.0.0.1:8899/api/post';
  // post 方法接收三个参数:
  // 参数1: 要请求的URL地址
  // 参数2: 要发送的数据对象
  // 参数3: 指定post提交的编码类型为 application/x-www-form-urlencoded
  this.$http.post(url, { name: 'zs' }, { emulateJSON: true }).then(res => {
    console.log(res.body);
  });
}

发送JSONP请求获取数据

jsonpInfo() { // JSONP形式从服务器获取数据
  var url = 'http://127.0.0.1:8899/api/jsonp';
  this.$http.jsonp(url).then(res => {
    console.log(res.body);
  });
}

Vue中的动画

为什么要有动画:动画能够提高用户的体验,帮助用户更好的理解页面中的功能;

使用过渡类名

  1. HTML结构:
<div id="app">
    <input type="button" value="动起来" @click="myAnimate">
    <!-- 使用 transition 将需要过渡的元素包裹起来 -->
    <transition name="fade">
        <div v-show="isshow">动画哦</div>
    </transition>
</div>
  1. VM 实例:

// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
  el: '#app',
  data: {
    isshow: false
  },
  methods: {
    myAnimate() {
      this.isshow = !this.isshow;
    }
  }
});
  1. 定义两组类样式:

    /* 定义进入和离开时候的过渡状态 */

    .fade-enter-active,
    
    .fade-leave-active {
    
      transition: all 0.2s ease;
    
      position: absolute;
    
    }



    /* 定义进入过渡的开始状态 和 离开过渡的结束状态 */
    
    .fade-enter,
    
    .fade-leave-to {
    
      opacity: 0;
    
      transform: translateX(100px);
    
    }

使用第三方 CSS 动画库

  1. 导入动画类库:

<link rel="stylesheet" type="text/css" href="./lib/animate.css">
  1. 定义 transition 及属性:

<transition

    enter-active-class="fadeInRight"
    
    leave-active-class="fadeOutRight"
    
    :duration="{ enter: 500, leave: 800 }">

    <div class="animated" v-show="isshow">动画哦</div>

</transition>

使用动画钩子函数

  1. 定义 transition 组件以及三个钩子函数:

<div id="app">

    <input type="button" value="切换动画" @click="isshow = !isshow">
    
    <transition
    
    @before-enter="beforeEnter"
    
    @enter="enter"
    
    @after-enter="afterEnter">
    
      <div v-if="isshow" class="show">OK</div>
    
    </transition>

  </div>
  1. 定义三个 methods 钩子方法:

methods: {

        beforeEnter(el) { // 动画进入之前的回调
    
          el.style.transform = 'translateX(500px)';
    
        },
    
        enter(el, done) { // 动画进入完成时候的回调
    
          el.offsetWidth;
    
          el.style.transform = 'translateX(0px)';
    
          done();
    
        },
    
        afterEnter(el) { // 动画进入完成之后的回调
    
          this.isshow = !this.isshow;
    
        }
    
      }
  1. 定义动画过渡时长和样式:

.show{

      transition: all 0.4s ease;
    
    }

v-for 的列表过渡

  1. 定义过渡样式:

<style>

    .list-enter,.list-leave-to {
    
      opacity: 0;
    
      transform: translateY(10px);
    
    }



    .list-enter-active,.list-leave-active {
    
      transition: all 0.3s ease;
    
    }

</style>
  1. 定义DOM结构,其中,需要使用 transition-group 组件把v-for循环的列表包裹起来:

<div id="app">
    <input type="text" v-model="txt" @keyup.enter="add">
    <transition-group tag="ul" name="list">
        <li v-for="(item, i) in list" :key="i">{{item}}</li>
    </transition-group>
</div>
  1. 定义 VM中的结构:

// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
  el: '#app',
  data: {
    txt: '',
    list: [1, 2, 3, 4]
  },
  methods: {
    add() {
      this.list.push(this.txt);
      this.txt = '';
    }
  }
});

列表的排序过渡

<transition-group> 组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的 v-move 特性,它会在元素的改变定位的过程中应用

v-movev-leave-active 结合使用,能够让列表的过渡更加平缓柔和:

.v-move{
  transition: all 0.8s ease;
}

.v-leave-active{
  position: absolute;
}

以上是关于Vue-自定义过滤器的使用的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在 vue.js 中的自定义搜索过滤器不起作用?

自定义 v-repeat 过滤器 Vue.js

04Vue.js---自定义过滤器

Vue.js学习 Item14 – 过滤器与自定义过滤器

vue-cli 自定义过滤器的使用

vue.js之过滤器,自定义指令,自定义键盘信息以及监听数据变化