zoukankan      html  css  js  c++  java
  • 03 . Vue基础之计算属性,过滤器

    vue计算属性

    /*
    		复杂逻辑,模板难以维护
    				1. 基础例子
    				2. 计算缓存 VS methods
    						- 计算属性是基于他们的依赖进行缓存的.
    						- 计算属性只有在他的相关依赖发生改变时才会重新求值
    				3. 计算属性VS watch
    				    - v-model
    */
    
    侦听器
    /*
    		数据变化时执行异步开销大的操作
    */
    

    Example

    <!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

    验证用户名是否可用

    <!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

    <!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

    <!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

    <!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过滤器

    功能
    /*
    		格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等.
    */
    

    13

    自定义过滤器
    /*
    		Vue.filter('过滤器名称',function(value){
    			// 过滤业务逻辑
    			
    		})
    */
    
    <!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>
    
    
    带参数的过滤器
    Vue.filter('format',function(value,arg1){
    	// Value就是过滤器传递过来的参数
    })
    
    // 使用
    <div>
      {{ date | format{'yyyy-MM-dd' } }}
    </div>
    

    日期格式化规则

    /*
    		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
    */
    

    使用过滤器格式化日期

    <!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>
    
    综合案例
    /*
    		图书列表
    			实现静态列表效果
          基于数据实现模板效果
          处理每行的操作按钮
          
        添加图书
        	实现表单的静态效果
        	添加图书表单域数据绑定
        	添加按钮事件绑定
    			实现添加业务逻辑
    			
    		修改图书
    			修改信息填充到表单
    			修改后重新提交表单
    			重用添加和修改的方法
    			
    		删除图书
    			删除按钮绑定时间处理方法
    			实现删除业务逻辑
    */	
    

    常用特性应用场景

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

    Example1

    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="UTF-8">
    		<title>Document</title>
    		<style type="text/css">
    			.grid {
    				margin: auto;
    				 530px;
    				text-align: center;
    			}
    
    			.grid table {
    				border-top: 1px solid #C2D89A;
    				 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>
    
  • 相关阅读:
    git 删除未提交的文件
    Vmware Ubuntu 开机蓝屏
    php 加入 unless 语法
    Unity 登录白屏或者黑屏
    Ubuntu php + apache
    Ubuntu mysql
    Ubuntu 重装vmtool
    window 后台运行的应用程序点击没反应
    phpstorm格式设置不同导致的Git代码无法正常比较
    phpstorm 设置换行符的格式
  • 原文地址:https://www.cnblogs.com/you-men/p/13975121.html
Copyright © 2011-2022 走看看