案例学习--品牌案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
<!--导入vue的CDN-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="./index.css">
</head>
<body>
<!-- react,ng,vue共同特点:适合做单页面应用程序。-->
<!-- 品牌案例:-->
<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:
<!--增加一个键盘修饰符 指定按键修饰
提供的按键修饰符有 .enter .tab .delete .esc .space .up .down .left .right
可以根据键盘码的对应值自定义修饰,例如,113对应为F2,可以为键盘起别名 -->
<!--<input type="text" v-model="name" @keyup.enter="add">-->
<!--<input type="text" v-model="name" @keyup.113="add">-->
<input type="text" v-model="name" @keyup.f2="add">
</label>
<!-- 函数后面添加括号可以传参-->
<input type="button" value="添加" class="btn btn-primary" @click="add()">
<!--根据关键字实现数组的过滤-->
<label for="">搜索名称关键字:
<!-- 自动获取焦点,Vue中所有 的指令,在调用的时候,都已v- 开头-->
<!-- ,blue不加引号表示一个变量
自定义全局指令 v-focus v-color
这里双向绑定了keywords值,一旦输入框发生改变,keywords值就发生改变
下面 v-for监听也就产生了响应-->
<input type="text" v-model="keywords" class="form-control" v-focus v-color="'darkgreen'">
</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>
<!-- 根据自定义的keywords显示数据
自定义一个search方法,传入搜索的参数,在search方法中,把所有复合搜索关键字的数据,保存到
一个新的数组,v-for监听的数据发生改变,dom也会发生对应的改变,
下面的i是取得索引,绑定的key属性用于保证唯一标示性,相当于数据库中表的主键-->
<tr v-for="(item,i) in search(keywords)" :key="item.id">
<td>{{ item.id }}</td>
<td v-text="item.name"></td>
<!-- 使用过滤器,优先使用局部的,然后在找全局-->
<td>{{ item.ctime | dateFormat('yyyy-mm-dd')}}</td>
<td>
<!-- 删除功能。prevent阻止默认事件-->
<a href="" @click.prevent="del(item.id)">删除</a>
</td>
</tr>
</tbody>
</table>
<!-- 过滤器的基本使用,传入参数,可以传入多个参数
自定义局部指令 v-color全局指令 v-fontWeight局部指令,
如果传递的为数字,不加单(双)引号,如果为字符串,必须加单(双)引号-->
<p v-color="'pink'" v-fontweight="600" v-fontsize="'20px'">{{ msg|msgFormat('疯狂') }}</p>
<!-- 局部过滤器的使用 -->
<p>{{ new Date()|dateFormat }}</p>
</div>
</body>
<script>
// 定义一个全局的按键修饰符,给按键去一个别名
Vue.config.keyCodes.f2 = 113
// 定义一个Vue的全局的过滤器 叫做msgFormat,
Vue.filter('msgFormat', function (msg,arg) {
// 使用正则进行全局匹配
return msg.replace(/特别/g, arg)
});
// 使用Vue.directive()定义全局指令
// 参数一是指令的名称,在定义的时候,指令的名称前面,
// 不需要加 v- 前缀,比如focus,在调用的时候,必须在前面 v-前缀,v-focus来进行调用
// 参数2是一个对象,这个对象身上,有一些相关的函数,这些函数在特定 的阶段,
// 执行相应的函数
// 自定义指令获取文本框焦点
Vue.directive('focus', {
bind:function (el) { // 每当指令绑定到元素上的时候,会立即执行这个bind函数,只执行一次
//注意;在每个函数中,第一个参数,永远是el,便是被绑定了指令的那个元素,这个el参数,是一个原生的JS对象
// 在元素 刚绑定了指令的时候,还没有插入到DOM中的时候,
// 这时候,调用 focus方法没有作用,一个元素,只有插入DOM之后,才能获取焦点
// el.focus()
},
inserted: function (el) { // 表示元素插入到dom中的时候,会执行insertd 函数
// 和js行为有关的操作,最好在insert中去执行,防止JS行为不生效
el.focus() // 这是一个行为
},
updated: function () { //当VNode更新的时候,会执行updated,可能会触发多次
}
})
// 自定义设置字体颜色的指令
Vue.directive('color', {
// 样式只要通过指令绑定给了元素,不不管这个元素有没有被插入到页面中去,这个严肃肯定有一个内联的样式
// 第二个参数binding是一个对象。可以拿到传递的参数值value!
// 更多的信息,参考Vue官方文档的钩子函数的参数。
bind: function (el,binding) {
// 和样式相关的操作,最好在bind中,执行。
// el.style.color = 'red'
console.log(binding.value) // 结果
console.log(binding.name) //对应的名称
console.log(binding.expression) // 原始的表达式
// 根据传入的值进行设定字体的颜色
el.style.color = binding.value
}
})
new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '', // 搜索的关键字
msg: '我是一个特别牛逼人,一个特别单纯却不简单',
list:[
{id:1,name:'奔驰',ctime:new Date()},
{id:2,name:'宝马',ctime:new Date()},
{id:3,name:'比亚迪',ctime:new Date()},
{id:4,name:'劳斯莱斯',ctime:new Date()},
{id:5,name:'法拉利',ctime:new Date()},
]
},
methods: {
add() {
this.list.push({id:this.id,name:this.name,ctime:new Date()},)
this.id = this.name = ''
},
del(id) {
// 1. 如果根据id,找到要删除的一项的索引
// 2. 如果找到了索引,直接调用数组的splice方法
// 3. 前面都是废话,直接传递索引不就OK了吗?
// some根据指定条件循环进行判断,可以中途终止循环,i从0开始
this.list.some((item, i) => {
if(item.id == id){
// splice从索引为i的位置开始,删除一个,第三个参数为插入的数据
this.list.splice(i, 1)
// 返回true,终止循环数组,
return true
}
})
// 专门查找索引的方法,返回true就将index赋值回去。
var index = this.list.findIndex(item => {
if(item.id == id){
return true
}
})
},
search(keywords) {
// 如果keywords是空字符串,下面indexOf返回的应该是0,不是找不到返回-1
if(!keywords.trim()){
return this.list
}
var newList = []
// // 循环遍历数组
// this.list.forEach(item => {
// // 如果name属性包含查询的字段,则将数据对象添加
// if(item.name.indexOf(keywords) != -1){
// newList.push(item)
// }
// })
// return newList
// forEach some filter findIndex 这些都属于数组的新方法
// 都会对数组中的每一项,进行遍历,执行相关的操作。
// forEach不能中途终止,some可以, filter进行过滤
// 接受的是一个数组,item相当于遍历的每一个元素
return this.list.filter(item => {
// ES6总,为字符串提供了一个新的方法,
// 叫做String.prototype.includes('要包含的字符串')
// Jquery中可以 $(':contains(哈)').contains()
if(item.name.includes(keywords)){
return item
}
})
}
},
// 过滤器,允许自定义过滤器,可用作一些常见的文本格式化,过滤器可以用在两个地方,
// mustachc差值({{ var| }}),和v-bind表达式,过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号表示
// 过滤器调用时候的格式, {{ name|过滤器的名称}}
// 过滤器的定义语法 Vue.filter('过滤器的名称', function(data){})
// 过滤器中的function,第一个参数必须是管道符传递过来的数据。
filters: {// 定义局部过滤器,有两个条件,过滤器,名称 和处理函数
// 过滤器调用的时候采用的是就近原则。dt 就是传入的data对象
// pattern是后面 传入的参数
// ES6中字符串的新方法,填充补全字符串
// String.prototype.padStart(maxLength, fillString='')
// String.prototype.padEnd(maxLength, fillString='')
dateFormat: function (dt, pattern = '') {
// 根据给定的字符串,得到特定的时间
// yyyy-mm-dd
var y = dt.getFullYear()
var m = (dt.getMonth() + 1).toString().padStart(2, 0)
var d = dt.getDate().toString().padStart(2, 0)
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`
} else {
var h = dt.getHours().toString().padStart(2, 0)
var M = dt.getMinutes().toString().padStart(2, 0)
var s = dt.getSeconds().toString().padStart(2, 0)
return `${y}-${m}-${d} ${h}:${M}:${s}`
}
}
},
directives: { // 定义局部的指令,私有指令
'fontweight':{ // 设置字体的粗细
bind: function (el, binding) {
el.style.fontWeight = binding.value
}
},
// 多数情况下,使用bind和update钩子函数比较多
// 可以简写如下,相当于直接在这两个钩子函数里面添加了指令
'fontsize':function (el,binding) {
el.style.fontSize = binding.value
}
}
});
</script>
</html>