面试题三:请你谈一谈Vue中的filter功能的实现

2023-09-15 10:30:33

Vue中过滤器(filter)的使用

我们想一下有methods为什么要有filter的存在呢,因为filter的实现效率比methods要高的多。

看一下官方定义:

Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:

1. 局部过滤器(使用最频繁)

语法

  • template
<div>{{ name | judgeRole }}</div>
//或者
<div v-bind:id="rawId | formatId"></div>

上面的过滤器经过一顿操作之后就会变成:_s(_f("capitalize")(message))。

_f:该函数其实就是resolveFilter的别名,作用是从_this.$options.filter找到过滤器并返回
_s:该函数就是toString函数的别名,作用是拿到过滤之后的结果并传递给toString()函数,结果会保存到VNode中的text属性,返回结果直接渲染视图
 

_f函数的原理 

_f函数其实就是寻找过滤器的,如果找到过滤器就返回过滤器,找不到就返回与参数相同的值。它的代码其实很简单:

import {identity, resolveAssets} from 'core/util/index'

export function resolveFilter(id){
  return resolveAssets(this.$options, 'filters', id, true) || identity
}

我们重点来看一下resolveAssets到底做了什么事情。

export function resolveAsset (options, type, id, warnMissing){
  if(typeof(id) !== 'string'){
    return
  }
  
  const assets = options[type]
  if(hasOwn(assets, id)) return assets[id]
  const camelizedId = camelize(id)
  if(hasOwn(assets, camelizedId)) return assets[camelizedId]
  const PascalCaseId = capitlize(camelizedId)
  if(hasOwn(assets, PascalCaseId)) return assets[PascalCaseId]
  
  //检查原型链
  const res assets[id] || assets[camelizedId] || PascalCaseId
  if(process.env.NODE_ENV!=='production'&& warnMissing&&!res){
    warn('Fail to resolve' + type.slice(0,-1)+':'+id, options)
  }
  return res
}

其实它的寻找过程也很简单,主要是做了以下的操作(id是过滤器id):

1.判断过滤器id是否为字符串,不是则终止
2.用assets存储过滤器
3.hasOwn函数检查assets自身是否存在id属性,存在则返回
4.hasOwn函数检查assets自身是否存在驼峰化后的id属性,存在则返回
5.hasOwn函数检查assets自身是否存在将首字母大写后的id属性,存在则返回
6.如果还是没有,就是去原型链找,找不到就会打印警告

过滤器解析原理

我们想一下,解析器是怎么解析过滤器的语法?其实在vue内部专门有这么一个函数用来解析过滤器语法:parseFilters

它的原理就是解析过滤器列表,然后循环过滤器列表拼接字符串

  • script
filter:{
    judgeRole(val) {
      if (val === '0') {
        return '平台'
      } else if (val === '1') {
        return '企业'
      } else if (val === '2') {
        return '企业用户'
      } else {
        return ''
      }
    }

}

说明

  • 过滤器函数中的value,就是 |前面的值,它相当于第一个参数
  • 在过滤器函数中一定要返回一个值,他就是我们对格式处理后的结果
  • 通俗的来讲,当为一个数据绑定一个过滤器后,每一次渲染这个数据的时候,他都会调用相应过滤器的函数

实战

使用vue-cli下载一个默认的项目,我使用vue/cli4默认的目录如下 

1.在components文件夹下新建FilterLoc.vue表示局部的过滤器,并写上如下代码,我们的目的是把sunwukong首字母变成大写

<template>
    <div>{{name | capitalize}}</div>
</template>

<script>
export default {
    data(){
        return {
            name:'sunwukong'
        }
    },
    filters:{
        //当value改变的时候,他会执行这个函数
        capitalize:function (value) {
            //一定要返回一个值才能在组件中正常显示
            if (!value) return ''
            value = value.toString()
            return value.charAt(0).toUpperCase() + value.slice(1)
        }
    }
}
</script>

