前言

管道符的外观就是一根竖直线,也就是|。这个熟悉Linux的同学肯定不陌生了。而在Vue中,也常常能看见它的身影。比如Vue的过滤器:

<div>我叫:{{name|nameFilter}}</div>

过滤器的本质就是一种函数方法,类似java里面输入输出包装流,你传进去一个参数,然后根据这个参数,内部做一些变换映射,得到指定结果的过程。与普通方法不同的时,你只需要在你需要加工的参数后面跟上一根竖线然后再加上方法名字就可以了,写法比较简易。

具体实现

一、根据名字调用方法

这个是前提。

1、通过eval函数实现

在普通js中,可以使用eval方法来实现:

/*** 根据方法名字找到方法体* @param methodName* @returns {any}*/
function callMethodByName(methodName) {return eval(methodName)
}/*** 定义一个测试方法* @param p1* @param p2* @returns {*} 返回两个参数的和*/
function testMethod(p1, p2) {return p1 + p2
}const method = callMethodByName('testMethod') // 找到testMethod这个方法const result = method(2, 3) // 执行testMethod方法console.log(result) // 5

在vue中,承载方法的有method、computed和filter。其中computed带有缓存(虽然可以关闭),但是传参实现方式比较特殊,这里不做处理,感兴趣的自己去度娘看看。因此,我们就针对method和filter说一下操作方式。

2、通过method实现

vue的很多钩子都在它自己的$options里面。其中,所有的method会放在$options的method集合中,因此我们可以这样写:

