一、表单基本操作
都是通过 v -model
- 单选框
1、两个单选框须要同时通过 v -model 双向绑定 一个值
2、每一个单选框必须要有 value 属性 且 value 值不能一样
3、当某一个单选框选中的时候 v-model 会将以后的 value 值 扭转 data 中的 数据
gender 的值就是选中的值,咱们只须要实时监控他的值就能够了
<input type="radio" id="male" value="1" v-model='gender'>
<label for="male"> 男 </label>
<input type="radio" id="female" value="2" v-model='gender'>
<label for="female"> 女 </label>
<script>
new Vue({
el: '#app',
data: {
// 默认会让以后的 value 值为 2 的单选框选中
gender: 1,
},
})
</script>
-
复选框
- 复选框
checkbox
这种的组合时 data 中的 hobby 咱们要定义成数组 否则无奈实现多选
1、复选框须要同时通过 v -model 双向绑定 一个值 2、每一个复选框必须要有 value 属性 且 value 值不能一样 3、当某一个单选框选中的时候 v-model 会将以后的 value 值 扭转 data 中的 数据 hobby 的值就是选中的值,咱们只须要实时监控他的值就能够了 <div> <span> 喜好:</span> <input type="checkbox" id="ball" value="1" v-model='hobby'> <label for="ball"> 篮球 </label> <input type="checkbox" id="sing" value="2" v-model='hobby'> <label for="sing"> 唱歌 </label> <input type="checkbox" id="code" value="3" v-model='hobby'> <label for="code"> 写代码 </label> </div> <script> new Vue({ data: { // 默认会让以后的 value 值为 2 和 3 的复选框选中 hobby: ['2', '3'], }, }) </script>
- 复选框
-
下拉框和文本框
<div> <span> 职业:</span> <!-- 1、须要给 select 通过 v -model 双向绑定 一个值 2、每一个 option 必须要有 value 属性 且 value 值不能一样 3、当某一个 option 选中的时候 v-model 会将以后的 value 值 扭转 data 中的 数据 occupation 的值就是选中的值,咱们只须要实时监控他的值就能够了 --> <!-- multiple 多选 --> <select v-model='occupation' multiple> <option value="0"> 请抉择职业...</option> <option value="1"> 老师 </option> <option value="2"> 软件工程师 </option> <option value="3"> 律师 </option> </select> <!-- textarea 是 一个双标签 不须要绑定 value 属性的 --> <textarea v-model='desc'></textarea> </div> <script> new Vue({ data: { // 默认会让以后的 value 值为 2 和 3 的下拉框选中 occupation: ['2', '3'], desc: 'nihao' }, }) </script>
表单域修饰符
-
.number 将值转换为数值类型
- 如过输出以数字结尾的值,前面有夹杂非数组模式的字符串(如字母中文和其余符号)的话,属性值得到则是第一个非数字局部后面的所有数字。
- 如果输出的值以字符串结尾,则无奈转换成数字。
-
.trim 主动过滤用户输出的首尾空白字符
- 只能去掉首尾的,不能去除两头的空格
-
.lazy 将 input 事件切换成 change 事件
- .lazy 修饰符提早了同步更新属性值的机会。将 v -model 本来绑定在 input 事件的同步逻辑转变为绑定在 change 事件上。
- 在失去焦点 或者 按下回车键时才更新
<!-- 主动将用户的输出值转为数值类型 --> <input v-model.number="age" type="number"> <!-- 主动过滤用户输出的首尾空白字符 --> <input v-model.trim="msg"> <!-- 在“change”时而非“input”时更新 --> <input v-model.lazy="msg" >
二、自定义指令
- 内置指令不能满足咱们非凡的需要
- Vue 容许咱们自定义指令
Vue.directive 注册全局指令
<!--
应用自定义的指令,只需在对用的元素中,加上 'v-' 的前缀造成相似于外部指令 'v-if','v-text' 的模式。-->
<input type="text" v-focus>
<script>
// 留神点:// 1、在自定义指令中 如果以驼峰命名的形式定义 如 Vue.directive('focusA',function(){})
// 2、在 HTML 中应用的时候 只能通过 v-focus-a 来应用
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
// 当绑定元素插入到 DOM 中。其中 el 为 dom 元素
inserted: function (el) {
// 聚焦元素
el.focus();}
});
new Vue({el:'#app'});
</script>
Vue.directive 注册全局指令 带参数
binding 对象的 name 属性对应自定义指令的名称,value 属性对应自定义指令的值
<input type="text" v-color='msg'>
<script type="text/javascript">
/*
自定义指令 - 带参数
bind - 只调用一次,在指令第一次绑定到元素上时候调用
*/
Vue.directive('color', {
// bind 申明周期, 只调用一次,指令第一次绑定到元素时调用。在这里能够进行一次性的初始化设置
// el 为以后自定义指令的 DOM 元素
// binding 为自定义的函数形参 通过自定义属性传递过去的值 存在 binding.value 外面
bind: function(el, binding){
// 依据指令的参数设置背景色
// console.log(binding.value.color)
el.style.backgroundColor = binding.value.color;
}
});
var vm = new Vue({
el: '#app',
data: {
msg: {color: 'blue'}
}
});
</script>
自定义指令部分指令
- 部分指令,须要定义在 directives 的选项 用法和全局用法一样
- 部分指令只能在以后组件外面应用
- 当全局指令和部分指令同名时以部分指令为准
<input type="text" v-color='msg'>
<input type="text" v-focus>
<script type="text/javascript">
/*
自定义指令 - 部分指令
*/
var vm = new Vue({
el: '#app',
data: {
msg: {color: 'red'}
},
// 部分指令,须要定义在 directives 的选项
directives: {
color: {bind: function(el, binding){el.style.backgroundColor = binding.value.color;}
},
focus: {inserted: function(el) {el.focus();
}
}
}
});
</script>
三、计算属性 computed
- 模板中放入太多的逻辑会让模板过重且难以保护,应用计算属性能够让模板更加的简洁
computed: {reversedMessage: function () {return this.msg.split('').reverse().join('')
}
}
- 计算属性是基于它们的响应式依赖(data)进行缓存的,只有 data 中的数据(咱们应用的值)没有发生变化,就不会再进行一次计算。而用办法实现的化是调用一次就执行一次。因而有时应用计算属性绝对耗时的计算能够节俭一些性能。
- computed 比拟适宜对多个变量或者对象进行解决后返回一个后果值,只有当多个变量中的某一个值产生了变动,咱们监控的返回值才就会发生变化(才会再次进行计算)
<div id="app">
<!--
当屡次调用 reverseString 的时候
只有外面的 num 值不扭转 他会把第一次计算的后果间接返回
直到 data 中的 num 值扭转 计算属性才会从新产生计算
-->
<div>{{reverseString}}</div>
<div>{{reverseString}}</div>
<!-- 调用 methods 中的办法的时候 他每次会从新调用 -->
<div>{{reverseMessage()}}</div>
<div>{{reverseMessage()}}</div>
</div>
<script type="text/javascript">
/*
计算属性与办法的区别: 计算属性是基于依赖进行缓存的,而办法不缓存
*/
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao',
num: 100
},
methods: {reverseMessage: function(){console.log('methods')
return this.msg.split('').reverse().join('');
}
},
//computed 属性 定义 和 data 曾经 methods 平级
computed: {
// reverseString 这个是咱们本人定义的名字
reverseString: function(){console.log('computed')
var total = 0;
// 当 data 中的 num 的值扭转的时候 reverseString 会主动产生计算
for(var i=0;i<=this.num;i++){total += i;}
// 这里肯定要有 return 否则 调用 reverseString 的 时候无奈拿到后果
return total;
}
}
});
</script>
四、侦听器 watch
- 应用 watch 来响应数据的变动
- 数据变动时执行异步或开销较大的操作
- watch 中的属性 肯定是 data 中 曾经存在的数据
- 当须要监听一个对象的扭转时,一般的 watch 办法无奈监听到对象外部属性的扭转,只有 data 中的数据才可能监听到变动,此时就须要 deep 属性对对象进行深度监听
<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">
/* 侦听器 */
var vm = new Vue({
el: '#app',
data: {
firstName: 'Jim',
lastName: 'Green',
// fullName: 'Jim Green'
},
//watch 属性 定义 和 data 曾经 methods 平级
watch: {
// 留神:这里 firstName 对应着 data 中的 firstName
// 当 firstName 值 扭转的时候 会主动触发 watch
firstName: function(val) {this.fullName = val + ' ' + this.lastName;},
// 留神:这里 lastName 对应着 data 中的 lastName
lastName: function(val) {this.fullName = this.firstName + ' ' + val;}
}
});
</script>
五、过滤器
- Vue.js 容许自定义过滤器,可被用于一些常见的文本格式化。
- 过滤器能够用在两个中央:双花括号插值和 v -bind 表达式。
- 过滤器应该被增加在 JavaScript 表达式的尾部,由“管道”符号批示
- 反对级联操作
- 过滤器不扭转真正的
data
,而 只扭转渲染的后果,并返回过滤后的版本 - 全局注册时是 filter,没有 s 的。而部分过滤器是 filters,是有 s 的
5.1 自定义过滤器
Vue.filter(‘过滤器名称’, function(value){// 过滤器业务逻辑})
5.2 过滤器的应用
<div>{{msg | upper}}</div>
<div>{{msg | upper | lower}}</div>
<div v-bind:id=“id | formatId"></div>
5.3 部分过滤器
filters:{capitalize: function(){}}
<div id="app">
<input type="text" v-model='msg'>
<!-- upper 被定义为接管单个参数的过滤器函数,表达式 msg 的值将作为参数传入到函数中 -->
<div>{{msg | upper}}</div>
<!--
反对级联操作
upper 被定义为接管单个参数的过滤器函数,表达式 msg 的值将作为参数传入到函数中。而后持续调用同样被定义为接管单个参数的过滤器 lower,将 upper 的后果传递到 lower 中
-->
<div>{{msg | upper | lower}}</div>
<div :abc='msg | upper'> 测试数据 </div>
</div>
<script type="text/javascript">
// lower 为全局过滤器
Vue.filter('lower', function(val) {return val.charAt(0).toLowerCase() + val.slice(1);
});
var vm = new Vue({
el: '#app',
data: {msg: ''},
//filters 属性 定义 和 data 曾经 methods 平级
// 定义 filters 中的过滤器为部分过滤器
filters: {
// upper 自定义的过滤器名字
// upper 被定义为接管单个参数的过滤器函数,表达式 msg 的值将作为参数传入到函数中
upper: function(val) {
// 过滤器中肯定要有返回值 这样外界应用过滤器的时候能力拿到后果
return val.charAt(0).toUpperCase() + val.slice(1);
}
}
});
</script>
5.4 过滤器中传递参数
定义
Vue.filter(‘format’, function(value, arg){// arg 就是过滤器传递过去的参数})
应用<div>{{date | format(‘yyyy-MM-dd')}}</div>
<div id="box">
<!--
filterA 被定义为接管三个参数的过滤器函数。其中 message 的值作为第一个参数,一般字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。-->
{{message | filterA('arg1', 'arg2') }}
</div>
<script>
// 在过滤器中 第一个参数 对应的是 管道符后面的数据 n 此时对应 message
// 第 2 个参数 a 对应 实参 arg1 字符串
// 第 3 个参数 b 对应 实参 arg2 字符串
Vue.filter('filterA',function(n,a,b){if(n<10){return n+a;}else{return n+b;}
});
new Vue({
el:"#box",
data:{message: "哈哈哈"}
})
</script>
六、生命周期
- 事物从出世到死亡的过程
- Vue 实例从创立 到销毁的过程,这些过程中会随同着一些函数的自调用。咱们称这些函数为钩子函数
6.1. 次要阶段
- 挂载(初始化相干属性)
1 beforeCreate
2 created
3 beforeMount 4 mounted - 更新(元素或组件的变更操作)
1 beforeUpdate
2 updated - 销毁(销毁相干属性)
1 beforeDestroy
2 destroyed
罕用的钩子函数
beforeCreate | 在实例初始化之后,数据观测和事件配置之前被调用。此时 data 和 methods 以及页面的 DOM 构造都没有初始化 什么都做不了 |
---|---|
created | 在实例创立实现后被立刻调用此时 data 和 methods 曾经能够应用 然而页面还没有渲染进去 |
beforeMount | 在挂载开始之前被调用 此时页面上还看不到实在数据 只是一个模板页面而已 |
mounted | el 被新创建的 vm.$el 替换,并挂载到实例下来之后调用该钩子。数据曾经实在渲染到页面上,在这个钩子函数外面咱们能够应用一些第三方的插件 |
beforeUpdate | 数据更新时调用,产生在虚构 DOM 打补丁之前。页面上数据还是旧的 |
updated | 因为数据更改导致的虚构 DOM 从新渲染和打补丁,在这之后会调用该钩子。页面上数据曾经替换成最新的 |
beforeDestroy | 实例销毁之前调用 |
destroyed | 实例销毁后调用 |
数组变异办法
- 在 Vue 中,间接批改对象属性的值无奈触发响应式。当你间接批改了对象属性的值,你会发现,只有数据改了,然而页面内容并没有扭转
- 变异数组办法即放弃数组办法原有性能不变的前提下对其进行性能拓展
push() |
往数组最初面增加一个元素,胜利返回以后数组的长度 |
---|---|
pop() |
删除数组的最初一个元素,胜利返回删除元素的值 |
shift() |
删除数组的第一个元素,胜利返回删除元素的值 |
unshift() |
往数组最后面增加一个元素,胜利返回以后数组的长度 |
splice() |
有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原地位替换的值 |
sort() |
sort() 使数组依照字符编码默认从小到大排序, 胜利返回排序后的数组 |
reverse() |
reverse() 将数组倒序,胜利返回倒序后的数组 |
替换数组
- 不会扭转原始数组,但总是返回一个新数组
filter | filter() 办法创立一个新的数组,新数组中的元素是通过查看指定数组中符合条件的所有元素。 |
---|---|
concat | concat() 办法用于连贯两个或多个数组。该办法不会扭转现有的数组 |
slice | slice() 办法可从已有的数组中返回选定的元素。该办法并不会批改数组,而是返回一个子数组 |
动静数组响应式数据
触发视图从新更新一遍,让数据动静起来Vue.set(vm.items, indexOfItem, newValue)
vm.$set(vm.items, indexOfItem, newValue)
1 参数一示意要解决的数组名称
2 参数二示意要解决的数组的索引
3 参数三示意要解决的数组的值
var vm = new Vue({
el: '#app',
data: {list: ['apple', 'orange', 'banana'],
info: {
name: 'lisi',
age: 12
}
},
});
// vm.list[1] = 'lemon'; // 无奈触发动静批改数据
// Vue.set(vm.list, 2, 'lemon');
vm.$set(vm.list, 1, 'lemon');
图书列表案例
- 动态列表成果
- 基于数据实现模板成果
- 解决每行的操作按钮
1. 提供的静态数据
- 数据寄存在 vue 中 data 属性中
var vm = new Vue({
el: '#app',
data: {
books: [{
id: 1,
name: '三国演义',
date: ''
},{
id: 2,
name: '水浒传',
date: ''
},{
id: 3,
name: '红楼梦',
date: ''
},{
id: 4,
name: '西游记',
date: ''
}]
}
});
2. 把提供好的数据渲染到页面上
- 利用 v-for 循环 遍历 books 将每一项数据渲染到对应的数据中
<tbody>
<tr :key='item.id' v-for='item in books'>
<!-- 对应的 id 渲染到页面上 -->
<td>{{item.id}}</td>
<!-- 对应的 name 渲染到页面上 -->
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<!-- 阻止 a 标签的默认跳转 -->
<a href="" @click.prevent> 批改 </a>
<span>|</span>
<a href="" @click.prevent> 删除 </a>
</td>
</tr>
</tbody>
3. 增加图书
- 通过双向绑定获取到输入框中的输出内容
- 给按钮增加点击事件
- 把输入框中的数据存储到 data 中的 books 外面
<div>
<h1> 图书治理 </h1>
<div class="book">
<div>
<label for="id">
编号:</label>
<!-- 3.1、通过双向绑定获取到输入框中的输出的 id -->
<input type="text" id="id" v-model='id'>
<label for="name">
名称:</label>
<!-- 3.2、通过双向绑定获取到输入框中的输出的 name -->
<input type="text" id="name" v-model='name'>
<!-- 3.3、给按钮增加点击事件 -->
<button @click='handle'> 提交 </button>
</div>
</div>
</div>
<script type="text/javascript">
/*
图书治理 - 增加图书
*/
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
books: [{
id: 1,
name: '三国演义',
date: ''
},{
id: 2,
name: '水浒传',
date: ''
},{
id: 3,
name: '红楼梦',
date: ''
},{
id: 4,
name: '西游记',
date: ''
}]
},
methods: {handle: function(){
// 3.4 定义一个新的对象 book 存储 获取到输入框中 书 的 id 和名字
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
// 3.5 把 book 通过数组的变异办法 push 放到 books 外面
this.books.push(book);
//3.6 清空输入框
this.id = '';
this.name = '';
}
}
});
</script>
4. 批改图书 - 上
-
点击批改按钮的时候 获取到要批改的书籍名单
- 4.1 给批改按钮增加点击事件,须要把以后的图书的 id 传递过来 这样才晓得须要批改的是哪一本书籍
-
把须要批改的书籍名单填充到表单外面
- 4.2 依据传递过去的 id 查出 books 中 对应书籍的详细信息
- 4.3 把获取到的信息填充到表单
<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">
<label for="name">
名称:</label>
<input type="text" id="name" v-model='name'>
<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}}</td>
<td>
<!---
4.1 给批改按钮增加点击事件,须要把以后的图书的 id 传递过来
这样才晓得须要批改的是哪一本书籍
--->
<a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
<span>|</span>
<a href="" @click.prevent> 删除 </a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
/*
图书治理 - 增加图书
*/
var vm = new Vue({
el: '#app',
data: {
flag: false,
id: '',
name: '',
books: [{
id: 1,
name: '三国演义',
date: ''
},{
id: 2,
name: '水浒传',
date: ''
},{
id: 3,
name: '红楼梦',
date: ''
},{
id: 4,
name: '西游记',
date: ''
}]
},
methods: {handle: function(){
// 3.4 定义一个新的对象 book 存储 获取到输入框中 书 的 id 和名字
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
// 3.5 把 book 通过数组的变异办法 push 放到 books 外面
this.books.push(book);
//3.6 清空输入框
this.id = '';
this.name = '';
},
toEdit: function(id){console.log(id)
//4.2 依据传递过去的 id 查出 books 中 对应书籍的详细信息
var book = this.books.filter(function(item){return item.id == id;});
console.log(book)
//4.3 把获取到的信息填充到表单
// this.id 和 this.name 通过双向绑定 绑定到了表单中 一旦数据扭转视图自动更新
this.id = book[0].id;
this.name = book[0].name;
}
}
});
</script>
5. 批改图书 - 下
- 5.1 定义一个标识符,次要是管制 编辑状态下以后编辑书籍的 id 不能被批改 即 处于编辑状态下 以后管制书籍编号的输入框禁用
- 5.2 通过属性绑定给书籍编号的 绑定 disabled 的属性 flag 为 true 即为禁用
- 5.3 flag 默认值为 false 处于编辑状态 要把 flag 改为 true 即以后表单为禁用
- 5.4 复用增加办法 用户点击提交的时候仍然执行 handle 中的逻辑如果 flag 为 true 即 表单处于不可输出状态 此时执行的用户编辑数据数据
<div id="app">
<div class="grid">
<div>
<h1> 图书治理 </h1>
<div class="book">
<div>
<label for="id">
编号:</label>
<!-- 5.2 通过属性绑定 绑定 disabled 的属性 flag 为 true 即为禁用 -->
<input type="text" id="id" v-model='id' :disabled="flag">
<label for="name">
名称:</label>
<input type="text" id="name" v-model='name'>
<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}}</td>
<td>
<a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
<span>|</span>
<a href="" @click.prevent> 删除 </a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
/* 图书治理 - 增加图书 */
var vm = new Vue({
el: '#app',
data: {
flag: false,
id: '',
name: '',
books: [{
id: 1,
name: '三国演义',
date: ''
},{
id: 2,
name: '水浒传',
date: ''
},{
id: 3,
name: '红楼梦',
date: ''
},{
id: 4,
name: '西游记',
date: ''
}]
},
methods: {handle: function() {
/*
5.4 复用增加办法 用户点击提交的时候仍然执行 handle 中的逻辑
如果 flag 为 true 即 表单处于不可输出状态 此时执行的用户编辑数据数据
*/
if (this.flag) {
// 编辑图书
// 5.5 依据以后的 ID 去更新数组中对应的数据
this.books.some((item) => {if (item.id == this.id) {
// 箭头函数中 this 指向父级作用域的 this
item.name = this.name;
// 实现更新操作之后,须要终止循环
return true;
}
});
// 5.6 编辑完数据后表单要处以能够输出的状态
this.flag = false;
// 5.7 如果 flag 为 false 表单处于输出状态 此时执行的用户增加数据
} else {var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
this.books.push(book);
// 清空表单
this.id = '';
this.name = '';
}
// 清空表单
this.id = '';
this.name = '';
},
toEdit: function(id) {
/*
5.3 flag 默认值为 false 处于编辑状态 要把 flag 改为 true 即以后表单为禁 用
*/
this.flag = true;
console.log(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;
}
}
});
</script>
6. 删除图书
- 6.1 给删除按钮增加事件 把以后须要删除的书籍 id 传递过去
- 6.2 依据 id 从数组中查找元素的索引
- 6.3 依据索引删除数组元素
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
<span>|</span>
<!-- 6.1 给删除按钮增加事件 把以后须要删除的书籍 id 传递过去 -->
<a href=""@click.prevent='deleteBook(item.id)'> 删除 </a>
</td>
</tr>
</tbody>
<script type="text/javascript">
/*
图书治理 - 增加图书
*/
var vm = new Vue({
methods: {deleteBook: function(id){
// 删除图书
#// 6.2 依据 id 从数组中查找元素的索引
// var index = this.books.findIndex(function(item){
// return item.id == id;
// });
#// 6.3 依据索引删除数组元素
// this.books.splice(index, 1);
// -------------------------
#// 办法二:通过 filter 办法进行删除
# 6.4 依据 filter 办法 过滤出来 id 不是要删除书籍的 id
# 因为 filter 是替换数组不会批改原始数据 所以须要 把 不是要删除书籍的 id 赋值给 books
this.books = this.books.filter(function(item){return item.id != id;});
}
}
});
</script>
七、罕用个性利用场景
7.1 过滤器
- Vue.filter 定义一个全局过滤器
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<!-- 1.3 调用过滤器 -->
<td>{{item.date | dateFormat}}</td>
<td>
<a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
<span>|</span>
<a href=""@click.prevent='deleteBook(item.id)'> 删除 </a>
</td>
</tr>
<script>
#1.1 Vue.filter 定义一个全局过滤器
Vue.filter('dateFormat', (dataStr) => {console.log(dataStr)
var time = new Date(dataStr);
console.log(time)
function timeAdd0(str) {if (str < 10) {str = '0' + str;}
return str
}
var y = time.getFullYear();
var m = time.getMonth() + 1;
var d = time.getDate();
var h = time.getHours();
var mm = time.getMinutes();
var s = time.getSeconds();
return y + '-' + timeAdd0(m) + '-' + timeAdd0(d) + '' + timeAdd0(h) +':'+ timeAdd0(mm) +':' + timeAdd0(s);
})
#1.2 提供的数据 蕴含一个工夫戳 为毫秒数
[{
id: 1,
name: '三国演义',
date: 2525609975000
},{
id: 2,
name: '水浒传',
date: 2525609975000
},{
id: 3,
name: '红楼梦',
date: 2525609975000
},{
id: 4,
name: '西游记',
date: 2525609975000
}];
</script>
7.2 自定义指令
- 让表单主动获取焦点
- 通过 Vue.directive 自定义指定
<!-- 2.2 通过 v - 自定义属性名 调用自定义指令 -->
<input type="text" id="id" v-model='id' :disabled="flag" v-focus>
<script>
# 2.1 通过 Vue.directive 自定义指定
Vue.directive('focus', {inserted: function (el) {el.focus();
}
});
</script>
7.3 计算属性
-
通过计算属性计算图书的总数
- 图书的总数就是计算数组的长度
<div class="total">
<span> 图书总数:</span>
<!-- 3.2 在页面上 展现进去 -->
<span>{{total}}</span>
</div>
<script type="text/javascript">
/* 计算属性与办法的区别: 计算属性是基于依赖进行缓存的,而办法不缓存 */
var vm = new Vue({
data: {
flag: false,
submitFlag: false,
id: '',
name: '',
books: []},
computed: {total: function(){
// 3.1 计算图书的总数
return this.books.length;
}
},
});
</script>
7.4 侦听器
当增加图书时,输出的书名已存在,则提交按钮禁用
book.date = new Date().getTime();
<button @click='handle' :disabled="submitFlag"> 提交 </button>
<script>
var vm = new Vue({
el: '#app',
data: {
submitFlag: false,
id: '',
name: '',
books: []},
watch: {name: function(val) {
// 验证图书名称是否曾经存在
var flag = this.books.some(function(item){return item.name == val;});
if(flag) {
// 图书名称存在
this.submitFlag = true;
}else{
// 图书名称不存在
this.submitFlag = false;
}
}
},
});
</script>
7.5 生命周期
mounted 生命周期钩子函数被触发的时候,模板曾经能够应用
个别此时用于获取后盾数据,而后把数据填充到模板
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;
}