前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >03 . Vue基础之计算属性,过滤器

03 . Vue基础之计算属性,过滤器

作者头像
iginkgo18
发布2020-11-24 11:12:28
1.8K0
发布2020-11-24 11:12:28
举报
文章被收录于专栏:devops_k8sdevops_k8s
vue计算属性
代码语言:javascript
复制
/*
		复杂逻辑,模板难以维护
				1. 基础例子
				2. 计算缓存 VS methods
						- 计算属性是基于他们的依赖进行缓存的.
						- 计算属性只有在他的相关依赖发生改变时才会重新求值
				3. 计算属性VS watch
				    - v-model
*/
侦听器
代码语言:javascript
复制
/*
		数据变化时执行异步开销大的操作
*/

Example

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
	</head>
	<body>
		<div id="app">
			<div>
				<span>名:</span>
				<span>
					<input type="text" v-model='firstName'>
				</span>
			</div>
			<div>
				<span>姓:</span>
				<span>
					<input type="text" v-model='lastName'>
				</span>
			</div>
			<div>{{fullName}}</div>
		</div>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">
			/*
      侦听器
    */
			var vm = new Vue({
				el: '#app',
				data: {
					firstName: 'Jim',
					lastName: 'Green',
					// fullName: 'Jim Green'
				},
				computed: {
					fullName: function() {
						return this.firstName + ' ' + this.lastName;
					}
				},
				watch: {
					// firstName: function(val) {
					//   this.fullName = val + ' ' + this.lastName;
					// },
					// lastName: function(val) {
					//   this.fullName = this.firstName + ' ' + val;
					// }
				}
			});
		</script>
	</body>
</html>

Example2

验证用户名是否可用

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

	<head>
		<meta charset="UTF-8">
		<title>Document</title>
	</head>

	<body>
		<div id="app">
			<span>用户名:</span>
			<span>
				<input type="text" v-model.lazy="uname" />
			</span>

			<span>{{ tip }}</span>
		</div>

		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">
			/*
				侦听器
					1. 采用侦听器监听用户名的变化
					2. 调用后台接口进行验证
					3. 根据验证的结果调整提示信息
			*/
			var vm = new Vue({
				el: '#app',
				data: {
					uname: '',
					tip: ''
				},
				methods: {
					checkName: function(uname) {
						// 调用接口,但是可以使用定时任务方式模拟接口调用
						var that = this
						setTimeout(function() {
							// 模拟接口调用
							if (uname == "admin") {
								that.tip = '用户名已经存在,请更换一个'
							} else {
								that.tip = '用户名可以使用'
							}
						}, 2000)
					}
				},
				watch: {
					uname: function(val) {
						/// 调用后台接口验证用户名的合法性
						this.checkName(val)

						// 修改提示信息
						this.tip = '正在用户名验证中'
					}
				}
			})
		</script>
	</body>
</html>
计算属性案例

Example1

代码语言:javascript
复制
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<title>Examples</title>
		<meta name="description" content="">
		<meta name="keywords" content="">
		<link href="" rel="stylesheet">
		<script type="text/javascript" src="lib/vue.js"></script>
	</head>
	<body>

		<div id="box">
			<!-- 截取myname字符串将首字母大写,不推荐,请看下面 -->
			{{ myname.substring(0,1).toUpperCase() + myname.substring(1) }}
			
			<!-- 不要加(),否则就是函数 -->
			<p>计算属性:{{ getMyName }}</p>
			<p>普通方法:{{ getMyNameMethod() }}</p>
			
			<div>
				也需要计算结果
				<p>计算属性:{{ getMyName }}</p>
				<!-- 计算属性可以让一个页面多个地方调用一个计算结果只调用一次,而方法多次调用会多次执行  -->
				<!-- 1. 依赖的状态改变了, 计算属性会重新计算一遍  
					 2. 计算属性会缓存  -->
				<p>普通方法:{{ getMyNameMethod() }}</p>
			</div>
		</div>

		<script>
			vm = new Vue({
				el: "#box",
				data: {
					myname: "xiaoming"
				},
				
				methods:{
					getMyNameMethod(){
						console.log("getMyNameMethos-方法调用")
						return this.myname.substring(0,1).toUpperCase() + this.myname.substring(1)					}
				},
				
				computed:{
					getMyName(){
						console.log("getMyName-计算属性调用")
						return this.myname.substring(0,1).toUpperCase() + this.myname.substring(1)
					}
				}
			})
		</script>
	</body>