export default {data() {return {}},mounted() {const result = this.$options.methods['testMethod'](5, 5)console.log(result) // 10},methods: {testMethod(p1, p2) {return p1 + p2}}
}

3、通过filter实现

filter的实现和method类似,都是在$options里面。

export default {data() {return {}},mounted() {const result = this.$options.filters['val']('')console.log(result) // --},filters: {val(v) {return v || '--'}}
}

二、实现管道符功能

基础知识讲解完毕后,就可以进入正题了。

举个栗子。

我们从后端获取了一个列表,里面有id,姓名(name),性别(gender),年龄(age),部门(dept)字段
其中性别返回的值为0,1。0-男 1-女 (没有中性,手动滑稽)
dept返回值为100,101,102。100-人力资源部 101-财务部 102-科技部
其余字段真实字符展示。原始数据:
[{"id": "user001","name": "小王","age": 30,"gender": 0,"dept": 100},{"id": "user003","name": "老邓","age": 40,"gender": 1,"dept": 101},{"id": "user003","name": "小芸","age": 27,"gender": 1,"dept": 102}
]

这个案例其实很常见,后端对于一些常量值不会返回真实文字,而是返回一个编码。前端开发拿到编码后需要做一些映射转换,将code转为文字。而这转换的过程就是写一个方法去实现。

现在有个需求,打印出这个列表里面的name、gender和dept字段,并且gender和dept要以汉字展示

1、一般的思路

先定义gender和dept的转换方法:

method: {gender(v) {return v === 1 ? '女' : '男'},dept(v) {let res = ''switch (v) {case 100:res = '人力资源部'breakcase 101:res = '财务部'breakcase 102:res = '科技部'break}return res}}

然后,我们使用List的map功能进行映射:

//映射
const list = data.map(({ name, gender, dept }) => {return {name,gender: this.gender(gender),dept: this.dept(dept)}
})//自定义打印
const print=(list)=> {list.forEach(({ name, gender, dept }) => {console.log(`姓名:${name} 性别:${gender} 部门:${dept}`)})
}print(list)

但是有个问题,就是代码冗余度较高,你看,即使用展开运算符缩减了代码,gender关键字依旧出现了6次。而且,字段越多,我们要补全的就越多。并且一般这种映射方法都是采用filter的。采用filter的话可以在html中以管道符存在,如果是采用filter,那么单独在非html区域因为this指向原因就无法直接使用,就得再写一套method方法,冗余度更高。

2、改进办法

改进办法就是采用自定义管道符实现。我们先将要打印的字段保存到一个数组:

// 待打印字段
const fields = [{prop: '姓名',field: 'name|name'},{prop: '性别',field: 'gender|gender'},{prop: '部门',field: 'dept|dept'}
]

然后遍历每一个字段,在读到filed的时候进行拆分,然后拿到方法名字,计算出映射后的值:

function pipleLine(dataList) {return dataList.map(v => fields.map(({ field = '' }) => {// 仿照vue的系统级filter进行管道格式解析const vals = field.split('|')let val = v[field]if (vals.length > 1) {val = v[vals[0]]// 循环遍历所有的filter进行层层过滤for (let i = 1; i < vals.length; i++) {const filter = this.$options.filters[vals[i]] // 根据名字找到系统的filterif (typeof filter === 'function') {val = filter(val)}}}return val}))
}pipleLine([...])//返回
[{"id": "user001","name": "小王","age": 30,"gender": "男","dept": "人力资源部"},{"id": "user003","name": "老邓","age": 40,"gender": "女","dept": "财务部"},{"id": "user003","name": "小芸","age": 27,"gender": "女","dept": "科技部"}
]

因为管道符可以无限连接,类似:

<div>我叫:{{name|nameFilter|f2|f3....}}</div>

所以我们是遍历了竖线后的每个方法对竖线最左边的原始参数进行处理的。

然后根据需要,自行打印这个列表。

3、遗留问题

vue的过滤器或者方法都是支持带参数的,如果要解析的话,需要匹配两个括号位置,截取中间字符作为参数。这个后面有空再写吧。

另外,上面的方式只针对vue的写法。普通js可以将:

this.$options.filters[vals[i]]转换为:eval(vals[i])

手动撸代码实现Vue管道符过滤器filter功能相关推荐

  1. 机器学习手动撸代码系列3-感知机

    前面讲了线性回归和局部加权线性回归. 今天讲感知机,感知机是模仿人体大脑处理外界信息的一种算法,即输入信号→处理→输出信号. 它是最简单形式的前馈神经网络,是一种二元线性分类器, 把矩阵上的输入x(实 ...

  2. Vue中的过滤器(filter)

    一.Vue中的过滤器是什么 过滤器(filter)是输送介质管道上不可缺少的一种装置,大白话,就是把一些不必要的东西过滤掉,过滤器实质不改变原始数据,只是对数据进行加工处理后返回过滤后的数据再进行调用 ...

  3. vue 分模块打包 脚手架_手动撸一个webpack4脚手架(仿vuecli2)

    其实vue的脚手架是真的多,vue的nuxt脚手架的,vue的webpack脚手架的,还有各种gitHub上的后台管理系统模板的..... 而vue-cli2的webpack模板,这个相信是大多数人最 ...

  4. vsc写vue生成基本代码快捷键_基于vue2.X的webpack基本配置,教你手动撸一个webpack4的配置...

    webpack说复杂也不复杂.不复杂,核心概念不外乎是entry, output, loader, plugins.webpack4还新增了optimization选项,用于代码分割和打包优化.现在w ...

  5. uglifyjs报错 webpack_基于vue2.X的webpack基本配置,教你手动撸一个webpack4的配置

    webpack说复杂也不复杂.不复杂,核心概念不外乎是entry, output, loader, plugins.webpack4还新增了optimization选项,用于代码分割和打包优化.现在w ...

  6. thymealf如何实现传单个变量给html_梦回2013,看尤大vue的第一行代码,如何用30行代码实现vue(超简洁,适合初学者)...

    非非非标题党,干货预警!!! 介绍 大家好,我是清池交友 app 开发日记,记录清池交友 app 开发中学习过程和踩坑日记,伪全栈[1] 技术栈:前端 js,vue,uniapp,后端 java 尤大 ...

  7. vue学习日志-过滤器

    一.过滤器 1.1 概述 (1)过滤器(Filters)提供了一种 执行文本转换的方法,比如说都转换成大写字母或者几乎做任何我们想做的事情. (2)过滤器既可以在 双花括号插值 中使用,也可以在 v- ...

  8. Vue过滤器-filter

    Vue中的过滤器不能替代Vue中的methods.computed或者watch,因为过滤器不改变真正的data,而只是改变渲染的结果,并返回过滤后的版本.在很多不同的情况下,过滤器都是有用的,比如尽 ...

  9. Vue的过滤器(filter)

    在Vue.js中,过滤器主要用于文本的格式化,或者数组数据的过滤与排序等.从Vue.js2.0.0版本开始,内置的过滤器被删除了,如果使用过滤器,需要自己编写.过滤器可以用在两个地方:双花括号插值和v ...

最新文章

  1. Spring-boot-文件上传大小限制
  2. Struts09---验证框架
  3. Linux安装ansible自动化运维工具
  4. pytorch | transpose、permute、view、contiguous、is_contiguous、reshape
  5. api接口响应类型定义
  6. 【Filecoin源码仓库全解析】第一章:搭建Filecoin测试节点
  7. LeetCode 02.两数相加
  8. linux网络编程-----项目管理工具-----Makefile
  9. Mybatis(11)连接池基本介绍
  10. python中什么是序列_在Python中,什么是字符串序列?(或者是油嘴滑舌的虫子?)...
  11. 27-React Lists and Keys
  12. pythonxy官网下载_spyder安装包
  13. 502网关错误解决_“ HTTP 502错误的网关”错误和解决方案
  14. EditPlus下载安装和汉化
  15. 三角形求高公式计算机,三角形已知边长求高公式有哪些
  16. Tomcat网站根目录设置
  17. Windows---diskpart命令的使用
  18. 必须学会的几道家常菜
  19. 大数据有哪些存储方式?
  20. 二维泊松方程求解-SIP-最速下降法-共轭梯度

热门文章

  1. web安全之挖掘Linux内核漏洞
  2. 残差网络resnet详解
  3. 使火狐浏览器默认在新的标签页打开链接
  4. Linux内核符号及地址
  5. 错误解决:These dependencies were not found: core-js/modules/es.array.push.js
  6. 用ASPOSE将PDF转为word(解除页数限制和去水印)
  7. Vivado软件的使用——以led的交替闪烁为例
  8. decode函数的妙用
  9. Unbuntu系统下,切换python版本
  10. 桶排序算法:topK元素golang实现