品牌列表案例
运用的知识:
v-model
进行双向绑定
@click.prevent="del(id)"
函数传参
v-for
循环
String.prototype.includes('要包含的字符串')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cysky</title>
<link rel="stylesheet" href="../lib/bootstrap-3.3.7.css">
<script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3>添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label for="">
ID:
<input type="text" class="form-control" v-model="id">
</label>
<label for="">
Name:
<input type="text" class="form-control" v-model="name">
</label>
<label for="">
<input type="button" value="添加" class="btn btn-primary" @click="add">
</label>
<label for="">
搜索名称关键字:
<input type="text" class="form-control" v-model="keywords">
</label>
</div>
</div>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Ctime</th>
<th>Del</th>
</tr>
</thead>
<tbody>
<tr v-for="item in search(keywords)">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.ctime }}</td>
<td><a href="" @click.prevent="del(id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '',
list: [
{id: 1, name: '奔驰', ctime: new Date()},
{id: 2, name: '宝马', ctime: new Date()},
]
},
methods: {
add() {
var car = {id: this.id, name: this.name, ctime: new Date()};
this.list.push(car);
this.id = '';
this.name = ''
},
del(id) {
var index = this.list.indexOf(function (item) {
if (item.id === id) {
return true
}
});
this.list.splice(index, 1)
},
search(keywords) {
return this.list.filter(function (item) {
if (item.name.includes(keywords)) {
return item
}
})
}
}
})
</script>
</body>
</html>
<tr v-for="item in search(keywords)">
之前,v-for 中的数据,都是直接从 data 上的 list 中直接渲染过来的,现在,这里定义了一个 search 方法 在 search 方法内部,通过执行 for 循环,把所有符合搜索的关键字的数据,保存到一个新数组中返回。
全局过滤器
定义私有过滤器 过滤器有两个 条件 【过滤器名称 和 处理函数】
所谓的全局过滤器,就是所有的VM实例都共享的
Vue.filter('dataFormat',function(dataStr,pattern = ''){
var dt = new Date(dataStr);
var y = dt.getFullYear();
var m = dt.getMonth()+1;
var d = dt.getDate().toString().padStart(2,'0');
var h = dt.getHours().toString().padStart(2,'0');
var mm = dt.getMinutes().toString().padStart(2,'0');
var s = dt.getSeconds().toString().padStart(2,'0');
return `${y}-${m}-${d} ${h}:${mm}:${s}`
});
使用: <td>{{ item.ctime | dateFormat() }}</td>
私有过滤器
过滤器调用的时候,采用就近原则,如果私有过滤器和全局过滤器名称一致,这时候优先调用私有过滤器
filters:{
timeFormat: function (dateStr, pattern='') {
var dt = new Date(dateStr);
var y = dt.getFullYear();
var m = dt.getMonth() + 1;
var d = dt.getDate();
var h = dt.getHours().toString().padStart(2,'0');
var mm = dt.getMinutes().toString().padStart(2,'0');
var s = dt.getSeconds().toString().padStart(2,'0');
return `${y}-${m}-${d} ${h}:${mm}:${s}`
}
}
自定义全局按键修饰符
全部的按键别名:
.enter
.tab
-
.delete
(捕获“删除”和“退格”键) .esc
.space
.up
.down
.left
.right
以上可以直接使用:@click.enter = 'add'
Vue.config.keyCodes.f2 = 113
使用:@click.f2='add'
使用Vue.directive()定义全局的指令
Vue.directive('focus',{
inserted:function(el){
el.focus()
}
});
使用:<input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'green'">
inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
和样式相关的操作,一般都可以在 bind 执行
Vue.directive('color',{
bind:function(el,binding){
el.style.color = 'red';
console.log(binding.value)
}
});
使用:<input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'green'">
每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
函数中的第一个参数永远是 el ,表示被绑定了指令的那个元素, 这个 el 参数, 是一个原生的 JS 对象
和 JS 行为有关的操作,最好在 inserted 中去执行
参数1:指令的名称,注意,在定义的时候,指令名称前不需要加 v- 前缀,但是,在调用的时候,必须在指令名称前加上 v- 前缀来进行调用
参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定阶段,执行相关的操作
自定义私有指令
directives: {
'fontweight': {
bind: function (el, binding) {
el.style.fontWeight = binding.value
}
},
'fontsize': {
bind: function (el, binding) {
el.style.fontSize = binding.value
}
}
}
品牌列表完整案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cysky</title>
<link rel="stylesheet" href="../lib/bootstrap-3.3.7.css">
<script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3>添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label for="">
ID:
<input type="text" class="form-control" v-model="id">
</label>
<label for="">
Name:
<input type="text" class="form-control" v-model="name">
</label>
<label for="">
<input type="button" value="添加" class="btn btn-primary" @click="add">
</label>
<label for="">
搜索名称关键字:
<input type="text" class="form-control" v-model="keywords" v-focus>
</label>
</div>
</div>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Ctime</th>
<th>Del</th>
</tr>
</thead>
<tbody>
<tr v-for="item in search(keywords)">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.ctime | timeFormat() }}</td>
<td><a href="" @click.prevent="del(id)">删除</a></td>
</tr>
</tbody>
</table>
<p v-fontsize="50" v-color="'blue'">这是一个P标签,用于测试私有directives</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '',
list: [
{id: 1, name: '奔驰', ctime: new Date()},
{id: 2, name: '宝马', ctime: new Date()},
]
},
methods: {
add() {
var car = {id: this.id, name: this.name, ctime: new Date()};
this.list.push(car);
this.id = '';
this.name = ''
},
del(id) {
var index = this.list.indexOf(function (item) {
if (item.id === id) {
return true
}
});
this.list.splice(index, 1)
},
search(keywords) {
return this.list.filter(function (item) {
if (item.name.includes(keywords)) {
return item
}
})
}
},
filters: {//私有过滤器
timeFormat: function (dateStr, pattern = '') {
var dt = new Date(dateStr);
var y = dt.getFullYear();
var m = dt.getMonth() + 1;
var d = dt.getDate();
var h = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var s = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${h}:${mm}:${s}`
}
},
directives: {//自定义私有指令
'fontweight': {
bind: function (el, binding) {
el.style.fontWeight = binding.value
}
},
'fontsize': {
bind: function (el, binding) {
el.style.fontSize = parseInt(binding.value) + 'px'
}
},
'color': {
bind: function (el, binding) {
el.style.color = binding.value
}
},
'focus': {
inserted: function (el) {
el.focus()
}
}
}
})
</script>
</body>
</html>
生命周期
beforeCreate(){}
:这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它
注意:在 beforeCreate(){}
执行的时候,data 和 methods 中的数据都还没有初始化
created(){}
这是遇到的第二个生命周期函数,在 created 中,data 和 methods 都已经被初始化好了
注意:如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作
beforeMount(){}
这是遇到的第三个生命周期函数,表示模版已经在内存中编辑完成了,但是尚未把模版渲染到页面中
注意:在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的模版字符串
mounted(){}
这是遇到的第四个盛名周期函数,表示,内存中的模版,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
注意:mounted 是实例创建期间最后的一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其他操作,这个实例就在内存中,等候
接下来的是运行中的两个事件
beforeUpdate() {}
这时候表示我们的界面还没有被更新(数据已经更新了)
结论: 当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时 data 数据是最新的,页面尚未和 最新的数据保持同步
updated(){}
事件执行的时候,页面和 data 数据已经保持同步了,都是最新的