</html>

Example2

代码语言:javascript
复制
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<title>Examples</title>
		<meta name="description" content="">
		<meta name="keywords" content="">
		<link href="" rel="stylesheet">
		<script type="text/javascript" src="lib/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<input type="text" v-model="mytext" />
			<!-- <input type="text" @input="handleInput()" v-model="mytext" /> -->

			<ul>
				<li v-for="data in getMyDatalist">
					{{ data }}
				</li>
			</ul>
		</div>

		<script type="text/javascript">
			var vm = new Vue({
				el: "#box",
				data: {
					mytext: "",
					datalist: ["aaa", "bbb", "ccc", "ddd", "eee", ],
				},

				computed: {
					getMyDatalist() {
						return this.datalist.filter(item => item.indexOf(this.mytext) > -1)
					}
				},
			})
		</script>

	</body>
</html>

Example3

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

	<head>
		<meta charset="UTF-8">
		<title>Document</title>
	</head>

	<body>
		<div id="app">
			<div>{{ reverseString }}</div>
			<div>{{ reverseString }}</div>
			<div>{{ reverseMessage() }}</div>
			<div>{{ reverseMessage() }}</div>
		</div>

		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {
					msg: 'hello',
					num: 100
				},
				methods: {
					reverseMessage: function() {
						console.log('methods')
						return this.msg.split('').reverse().join('')
					}
				},
				computed: {
					reverseString: function() {
						// return this.msg.split('').reverse().join()
						console.log('computed')
						var total = 0
						for (var i = 0; i <= this.num; i++) {
							total += i
						}
						return total
					}
				}
			})
		</script>
	</body>
</html>
Vue过滤器
功能
代码语言:javascript
复制
/*
		格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等.
*/
13
13
自定义过滤器
代码语言:javascript
复制
/*
		Vue.filter('过滤器名称',function(value){
			// 过滤业务逻辑
			
		})
*/
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
	</head>
	<body>
		<div id="app">
			<input type="text" v-model='msg'>
			<div>{{msg |upper }}</div>
			<div>{{msg |lower }}</div>
			<div :abc='msg |upper'>测试数据</div>
		</div>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">
			/*
			  过滤器
			  1、可以用与插值表达式和属性绑定
			  2、支持级联操作
			*/
			Vue.filter('upper', function(val) {
				return val.charAt(0).toUpperCase() + val.slice(1)
			})

			Vue.filter('lower', function(val) {
				return val.charAt(0).toLowerCase() + val.slice(1)
			})

			var vm = new Vue({
				el: '#app',
				data: {
					msg: ''
				}
			})
		</script>
	</body>
</html>
带参数的过滤器
代码语言:javascript
复制
Vue.filter('format',function(value,arg1){
	// Value就是过滤器传递过来的参数
})

// 使用
<div>
  {{ date | format{'yyyy-MM-dd' } }}
</div>

日期格式化规则

代码语言:javascript
复制
/*
		y: 	年
		M:  年中的月份(1-12)
		d:  月份中的天(1-31)
		h:  小时(0-23)
		m:  分(0-59)
		s:  秒(0-59)
		S:  毫秒(0-999)
		q:  季度(1-4)
		
		时间格式化为yyyy-MM-dd
*/

