品牌列表案例的基础部分
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="lib/bootstrap.css">
<script src="lib/vue-2.6.10.js"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label>
Id:
<input type="text" class="form-control" v-model="id">
</label>
<label>
Name:
<input type="text" class="form-control" v-model="name" @keyup.enter="add">
<!--按键修饰符-->
</label>
<!--在vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参-->
<input type="button" value="添加" class="btn btn-primary" @click="add">
<label>
搜索名称关键字:
<!--在vue中所有的指令在调用的时候,都用v-开头-->
<input type="text" class="form-control" v-model="keywords" v-focus v-color="'blue'">
</label>
</div>
</div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Ctime</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<!--之前,v-for 中的数据,都是从 data 上的list中直接渲染过来的-->
<!--现在,我们自定义了一个 search 方法,同时,把所有关键字,通过传参的形式,传递给了search 方法-->
<!--在search方法内部通过执行for循环,把所有符合搜索关键字的数据,保存在一个新数组中-->
<tr v-for="item in search(keywords)" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.ctime | dateFormat('yyyy-mm-dd')}}</td>
<td>
<a href="" @click.prevent="del(item.id)">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<script>
//全局过滤器,进行时间的格式化
Vue.filter('dateFormat', function (dateStr, pattern = '') {
//根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr);
var y = dt.getFullYear();
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// return y + '-' + m + '-' + d;
//上面的拼接方法过于繁琐,采用下面的模板字符串方法进行拼接
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
});
//自定义全局指令
//其中参数1是指令的名称,注意,在定义的时候,指令的前面不需要加v-前缀,但是在调用的时候,必须在指令名称前加上v-前缀
//参数2是一个对象,这个对象身上有一些指令相关的函数,这些函数可以在特定的阶段执行相关的操作
Vue.directive('focus', {
bind: function (el) {//每当指令绑定到元素上的时候,会立即执行这个bind函数,只执行一次
// el.focus();
/*在元素刚绑定了指令的时候,还没有插入到dom中的时候,调用focus方法没有作用,因为一个元素只有插入DOM之后才能获取焦点*/
/*注意,在每个函数中,第一个参数,永远都是el,表示被绑定了指令的元素,是一个原声的对象*/
},
inserted: function (el) {//inserted表示元素插入到Dom中的时候,会执行此函数,且只执行一次
/*和js行为有关的操作,最好在inserted中去执行,防止js行为不生效*/
el.focus();
},
updated: function (el) {//当VNode更新的时候,会执行 updated,可能会触发多次
}
});
//自定义一个全局自动设置颜色的指令
Vue.directive('color', {
//样式只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
//将来元素肯定会显示到页面中去,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
bind: function (el, binding) {
el.style.color = binding.value;
/*和样式相关的操作,一般都可以在bind中执行*/
}
});
//创建vue实例
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() {//添加的方法
//分析
//获取 id 和 name ,直接从data中获取
//组织出一个对象
//把这个对象,调用数组的相关方法,添加到当前data中的list中
//注意: 在vue中已经实现了数据的双向绑定,每当我们修改了data中的数据,vue会默认监听到数据改动,自动把最新的数据应用到页面上
var obj = {id: this.id, name: this.name, ctime: new Date()};
this.list.push(obj);
this.id = this.name = '';
},
del(id) {//根据id删除数据
//分析
//如何根据id找到要删除这一项的索引
//如果找到索引直接调用数组的splice方法
this.list.some((item, i) => {
if (item.id == id) {
//在数组的some方法中,如果return true 就会终止后续循环
this.list.splice(i, 1);
/*
array.splice(start,deleteCount,item1,item2...)
start: 开始操作的索引
deleteCount:要移除的数组元素的个数
itemN:要添加进数组的元素,如果不指定,则splice只删除数组元素
*/
return true;
}
})
},
search(keywords) {//根据关键字进行数据的搜索
// var newList = [];
// this.list.forEach(item => {
// if (item.name.indexOf(keywords) != -1) {
// newList.push(item)
// }
// });
// return newList;
// 注意: forEach some filter findIndex 这些都属于数组的新方法
//都会对数组中的每一项,进行遍历,执行相关的操作
return this.list.filter(item => {
//注意: ES6中,为字符串提供了一个新方法,叫做 String.prototype.includes('要包含的字符串')
//如果包含,则返回true,否则返回false
return item.name.includes(keywords)
})
}
}
});
</script>
<!--过滤器的定义语法-->
<!--Vue.filter('过滤器名称',function(){})-->
<!--过滤器中的 function , 第一个参数已经被规定死了,永远都是过滤器管道符前面传递过来的数据-->
<div id="app2">
<!--可以有多个过滤器,按照从左到右的顺序过滤,将前面过滤的结果传到后面的过滤器-->
<p v-cloak>{{ msg | msgFormat('疯狂','+1') | test }}</p>
</div>
<script>
//定义一个Vue全局过滤器,名字叫做 msgFormat
//过滤器调用时候的格式 {{name | nameope}}
Vue.filter('msgFormat', function (msg, arg, arg2) {
//字符串的 replace方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则
return msg.replace(/单纯/g, arg + arg2);
});
Vue.filter('test', msg => {
return msg + '========';
});
var vm = new Vue({
el: '#app2',
data: {
msg: '我是一个单纯的男孩,我曾以为我是最单纯的!'
}
})
</script>
<!--如何定义一个私有(局部)的过滤器-->
<!--过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致,优先到调用私有-->
<!--
var vm = Vue({
el: '',
data:{},
methods:{},
filters:{//定义私有过滤器,过滤器有两个条件,【过滤器名称 和 处理函数】
dateFormat: function(dataStr, pattern){
//过滤的条件
}
},
})
-->
<!--如何定义一个私有(局部)的指令-->
<!--
var vm = Vue({
el: '',
data:{},
methods:{},
directives:{//自定义私有指令
'fontWeight':{
bind: function(el, binding){
el.style.fontWeight = binding.value;
}
}
}
})
-->
<script>
/*自定义全局按键修饰符*/
Vue.config.keyCodes.f2 = 113;
</script>
</body>
</html>