一. 常用特性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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

最新文章

  1. redis3.2 Jedis java操作
  2. 简单的 Promise 实现
  3. 利用iframe实现无刷新上传处理
  4. jquery学习笔记---插件开发模式和结构
  5. MetInfo安装
  6. (转)文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别
  7. Splitter
  8. iOS程序性能优化
  9. CentOS系统Apache服务器优化详解
  10. GCC的编译和安装 很好的资料
  11. Android布局管理器(贞布局)
  12. 初学 Canvas &lt;第一篇-基础篇&gt;
  13. c#类初始化器
  14. CodeForces 581D Three Logos
  15. Apriori算法原理总结
  16. 《Java从入门到放弃》入门篇:springMVC数据校验
  17. CentOS7.2编译安装PHP7.2.3之史上最详细步骤。
  18. django csrftoken
  19. QQ如何开通在线客服
  20. 从手机中提取boot.img

热门文章

  1. 【转载】Java泛型(一)
  2. 使用vs进行Nuget打包时的LicenseExpression填写示例参考
  3. 【网易官方】极客战记(codecombat)攻略-地牢-逃脱
  4. 使用pyaudio播放无损音乐(wav)
  5. Debian 系统修改网卡ens33名称为 eth0
  6. Linux环境下mysql报错:bash: mysql: command not found 的解决方法
  7. 一文搞懂vim复制粘贴
  8. Nginx作为静态WEB服务
  9. Python - metaclass元类(图)
  10. Plastic Bottle Manufacturer Profile: Plastic Bottle Forming Process