使用过滤器格式化日期

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
	</head>
	<body>
		<div id="app">
			<div>{{date | format('yyyy-MM-dd hh:mm:ss')}}</div>
		</div>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">
			/*
      过滤器案例:格式化日期
      
    */
			// Vue.filter('format', function(value, arg) {
			//   if(arg == 'yyyy-MM-dd') {
			//     var ret = '';
			//     ret += value.getFullYear() + '-' + (value.getMonth() + 1) + '-' + value.getDate();
			//     return ret;
			//   }
			//   return value;
			// })
			Vue.filter('format', function(value, arg) {
				function dateFormat(date, format) {
					if (typeof date === "string") {
						var mts = date.match(/(\/Date\((\d+)\)\/)/);
						if (mts && mts.length >= 3) {
							date = parseInt(mts[2]);
						}
					}
					date = new Date(date);
					if (!date || date.toUTCString() == "Invalid Date") {
						return "";
					}
					var map = {
						"M": date.getMonth() + 1, //月份 
						"d": date.getDate(), //日 
						"h": date.getHours(), //小时 
						"m": date.getMinutes(), //分 
						"s": date.getSeconds(), //秒 
						"q": Math.floor((date.getMonth() + 3) / 3), //季度 
						"S": date.getMilliseconds() //毫秒 
					};

					format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
						var v = map[t];
						if (v !== undefined) {
							if (all.length > 1) {
								v = '0' + v;
								v = v.substr(v.length - 2);
							}
							return v;
						} else if (t === 'y') {
							return (date.getFullYear() + '').substr(4 - all.length);
						}
						return all;
					});
					return format;
				}
				return dateFormat(value, arg);
			})
			var vm = new Vue({
				el: '#app',
				data: {
					date: new Date()
				}
			});
		</script>
	</body>
</html>
综合案例
代码语言:javascript
复制
/*
		图书列表
			实现静态列表效果
      基于数据实现模板效果
      处理每行的操作按钮
      
    添加图书
    	实现表单的静态效果
    	添加图书表单域数据绑定
    	添加按钮事件绑定
			实现添加业务逻辑
			
		修改图书
			修改信息填充到表单
			修改后重新提交表单
			重用添加和修改的方法
			
		删除图书
			删除按钮绑定时间处理方法
			实现删除业务逻辑
*/	

常用特性应用场景

代码语言:javascript
复制
/*
		过滤器(格式化日期)
		自定义指令(获取表单焦点)
		计算属性(统计图书数量)
		侦听器(验证图书存在性)
		生命周期(图书数据处理)
*/

