第三节:Vuejs常用特性2和图书案例
一. 常用特性2
1. 监听器
用watch来响应数据的变化, 一般用于异步或者开销较大的操作, watch 中的属性 一定是data 中 已经存在的数据!!! 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听.
案例1:监听firstName和lastName,当他们发生变化的时候,fullName也发生变化; 该需求也可也把fullName声明成一个计算属性,同样可以达到这个效果。
案例2:输入用户名,当光标离开input标签的时候,进行验证该用户名是否存在。
2. 过滤器
过滤器可以全局注册Vue.filter,也可以局部注册filters。过滤器可以用在两个地方:双花括号插值和v-bind属性表达式。过滤器不改变真正的 data ,而只是改变渲染的结果,并返回过滤后的版本.
(1).第一个参数表示管道符前面的数据,而且过滤器支持级联操作。
比如:{{msg | glq1 | glq2}} 支持多个过滤器
(2).带参数的过滤器: 第一个参数不需要传递,默认就是要过滤的数据,后面可以继续写参数进行传递。
(3).补充一个日期过滤器
3. 实例的生命周期(常用的8个)
(1) beforeCreate: 在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
(2) created: 在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来
(3) beforeMount: 在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已
(4) mounted: el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上在这个钩子函数里面我们可以使用一些第三方的插件,数据的初始化可以放在这里。
(5) beforeUpdate: 数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的
(6) updated: 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的
(7) beforeDestroy: 实例销毁之前调用
(8) destroyed: 实例销毁后调用
4. 变异方法和替换数组、动态响应数据处理
(1).变异方法:
背景:在 Vue 中,直接修改对象属性的值无法触发响应式。当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变。所以:Vue中引入变异数组方法,即保持数组方法原有功能不变的前提下对其进行功能拓展,使其支持响应式。
常用方法如下:
a. push: 往数组最后面添加一个元素,成功返回当前数组的长度。
b. pop: 删除数组的最后一个元素,成功返回删除元素的值
c. shift: 删除数组的第一个元素,成功返回删除元素的值
d. unshift: 往数组最前面添加一个元素,成功返回当前数组的长度
e. splice: 有三个参数,第一个要删除元素的下标(必选),第二个要删除元素的个数(必选),第三个删除后想在原位置替换的值
f. sort: 将数组按照字符编码从小到大排序,成功返回排序后的数组
g. reverse: 将数组倒序排列,并返回倒叙后的数组
(2).替换数组
含义: 不会影响原始的数组数据,而是形成一个新的数组.
常用方法:
a. filter: 创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
b. concat: 用于连接两个或多个数组,该方法不会改变现有的数组。
c. slice: 从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组
eg:从第0个开始,获取两个元素 this.list = this.list.slice(0, 2);
(3).动态响应数据的处理
A. 操作数组
Vue.set(vm.list, 1, 'ypf');
vm.$set(vm.list, 1, 'ypf');
以上两句话是等效的,都表示把list数组中的第二个元素改为ypf。
B. 操作对象
Vue.set(vm.info, 'sex', '女');
vm.$set(vm.info, 'sex', '女');
以上两句话等效,表示给info对象增加一个属性sex,值为‘女’,如果info对象里已经有了sex属性,则执行的是修改操作
代码分享:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>04-常用特性2</title>
<style type="text/css">
p {
color: #0000FF;
font-size: 18px;
} div {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="myApp">
<p>1.监听器的使用</p>
<div>
<div>
<input type="text" v-model="firstName" placeholder="请输入firstName">
<input type="text" v-model="lastName" placeholder="请输入lastName">
</div>
<div>我的全名为:{{fullName}}</div>
</div>
<div>
验证用户名是否存在:<input type="text" v-model.lazy="userName"><span>{{tip}}</span>
</div>
<p>2.过滤器的使用</p>
<div>
<input type="text" v-model="msg">
<div>我是大写过滤器:{{msg|higher}}</div>
<div>我是小写过滤器:{{msg|lower}}</div>
<div :myClass="msg | higher">过滤器加在属性上</div>
<span>多参数过滤器</span>
<input type="text" v-model.number="myNum">
<div>结果为:{{myNum|myadd(10,20)}}</div>
<div>日期过滤器:{{myDate|format('yyyy-MM-dd hh:mm:ss')}}</div>
</div>
<p>4.变异方法和替换数组</p>
<div>
<ul>
<li :key="index" v-for="(item,index) in list">{{item}}</li>
</ul>
<input type="text" v-model='fname'>
<button @click='add'>添加</button>
<button @click='del'>删除</button>
<button @click='change'>替换</button>
</div>
<p>5.动态响应处理</p>
<div>
<button @click='handle1'>响应处理1</button>
<div>
<div>{{info.name}}</div>
<div>{{info.age}}</div>
<div>{{info.sex}}</div>
</div>
<button @click='handle2'>响应处理2</button>
</div>
</div>
<script src="./js/vue.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//全局过滤器(小写过滤器)
Vue.filter('lower', function(val) {
return val.toLowerCase();
});
//多参数过滤器
//val表示要过滤的值,m,n 分别对应传递进来的两个值,对应上面的10和20
Vue.filter('myadd', function(val, m, n) {
if (val < 10) {
return val + m;
} else {
return val + n;
}
});
//补充一个日期过滤器
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: '#myApp',
data: {
firstName: '',
lastName: '',
fullName: '',
userName:'',
tip:'',
msg: '',
myNum: '',
myDate: new Date(),
list: ['apple', 'orange', 'banana'],
fname: '',
info: {
name: 'lmr',
age: 20
}
},
methods: {
//验证用户名
checkUserName:function(uname){
var that=this;
//模拟调用后台
setTimeout(function(){
if (uname=='admin') {
that.tip='存在';
} else{
that.tip='不存在';
}
},1500);
},
//增加
add: function() {
this.list.push(this.fname);
},
//删除最后一个
del: function() {
this.list.pop();
},
//替换
change: function() {
//从第0个开始,获取两个元素
this.list = this.list.slice(0, 2);
},
handle1: function() {
//下面两句话等效,把list数组中的第二个元素改为ypf
Vue.set(vm.list, 1, 'ypf');
// vm.$set(vm.list, 1, 'ypf');
},
handle2: function() {
//下面两句话等效,表示给info对象增加一个属性sex,值为‘女’
// Vue.set(vm.info, 'sex', '女');
vm.$set(vm.info, 'sex', '女');
}
},
computed: {
//这里使用计算属性,也可以达到下面监听器的效果
// fullName:function(){
// return this.firstName+' '+this.lastName;
// }
},
//监听器
watch: {
//val代表该值
firstName: function(val) {
this.fullName = val + ' ' + this.lastName;
},
lastName: function(val) {
this.fullName = this.firstName + ' ' + val;
},
userName:function(val){
this.tip='正在校验中...';
this.checkUserName(val);
}
},
filters: {
//大写过滤器
higher: function(val) {
return val.toUpperCase();
}
} });
</script>
</body>
</html>
运行结果:
二. 图书案例
1. 需求
实现图书系统的显示,删除、修改、增加。
2. 用到的几个数组的技术点:
(1). filter: 根据条件过滤返回一个新数组,function(item){}; item为遍历数组中的元素
(2). some: 用于遍历数组 (item)=>{}, return true; 则结束遍历
(3). findIndex: 查找索引,function(item){}; item为遍历数组中的元素
最终运行效果:
代码分享:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图书系统</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;
}
</style>
</head>
<body>
<div id="myApp">
<div class="grid">
<div>
<h1>图书管理</h1>
<div class="book">
<div>
<label for="id">
编号:
</label>
<input type="text" id="id" v-model='id' :disabled="isEdit">
<label for="name">
名称:
</label>
<input type="text" id="name" v-model='name' @keyup.enter="handle">
<button @click='handle'>提交</button>
</div>
</div>
</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="editShow(item.id)">修改</a>
<span>|</span>
<a href="" @click.prevent="delBook(item.id)">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
</div> <script src="./js/vue.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//日期格式化过滤器
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: '#myApp',
data: {
books: [{
id: 1,
name: '三国演义',
date: 2525609975000
}, {
id: 2,
name: '水浒传',
date: 2525609975000
}, {
id: 3,
name: '红楼梦',
date: 2525609975000
}, {
id: 4,
name: '西游记',
date: 2525609975000
}],
id: '',
name: '',
isEdit: false,
},
methods: {
//增加 或 修改
handle: function() {
if (this.isEdit == false) {
//表示增加
var obj = {};
obj.id = this.id;
obj.name = this.name;
obj.date = 2525609975000;
this.books.push(obj);
// 清空表单
this.id = '';
this.name = '';
} else {
//表示修改
//根据id查找出来book,然后进行修改,可以用filter,这里用另外一种方式 Some,查找出来的同时直接修改
this.books.some((item) => {
if (item.id == this.id) {
item.name = this.name;
//返回true,表示终止循环
return true;
}
});
//清空表单,并恢复可编辑状态
this.id = '';
this.name = '';
this.isEdit = false;
}
},
//把要修改的内容显示在标签内
editShow: function(id) {
//根据id查找符合条件的book信息
var theEditBook = this.books.filter(function(item) {
return item.id == id;
});
//给标签赋值
this.id = theEditBook[0].id;
this.name = theEditBook[0].name;
//id标签位置不可改
this.isEdit = true;
},
//删除图书
delBook: function(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;
});
}
}
});
</script>
</body>
</html>
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
第三节:Vuejs常用特性2和图书案例的更多相关文章
- 第二节: Vuejs常用特性1
一. 常用特性 1. 表单元素 通过 v-model指令绑定 输入框.单选/多选框.下拉框.文本框 2. 表单域修饰符 (1) .number:转换成数值,如果输入的是非数字字符串时,无法进行转换 ( ...
- Vue的常用特性
Vue的常用特性 一.表单基本操作 都是通过v-model 单选框 1. 两个单选框需要同时通过v-model 双向绑定 一个值 2. 每一个单选框必须要有value属性 且value值不能一样 3. ...
- 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- ES6的一些常用特性
由于公司的前端业务全部基于ES6开发,于是给自己开个小灶补补ES6的一些常用特性.原来打算花两天学习ES6的,结果花了3天才勉强过了一遍阮老师的ES6标准入门(水好深,ES6没学好ES7又来了...) ...
- MVC常用特性
MVC常用特性使用 简介 在以前的文章中,我和大家讨论如何用SingalR和数据库通知来完成一个消息监控应用. 在上一篇文章中,我介绍了如何在MVC中对MongoDB进行CRUD操作. 今天,我将 ...
- C#网络程序设计(1)网络编程常识与C#常用特性
网络程序设计能够帮我们了解联网应用的底层通信原理! (1)网络编程常识: 1)什么是网络编程 只有主要实现进程(线程)相互通信和基本的网络应用原理性(协议)功能的程序,才能算是真正的网 ...
- C# XML序列化方法和常用特性
/* C#对象XML序列化(一):序列化方法和常用特性 .Net Framework提供了对应的System.Xml.Seriazliation.XmlSerializer负责把对象序列化到XML,和 ...
- Unity3D编辑器扩展(五)——常用特性(Attribute)以及Selection类
前面写了四篇关于编辑器的: Unity3D编辑器扩展(一)——定义自己的菜单按钮 Unity3D编辑器扩展(二)——定义自己的窗口 Unity3D编辑器扩展(三)——使用GUI绘制窗口 Unity3D ...
- AngularJS 的常用特性(五)
13.使用路由和 $location 切换视图 对于一些单页面应用来说,有时候需要为用户展示或者隐藏一些子页面视图,可以利用 Angular 的 $route 服务来管理这种场景. 你可以利用路由服务 ...
随机推荐
- 解决Cannot download "https://github.com/sass/node-sass/releases/download/binding.nod的问题
npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
- Java - 集合 - Map
Map 1.Map实现类:HashMap.Hashtable.LinkedHashMap.TreeMap HashMap 新增元素/获取元素 1 void contextLoads() { 2 //声 ...
- 生成树计数模板 spoj 104 (不用逆元的模板)
/* 这种题,没理解,只是记一记如何做而已: 生成树的计数--Matrix-Tree定理 题目:SPOJ104(Highways) 题目大意: *一个有n座城市的组成国家,城市1至n编号,其中一些城市 ...
- Bug搬运工-CSCux99539:Intermittent error message "Power supply 2 failed or shutdown"
Description Symptom:Following error messages will be seen intermittently.%PFMA-2-PS_FAIL: Power supp ...
- Codeforces Round #621 (Div. 1 + Div. 2) D
题意: 给n,m,k,有n个点,m条线,距离都是一: 有k个特殊点,选择其中两个,进行相连,距离变为1,使得原本的最短路,经过相连改变小或者不变,最终结果是所有结果里面的最大距离. 思路: 选择i,j ...
- Python 多任务(线程) day2 (1)
结论:多线程全局变量是共享的 (03) 因为多线程一般是配合使用,如果不共享,那么就要等到一个线程执行完,再把变量传递给另一个线程,就变成单线程了 但是如果多个线程同时需要修改一个全局变量,就会出现资 ...
- C++:打开一个文件夹下一系列的文件
可以用MFC的CFileFind类: FILE *pFile=NULL; CFileFind cff; CString fstr="C:\\page\\*.*"//所以用文件和文件 ...
- 05hive函数
一. 系统内置函数 1)查看系统自带的函数 hive> show functions; 2)显示自带的函数的用法 hive> desc function upper; 3)详细显示自带的函 ...
- MyBatis-Spring整合之方式4
直接删除Mybatis的配置文件,修改Beans.xml文件的sqlSessionFactory的参数内容,如下: <!--配置sqlSessionFactory--> <bean ...
- 关于websockets的压测工具
这是在workerman群中得到的信息,记录在此: loadrunner jemeter