2.我们在App.vue中引入并映射成组件

<template>
    <div><filter-loc></filter-loc></div>
</template>

<script>
import FilterLoc from '@/components/FilterLoc'
export default {
    components:{
        FilterLoc
    }
}
</script>

3.运行项目,观察效果,我们发下sunwukong首字母已经大写

2. 全局过滤器

1.我们可以在入口文件定义全局过滤器,当然也可以是其他文件,这里我们把最后一个首字母变成大写

  • main.js
/* 定义全局过滤器 */
Vue.filter('capitalize', function (value) {
  if (!value) return ''
  const length = value.length - 1
  value = value.toString()
  return value.slice(0,length) + value.charAt(length).toUpperCase() 
})

2.在components文件夹下新建FilterGlo.vue表示使用全局过滤器,并写上如下代码,直接使用过滤器

<template>
    <div>{{name | capitalize}}</div>
</template>

<script>
export default {
    data(){
        return {
            name:'zhubajie'
        }
    }
}
</script>

 3.我们在App.vue中引入并映射成组件,运行项目观察效果

说明
4. 其实刚刚我们定义了两个id相同的过滤器,但是我们发现局部的并没有改变,于是我们就发现了,过滤器的优先级:局部的要比全局的优先级高;

3. 串联过滤器

语法

<div>{{ message | filterA | filterB }}</div>
  • 后一个过滤器接收的参数为前一个参数的返回值

实战

1.在components文件夹下新建FilterSer.vue表示使用串联过滤器,并写上如下代码,直接使用全局过滤器(尾字母大写),和我们自定义的过滤器(首字母大写)

<template>
    <div>{{name|initalWord|capitalize}}</div>
</template>

<script>
export default {
    data(){
        return {
            name:'shawujing'
        }
    },
    filters:{
        initalWord:function (value) {
            if (!value) return ''
            value = value.toString()
            return value.charAt(0).toUpperCase() + value.slice(1)
        }
    }
}
</script>

 2.我们在App.vue中引入并映射成组件,运行项目观察效果,我们发现两个选择器都使用上了

4. 过滤器的参数

语法

<div>{{ message | filterA('arg1', arg2) }}</div>

实战

  1. components文件夹下新建FilterParam.vue表示使用过滤器参数,并写上如下代码,定义了一个过滤器,并传递了参数

<template>
    <div>{{name|paramsFil('白骨精','白龙马')}}</div>
</template>

<script>
export default {
    data(){
        return {
            name:'师徒四人'
        }
    },
    filters:{
        paramsFil:function (value,arg1,arg2) {
            console.log(value,arg1,arg2)
            return value + arg1 + arg2
        }
    }
}
</script>

我们在App.vue中引入并映射成组件,运行项目观察效果带上了所需要的参数。

  • 通过filterA('arg1', arg2)传入的参数为过滤器的后两个参数

 这个filter已经是非常全了,希望对于各位同仁有一定的帮助,面试如果这样回答关于filter的话,已经非常全了,因为里边包括了空间权重情况,多参数情况,多过滤情况,全面。另外预祝同仁工作顺利,家庭和睦。

更多推荐

产品新闻稿件怎么写?纯干货

写产品新闻稿件需要遵循一定的结构和写作规范,接下来伯乐网络传媒来给大家分享一下,以下是一些建议和步骤,供您参考:标题:使用简洁、准确的语言来概括产品的核心信息,吸引读者的兴趣。导语/导览:在开篇部分,以简洁明了的语句引起读者的兴趣,概述产品的主要特点和亮点。产品背景:介绍产品推出的背景和动机,例如市场需求、行业趋势或竞

【教程】AERMOD高斯稳态扩散模型

查看原文>>>基于AERMOD模型在大气环境影响评价中的实践应用随着我国经济快速发展,我国面临着日益严重的大气污染问题。近年来,严重的大气污染问题已经明显影响国计民生,引起政府、学界和人们越来越多的关注。大气污染是工农业生产、生活、交通、城市化等方面人为活动的综合结果,同时气象因素是控制大气污染的关键自然因素。大气污染

