第三节: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 服务来管理这种场景. 你可以利用路由服务 ...
随机推荐
- THINKPHP 模板上传图片--后台接收图片
模板 {extend name="public/base" /} {block name="body"} <div class="row&quo ...
- JS高级---把随机数对象暴露给window成为全局对象
通过自调用函数产生一个随机数对象, 在自调用函数外面, 调用该随机数对象方法产生随机数 把随机数对象暴露给window成为全局对象 全局变量 自调用一个函数 创建一个空的随机构造函数,给原型对 ...
- 2.5 【配置环境】多浏览器驱动 (chrome、IE、Firefox)❀
来源:http://blog.csdn.net/huilan_same/article/details/51896672 http://www.cnblogs.com/thinkCoding/p/64 ...
- C++记录(一)
1 extern 符表示该变量不是当前作用域定义的,用于声明. 如extern i;表示i不是当前作用域里的,是其他某个include的cpp文件里的变量. 2 int *p=0;相当于初始化p为空指 ...
- Nginx做缓存
查看服务 netstat -lntp|grep 80 Nginx作为缓存WEB服务 通常情况下缓存是用来减少后端压力, 将压力尽可能的往前推, 减少后端压力,提高网站并发延时 Nginx代理缓存原理 ...
- C# 篇基础知识9——特性、程序集和反射
特性(Attribute)是用于为程序元素添加额外信息的一种机制.比如记录文件修改时间或代码作者.提示某方法已经过期.描述如何序列化数据等等.方法.变量.属性.类.接口.结构体以及程序集等都是程序元素 ...
- tarjan-无向图(求割点)
一.基本概念 1.割点:无向连通图中,如果删除某点后,图变成不连通,则称改点为割点. 2.桥:无向连通图中,如果去掉某条边后,整张无向图会分成两部分(即整张图不连通),这样的一条边成为桥. 3.点双连 ...
- mybatis 源码分析--日志分析
1. MyBatis 没有提供日志实现,需要接入第三方的日志组件,但是第三方的日志组件都各自的Log级别,而不相同 实现方式:适配器模式 Slf4jImpl 2. 自动扫描日志实现,并且第三方日志 ...
- 消息队列(五)--- RocketMQ-消息存储4
问题 index 文件有什么作用,结构又是如何 概述 index 文件主要是为了 message key 服务的,rocketmq 发送消息的时候可以带上 key , messge key 是为了标识 ...
- HITCON-Training-master 部分 Writeup(1月30更新)
0x01.lab3 首先checksec一下,发现连NX保护都没开,结合题目提示ret2sc,确定可以使用shellcode得到权限. IDA查看伪代码 大致分析: 将shellcode写入name数 ...