Vue指令之v-for和key属性
循环数组,循环对象和循环数组中的对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-for循环</title>
<script src="vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<!-- v-for循环数组 -->
<div id="">
v-for循环数组
</div>
<p v-for="(item,i) in list">每一项:{{item}}------索引值:{{i}}</p>
<!-- 循环对象 -->
<!-- 注意:在遍历对象身上的键值对的时候,除了有var key 在第三个位置上还有一个索引 -->
<div id="">
v-for循环对象
</div>
<p v-for="(user,key,i) in list1">值:{{user}}------键:{{key}} ------索引:{{i}}</p>
<!-- v-for循环数组中的对象 -->
<div id="">
v-for循环数组中的对象
</div>
<p v-for="(user1,i) in list2">名字:{{user1.name}}------年龄:{{user1.age}} ------索引:{{i}}</p>
<!-- v-for循环数字 -->
<!-- in 后面我们放过 普通数组,对象数组,对象,还可以放数字 -->
<!-- 注意:如果使用v-for迭代数字的话,前面加count值从1开始 -->
<div id="">
v-for循环数字
</div>
<p v-for="(user2,i) in 10">数字:{{user2}}------索引:{{i}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [1, 2, 3, 4, 5, 6],
list1: {
name: 'zs',
age: '18',
},
list2:[
{name:'zs',age:'18'},
{name:'ls',age:'45'},
{name:'ww',age:'20'},
]
},
methods: {}
});
</script>
</body>
</html>
在2.20+版本里,当在组件中使用v-for时,key现在是必须的
当vue.js用v-for正在更新已渲染过的元素列表时,它默认用‘就地复用’策略。如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的顺序,而是简单复用此处每一个元素,并且确保它在特定索引下显示已被渲染过的每一个元素。为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一key属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-for循环中key属性的使用</title>
<script src="vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<label >ID:
<input type="text" name="" id="" v-model="ids" />
</label>
<label >Name:
<input type="text" name="" id="" v-model="names" />
</label>
<!-- 注意:v-for循环的时候,key属性只能使用number获取string -->
<!-- 注意: key在使用的时候,必须使用v-bind 属性绑定的形式,指定key的值 -->
<!-- 在组件中,使用v-for循环的时候,或者在一些特殊的情况中,如果v-for有问题,必须在使用v-for的同时,指定唯一key值 -->
<input type="button" name="" id="" value="添加" @click="add" />
<p v-for="item in list" :key="item.id">
<input type="checkbox" name="" id="" value="" />{{item.id}}---姓名:{{item.name}}</p>
</div>
<script>
var vm=new Vue({
el:'#app',
data:{
ids:'',
names:'',
list:[
{id:1,name:'王昭君'},
{id:2,name:'杨玉环'},
{id:3,name:'貂蝉'},
{id:4,name:'小乔'},
]
},
methods:{
add(){
this.list.unshift({id:this.ids,name:this.names});
}
}
});
</script>
</body>
</html>
Vue指令之v-if和v-show
一般来说,v-if有更高的切换消耗而v-show有更高的初始渲染消耗。因此,如果需要频繁切换v-show较好,如果在运行时条件不大可能改变v-if较好
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-if和v-show</title>
<script src="vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<input type="button" name="button" id="" value="消失" @click="flag=!flag"/>
<!-- v-if的特点:每次都会重新删除或者创建元素 -->
<!-- v-show的特点:每次不会重新进行DOM的删除和创建操作,只是切换了元素 的display:none样式 -->
<!-- v-if 有较高的切换性能消耗 -->
<!-- v-show 有较高的初始化渲染消耗 -->
<!-- 如果元素涉及到频繁的切换,最好不要使用v-if,而且推荐使用v-show -->
<!-- 如果元素可能永远也不会显示出来被用户看到,则推荐使用v-if -->
<div class="box" v-if="flag">我是一个v-if</div>
<div class="box2" v-show="flag">我是v-show</div>
</div>
<script>
var vm=new Vue({
el:'#app',
data:{
flag:false
},
methods:{
}
});
</script>
</body>
</html>
品牌案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>品牌列表案例</title>
<link rel="stylesheet" type="text/css" href="bootstrap-3.3.7.css" />
<script src="vue-2.4.0.js"></script>
</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.f2="add" />
</label>
<!-- 在vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了 -->
<input type="button" id="" class="btn btn-primary" value="添加" @click="add()" />
<label>搜索关键字:
<input type="text" class="form-control" v-model="keywords" v-focus />
</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>
<!-- 过滤器调用时候的名称 {{name | 过滤器的名称}} -->
<td>{{item.Ctime |dataFormat()}}</td>
<td>
<a href="#" @click.prevent="del(item.id)">刪除</a>
</td>
</tr>
</tbody>
</table>
</div>
<div id="app2">
<h3 v-color="'pink'" v-fontweight="900" v-fontsize="'30px'">{{dt|dataFormat()}}</h3>
</div>
<script>
// 全局过滤器,进行时间的格式化
// 所谓的全局过滤器,就是所有的VM 实例都共享的
Vue.filter('dataFormat', function(dataStr, pattern = '') {
//根据给定的时间字符串 得到特定的时间
var dt = new Date(dataStr)
/*yyyy-mm-dd */
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
// hh:mm:ss
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}`
}
})
// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113
// 使用 Vue.directive() 定义全局的指令 v-focus
// 其中:参数1:指令的名称,注意:在定义的时候,指令的名称前面,不需要加v- 前缀
// 但是:在调用的时候,必须在指令前面加上 v- 前缀来进行调用
// 参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作
Vue.directive('focus', {
bind: function(el) {
// 每当指令绑定到元素上的时候,会立即执行这个bind函数,只执行一次
// 注意:在每个函数中,第一个参数,永远都是el,表示被绑定了指令的那个元素,这个el参数,是一个原生的JS对象
// 在元素刚绑定了指令的时候,还没有插入到DOM中去的时候,这个时候,调用focus方法没有作用
// 因为,一个元素,只有插入DOM之后,才能获取焦点
},
inserted: function(el) {
// inserted 表示元素插入到DOM中的时候,会执行inserted 函数【触发一次】
el.focus()
// 和js 行为有关的操作,最好在inserted中去执行,放置JS行为不生效
},
updated: function(el) {
// 当VNode更新的时候,会执行updated,可能会触发多次
}
})
// 自定义一个设置字体颜色的指令
Vue.directive('color', {
// 样式,只要通过指令绑定给了元素,不管这个元素有没有插入到页面中去,这个元素肯定有了一个内联的样式
// 将来元素肯定会显示到页面中,这个时候浏览器的渲染引擎不然会解析样式,应用给这个元素
bind: function(el, binding) {
el.style.color = binding.value
}
})
// 创建Vue实例,得到ViewModel
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() {
// 添加数据
// 分析:
// 1.获取到id和name,直接从data上面获取
// 2.组织出一个对象
// 3.把这个对象,调用数组的相关方法,添加到当前data上的list中
// 4.在vue中,已经实现了数据的双向绑定,每当我们修改了data中的数据,vue会默认监听到数据的改动,自动把最新的数据,应用到页面上
// 5.当我们意识到上面的第四步的时候,就证明大家已经入门vue了,我们更多的是在进行vm中的model数据的操作,同时,在操作Model数据的时候,指定的业务逻辑操作
this.list.push({
id: this.id,
name: this.name,
Ctime: new Date()
})
// 清空input框内容
this.name = this.id = ''
},
del(id) {
// 根据Id删除数据
// 分析
// 1.如何根据Id,找到要删除这一项的索引
// 2.如果找到索引了,直接调用数组的spice 方法
/* this.list.some((item,i)=>{
if(item.id==id){
this.list.splice(i,1)
// 在数组的sone方法中,如果return true,就会立即终止这个数组的后续循环
return true;
}
}
}) */
var index = this.list.findIndex(item => {
if (item.id == id) {
return true;
}
})
this.list.splice(index, 1)
},
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 => {
// if(item.name.indexOf(keywords)!=-1)
// 注意:ES6中,为字符串提供了一个新方法,叫做String.prototype.includes('要包含的字符串')
// 如果 要包含,则返回true,否则返回false
if (item.name.includes(keywords)) {
return item
}
})
}
}
});
var vm2 = new Vue({
el: '#app2',
data: {
dt: new Date()
},
methods: {
},
// 定义私有过滤器 过滤器有两个条件【过滤名称 和 处理函数】
// 过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致了,这时候 优先调用私有过滤器
filters: {
dataFormat: function(dataStr, pattern = "") {
var dt = new Date(dataStr)
/*yyyy-mm-dd */
// padStart() 方法將字符串变成两位不足补0
var y = dt.getFullYear().toString().padStart(2, '0')
var m = (dt.getMonth() + 1).toString().padStart(2, '0')
var d = dt.getDate().toString().padStart(2, '0')
// return y+'-'+m+'-'+d
// hh:mm:ss
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} ==============`
}
}
},
// 自定义私有指令
directives: {
'fontweight': { //设置字体粗细的
bind: function(el, binding) {
el.style.fontWeight = binding.value
}
},
'fontsize': function(el, binding) { // 注意:这个 function 等同于 把 代码写到了 bind 和 update 中去
// 增加代码的健壮性
el.style.fontSize = parseInt(binding.value) + 'px'
}
}
})
</script>
</body>
</html>
过滤器的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>过滤器的基本使用</title>
<script src="vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<div id="">
{{msg | msgFormat('疯狂6+1','123')}}
</div>
</div>
<script>
// 定义一个vue全局的过滤器,名字叫做 msgFormat
Vue.filter('msgFormat', function(msg, arg, arg2) {
// 字符串的replace 方法,第一个参数,除了可写一个字符串之外,还可以定义一个正则,也可以带参数
return msg.replace(/善良/g, arg + arg2)
})
Vue.filter('msgFormat', function(msg) {
// 字符串的replace 方法,第一个参数,除了可写一个字符串之外,还可以定义一个正则,也可以带参数
return msg + '========='
})
var vm = new Vue({
el: '#app',
data: {
msg: '我曾经遇到一个很善良女孩子,我喜欢她,后来我才知道我喜欢的是她的善良,并不是她!'
},
methods: {}
});
</script>
</body>
</html>
vue调试工具vue-devtools
在Chrome应用商店插件里面使用