基础概念回顾:云原生应用交付

原文链接:基础概念回顾:云原生应用交付转载来源:NGINX开源社区NGINX唯一中文官方社区,尽在nginx.org.cn尽管云原生应用开发诞生于21世纪初,但是在术语使用方面还是非常混乱。本文将带您了解常见的术语和问题。云原生云原生计算基金会(CNCF)对“云原生”的定义如下:云原生技术允许企业在公有云、私有云和混合

数据结构-----栈(栈的初始化、建立、入栈、出栈、遍历、清空等操作)

目录前言栈1.定义2.栈的特点3.栈的储存方式3.1数组栈3.2链栈4.栈的基本操作(C语言)4.1初始化4.2判断是否满栈4.3判断空栈4.4入栈4.5出栈4.6获取栈顶元素4.7遍历栈4.8清空栈完整代码示例前言大家好呀!今天我们开始学习新的线性表结构----栈,前面我们学习了链表以及链表的相关操作,那么栈跟链表有

java高级:注解

目录认识注解&自定义注解元注解解析注解注解的应用场景认识注解&自定义注解注解和反射一样,都是用来做框架的,我们这里学习注解的目的其实是为了以后学习框架或者做框架做铺垫的。先来认识一下什么是注解?Java注解是代码中的特殊标记,比如@Override、@Test等,作用是:让其他程序根据注解信息决定怎么执行该程序。比如:

【Powershell 】(Windows下)常用命令 | 命令别名 | 运行Windows命令行工具 | 运行用户程序(vim、gcc、gdb)

微软官方Powershell文档:https://learn.microsoft.com/zh-cn/powershell/命令详细说明,在PDF的最后面:一、Powershell及命令简介1.1命令格式1.2命令的别名二、cmdlet别名三、cmdlet分类介绍3.1基础命令1.Get-Command2.Get-He

什么是Web浏览器的缓存机制?如何控制和清除浏览器缓存?

聚沙成塔·每天进步一点点⭐专栏简介⭐Web浏览器的缓存机制⭐浏览器缓存的工作原理⭐控制和清除浏览器缓存控制缓存⭐清除缓存⭐写在最后⭐专栏简介前端入门之旅:探索Web开发的奇妙世界欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是

JVM面试题(三)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言二、java中垃圾收集的方法有哪些?1.标记-清除:2.复制算法:3.标记-整理4.分代收集三、java内存模型四、简述java类加载机制?五、类加载器双亲委派模型机制?六、什么是类加载器,类加载器有哪些?七、简述java内存分配与回收策率以及

[echarts] 两侧堆叠柱状图

http://echarts.zhangmuchen.top/#/detail?cid=xOQSXIOQiKconstmyData=['福田区','罗湖区','南山区','盐田区','宝安区','龙岗区','坪山区','龙华区','光明区','大鹏区'];//全彩屏,双基色屏,简易屏,条形屏constoffLine=[

大型游戏动作竞技游戏开发和体感VR/AR游戏开发:创造引人入胜的虚拟世界

大型游戏动作竞技游戏和体感VR/AR游戏都代表了游戏开发领域的最新趋势。它们提供了高度沉浸式的娱乐体验,结合了视觉、听觉和体感互动。在本文中,我们将探讨如何开发这两种类型的游戏,并介绍其关键特点和开发流程。大型游戏动作竞技游戏的特点高品质图形:这些游戏通常具有引人入胜的3D图形,精美的场景和角色模型。多人在线模式:大多

运维:Powershell面向对象编程简介

运维/powershellPowershell面向对象编程简介作者:李俊才(jcLee95):https://blog.csdn.net/qq_28550263邮箱:291148484@163.com本文地址:https://blog.csdn.net/qq_28550263/article/details/13287

热文推荐