三vue的过滤器侦听器及计算属性
Posted 上善若水
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三vue的过滤器侦听器及计算属性相关的知识,希望对你有一定的参考价值。
一、过滤器
过滤器
(Filters
)是vue为开发者提供的功能,常用于文本的格式化
。过滤器可以用在两个地方:插值表达式
和v-bind属性绑定
。
过滤器应该被添加在javascript表达式的尾部
,由"管道符
"进行调用,示例代码如下:
1.1、定义过滤器
在创建vue实例期间,可以在filters 节点
中定义过滤器,示例代码如下:
const vm = new Vue(
el: '#app',
data:
message: 'hello world',
info: 'title info'
,
filters: // 在filters节点下定义“过滤器”
capitalize(str) // 把首字母转为大写的过滤器
return str.charAt(0).toUpperCase() + str.slice(1)
)
1.2、私有过滤器
和全局过滤器
在filters节点下定义的过滤器,称为“私有过滤器
”,因为它只能在当前vm实例所控制的el区域内使用
。如果希望在多个vue实例之间共享过滤器
,则可以按照如下的格式定义全局过滤器
:
// 全局过滤器,独立于每个 vm 实例之处
// Vue.filter() 方法接收两个参数
// 第 1 个参数,是全局过滤器的"名字"
// 第 2 个参数,是全局过滤器的"处理函数"
Vue.filter('capitalize', (str) =>
return str.charAt(0).toUpperCase() + str.slice(1) + '---'
)
1.3、连续调用多个过滤器
过滤器可以串联地
进行调用,例如:
<!-- 把 message 的值,交给 filterA 进行处理 -->
<!-- 把 filterA 处理的结果,再交给 filterB 进行处理 -->
<!-- 最终把 filterB 处理的结果,作为最终的值渲染到页面上 -->
message | filterA | filterB
示例代码如下:
备注:如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用的是“私有过滤器”
1.4、过滤器传参
过滤器的本质
是JavaScript函数
,因此可以接收参数,格式如下:
<!-- arg1 和 arg2 是传递给filterA的参数 -->
<p> message | filterA(arg1, arg2)</p>
// 过滤器处理函数的形参列表中:
// 第一个参数:永远都是 “管道符” 前面待处理的值
// 从二个参数开始,才是调用过滤器时传递过来的 arg1 和 arg2 参数
Vue.filter('filterA', (msg, arg1, arg2) =>
// 过滤器的代码逻辑...
)
示例代码如下:
1.5、过滤器的兼容性
过滤器仅在 vue2.x 和 1.x 中受支持,在vue3.x
的版本中剔除了过滤器
相关的功能。
在企业级项目开发中:
- 如果使用的是 2.x 版本的 vue,则依然可以使用过滤器相关的功能
- 如果项目已经升级到了3.x 版本的 vue,官方建议使用
计算属性
或方法
代替被剔除的过滤器功能
1.6、综合案例 — 品牌列表
日期处理库:https://dayjs.fenxianglu.cn/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>品牌列表案例</title>
<link rel="stylesheet" href="./lib/bootstrap.css">
<link rel="stylesheet" href="./css/brandlist.css">
</head>
<body>
<div id="app">
<!-- 卡片区域 -->
<div class="card">
<div class="card-header">
添加品牌
</div>
<div class="card-body">
<!-- 添加品牌的表单区域 -->
<!-- form 表单元素有 submit 事件 -->
<form @submit.prevent="add">
<div class="form-row align-items-center">
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">品牌名称</div>
</div>
<input type="text" class="form-control" placeholder="请输入品牌名称" v-model.trim="brand">
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary mb-2">添加</button>
</div>
</div>
</form>
</div>
</div>
<!-- 表格区域 -->
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">品牌名称</th>
<th scope="col">状态</th>
<th scope="col">创建时间</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in list" :key="item.id">
<td> item.id </td>
<td> item.name </td>
<td>
<div class="custom-control custom-switch">
<!-- 使用 v-model 实现双向数据绑定 -->
<input type="checkbox" class="custom-control-input" :id="'cb' + item.id" v-model="item.status">
<!-- 使用 v-if 结合 v-else 实现按需渲染 -->
<label class="custom-control-label" :for="'cb' + item.id" v-if="item.status">已启用</label>
<label class="custom-control-label" :for="'cb' + item.id" v-else>已禁用</label>
</div>
</td>
<td> item.time | dateFormat </td>
<td>
<a href="javascript:;" @click="remove(item.id)">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 只要导入了 dayjs 的库文件,在 window 全局,就可以使用 dayjs() 方法了 -->
<script src="./lib/dayjs.min.js"></script>
<script src="./lib/vue-2.6.12.js"></script>
<script>
// 声明格式化时间的全局过滤器
Vue.filter('dateFormat', function (time)
// 1. 对 time 进行格式化处理,得到 YYYY-MM-DD HH:mm:ss
// 2. 把 格式化的结果,return 出去
// 直接调用 dayjs() 得到的是当前时间
// dayjs(给定的日期时间) 得到指定的日期
const dtStr = dayjs(time).format('YYYY-MM-DD HH:mm:ss')
return dtStr
)
const vm = new Vue(
el: '#app',
data:
// 用户输入的品牌名称
brand: '',
// nextId 是下一个,可用的 id
nextId: 4,
// 品牌的列表数据
list: [
id: 1, name: '宝马', status: true, time: new Date() ,
id: 2, name: '奔驰', status: false, time: new Date() ,
id: 3, name: '奥迪', status: true, time: new Date() ,
],
,
methods:
// 点击链接,删除对应的品牌信息
remove(id)
this.list = this.list.filter(item => item.id !== id)
,
// 阻止表单的默认提交行为之后,触发 add 方法
add()
// 如果判断到 brand 的值为空字符串,则 return 出去
if (this.brand === '') return alert('必须填写品牌名称!')
// 如果没有被 return 出去,应该执行添加的逻辑
// 1. 先把要添加的品牌对象,整理出来
const obj =
id: this.nextId,
name: this.brand,
status: true,
time: new Date()
// 2. 往 this.list 数组中 push 步骤 1 中得到的对象
this.list.push(obj)
// 3. 清空 this.brand;让 this.nextId 自增 +1
this.brand = ''
this.nextId++
,
)
</script>
</body>
</html>
二、侦听器
2.1、什么是 watch 侦听器
watch 侦听器
允许开发者监视数据的变化,从而针对数据的变化做特定的操作
。
语法格式如下:
const vm = new Vue(
el: '#app',
data:
username: ''
,
watch:
// 监听 username 值的变化
// newVal 是 “变化后的新值”,oldVal 是 “变化之前的旧值”
username(newVal, oldVal)
console.log(newVal, oldVal)
)
2.2、使用 watch 检测用户名是否可用
监听 username 值的变化,并使用 axios 发起 Ajax 请求,检测当前输入的用户名是否可用
:
2.3、immediate 选项
默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器 立即被调用
,则需要使用 immediate
选项。示例代码如下:
2.4、deep 选项
如果watch 侦听的是一个对象
,如果对象中的属性值发生了变化
,则无法被监听到
。此时需要使用deep选项
,代码示例如下:
const vm = new Vue(
el: '#app',
data:
info: username: 'admin'
,
watch:
info:
handler(newVal)
console.log(newVal.username)
,
deep: true
)
2.5、监听对象单个属性的变化
如果只想监听对象中单个属性的变化
,则可以按照如下的方式定义 watch 侦听器:
const vm = new Vue(
el: '#app',
data:
info: username: 'admin'
,
watch:
'info.username':
handler(newVal)
console.log(newVal.username)
)
2.6、总结:
- 方法格式的侦听器
- 缺点1:无法在刚进入页面的时候,自动触发!!!
- 缺点2:如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器!!!
- 对象格式的侦听器
- 优点1:可以通过
immediate
选项,让侦听器自动触发!!! - 优点2:可以通过
deep
选项,让侦听器深度监听对象中每个属性的变化!!!
三、计算属性
3.1、什么是计算属性
计算属性指的是通过一系列运算
之后,最终得到一个属性值
。
这个动态计算出来的属性值
可以被模板结构或 methods 方法使用。示例代码如下:
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue(
el: '#app',
data:
// 红色
r: 0,
// 绿色
g: 0,
// 蓝色
b: 0
,
methods:
// 点击按钮,在终端显示最新的颜色
show()
console.log(this.rgb)
,
// 所有的计算属性,都要定义到 computed 节点之下
// 计算属性在定义的时候,要定义成“方法格式”
computed:
// rgb 作为一个计算属性,被定义成了方法格式,
// 最终,在这个方法中,要返回一个生成好的 rgb(x,x,x) 的字符串
rgb()
return `rgb($this.r, $this.g, $this.b)`
);
3.2、计算属性的特点
- 虽然计算属性在
声明的时候
被定义为方法
,但是计算属性的本质是一个属性
- 计算属性会
缓存计算的结果
,只有计算属性依赖的数据变化时
,才会重新进行运算
3.3、案例
3.3.1、计算属性案例—改造前
<!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.6.12.js"></script>
<style>
.box
width: 200px;
height: 200px;
border: 1px solid #ccc;
</style>
</head>
<body>
<div id="app">
<div以上是关于三vue的过滤器侦听器及计算属性的主要内容,如果未能解决你的问题,请参考以下文章