Example1

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
		<style type="text/css">
			.grid {
				margin: auto;
				width: 530px;
				text-align: center;
			}

			.grid table {
				border-top: 1px solid #C2D89A;
				width: 100%;
				border-collapse: collapse;
			}

			.grid th,
			td {
				padding: 10;
				border: 1px dashed #F3DCAB;
				height: 35px;
				line-height: 35px;
			}

			.grid th {
				background-color: #F3DCAB;
			}

			.grid .book {
				padding-bottom: 10px;
				padding-top: 5px;
				background-color: #F3DCAB;
			}

			.grid .total {
				height: 30px;
				line-height: 30px;
				background-color: #F3DCAB;
				border-top: 1px solid #C2D89A;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<div class="grid">
				<div>
					<h1>图书管理</h1>
					<div class="book">
						<div>
							<label for="id">
								编号:
							</label>
							<input type="text" id="id" v-model='id' :disabled="flag" v-focus>
							<label for="name">
								名称:
							</label>
							<input type="text" id="name" v-model='name'>
							<button @click='handle' :disabled="submitFlag">提交</button>
						</div>
					</div>
				</div>
				<div class="total">
					<span>图书总数:</span>
					<span>{{total}}</span>
				</div>
				<table>
					<thead>
						<tr>
							<th>编号</th>
							<th>名称</th>
							<th>时间</th>
							<th>操作</th>
						</tr>
					</thead>
					<tbody>
						<tr :key='item.id' v-for='item in books'>
							<td>{{item.id}}</td>
							<td>{{item.name}}</td>
							<td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
							<td>
								<a href="" @click.prevent='toEdit(item.id)'>修改</a>
								<span>|</span>
								<a href="" @click.prevent='deleteBook(item.id)'>删除</a>
							</td>
						</tr>
					</tbody>
				</table>
			</div>
		</div>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">
			/*
      图书管理-添加图书
    */
			Vue.directive('focus', {
				inserted: function(el) {
					el.focus();
				}
			});

			Vue.filter('format', function(value, arg) {
				function dateFormat(date, format) {
					if (typeof date === "string") {
						var mts = date.match(/(\/Date\((\d+)\)\/)/);
						if (mts && mts.length >= 3) {
							date = parseInt(mts[2]);
						}
					}
					date = new Date(date);
					if (!date || date.toUTCString() == "Invalid Date") {
						return "";
					}
					var map = {
						"M": date.getMonth() + 1, //月份 
						"d": date.getDate(), //日 
						"h": date.getHours(), //小时 
						"m": date.getMinutes(), //分 
						"s": date.getSeconds(), //秒 
						"q": Math.floor((date.getMonth() + 3) / 3), //季度 
						"S": date.getMilliseconds() //毫秒 
					};
					format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
						var v = map[t];
						if (v !== undefined) {
							if (all.length > 1) {
								v = '0' + v;
								v = v.substr(v.length - 2);
							}
							return v;
						} else if (t === 'y') {
							return (date.getFullYear() + '').substr(4 - all.length);
						}
						return all;
					});
					return format;
				}
				return dateFormat(value, arg);
			})
			var vm = new Vue({
				el: '#app',
				data: {
					flag: false,
					submitFlag: false,
					id: '',
					name: '',
					books: []
				},
				methods: {
					handle: function() {
						if (this.flag) {
							// 编辑图书
							// 就是根据当前的ID去更新数组中对应的数据
							this.books.some((item) => {
								if (item.id == this.id) {
									item.name = this.name;
									// 完成更新操作之后,需要终止循环
									return true;
								}
							});
							this.flag = false;
						} else {
							// 添加图书
							var book = {};
							book.id = this.id;
							book.name = this.name;
							book.date = 2525609975000;
							this.books.push(book);
							// 清空表单
							this.id = '';
							this.name = '';
						}
						// 清空表单
						this.id = '';
						this.name = '';
					},
					toEdit: function(id) {
						// 禁止修改ID
						this.flag = true;
						console.log(id)
						// 根据ID查询出要编辑的数据
						var book = this.books.filter(function(item) {
							return item.id == id;
						});
						console.log(book)
						// 把获取到的信息填充到表单
						this.id = book[0].id;
						this.name = book[0].name;
					},
					deleteBook: function(id) {
						// 删除图书
						// 根据id从数组中查找元素的索引
						// var index = this.books.findIndex(function(item){
						//   return item.id == id;
						// });
						// 根据索引删除数组元素
						// this.books.splice(index, 1);
						// -------------------------
						// 方法二:通过filter方法进行删除
						this.books = this.books.filter(function(item) {
							return item.id != id;
						});
					}
				},
				computed: {
					total: function() {
						// 计算图书的总数
						return this.books.length;
					}
				},
				watch: {
					name: function(val) {
						// 验证图书名称是否已经存在
						var flag = this.books.some(function(item) {
							return item.name == val;
						});
						if (flag) {
							// 图书名称存在
							this.submitFlag = true;
						} else {
							// 图书名称不存在
							this.submitFlag = false;
						}
					}
				},
				mounted: function() {
					// 该生命周期钩子函数被触发的时候,模板已经可以使用
					// 一般此时用于获取后台数据,然后把数据填充到模板
					var data = [{
						id: 1,
						name: '三国演义',
						date: 2525609975000
					}, {
						id: 2,
						name: '水浒传',
						date: 2525609975000
					}, {
						id: 3,
						name: '红楼梦',
						date: 2525609975000
					}, {
						id: 4,
						name: '西游记',
						date: 2525609975000
					}];
					this.books = data;
				}
			});
		</script>
	</body>
</html>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • vue计算属性
    • 侦听器
      • 计算属性案例
      • Vue过滤器
        • 功能
          • 自定义过滤器
            • 带参数的过滤器
              • 综合案例
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档