1.列表渲染 :
① <li v-for="p in persons">{{p.name}}-{{p.age}}</li>
data:{
persons:[{id:'01',name:'张',age:18},{ id: '02', name: '李', age: 19 },{ id: '03', name: '王', age: 20 }]
}
p in persons是指把vue的data中的数据persons传给参数p(类似于 for in 遍历操作),(有几个数据就传几个给p,也就生成几个li.) 而想要在页面显示哪个就用p.name取数据。
② <li v-for="(p,index) in persons" :key="index"> //in或者of都可以表示。
(p,index) p用来传参,index用来接收每个li的索引号的。
③(p,k)in cars cars是一个对象,p表示数据,k表示属性名。
其中②的bug: <li v-for="(p,index) in persons" :key="index"> 若是key用index,若生成的对象插在列表最前面时,把原来index=0的位置给占了,生成新的dom时,一对比就会发现之前和现在的列表得到index都串行了。
所以要用: :key='p.id' id实际是数据库生成的唯一的id。新旧对比两个列表,即使索引不同了,但是每个人id永不会变的。
如果是列表后面无其他内容时就不会错乱,index和id都行。
<body>
<div id="box">
<h2>人员列表</h2>
<input type="text" placeholder="输入信息" v-model="keyword">
<li v-for="(p,index) in filpersons" :key="p.id">{{p.name}}-{{p.age}}</li>
</div>
<Script type="text/javascript">
Vue.config.productionTip = false//阻止报错
new Vue({
el:'#box',
data:{
keyword:'',
persons:[{id:'01',name:'马冬梅',age:18, sex:'女'},
{ id: '02', name: '周冬雨', age: 19, sex:'女'},
{ id: '03', name: '周杰伦', age: 22, sex:'男'}],
filpersons:[]
},
watch:{
keyword:{
immediate:true,
handler(val){
this.filpersons = this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1
})
}
}
}
})
</Script>
</body>
2.列表过滤:
步骤一:拿到文本框的内容。
用watch对文本框中keyword进行监听 watch{keyword(value){..........}} 只有get数据,所以就可以简写。 文本框中的内容作为value参数。
并且用v-model:'keywords' 如果keywords改变则model中数据也会随着改变。反之也是
步骤二:拿到的数据和列表中数据对比进行过滤。
监听keywords之后就拿到了value值,现在操作时过滤p内容,并且返回过滤后内容。
watch:{ keyword(val){
this.persons=this.persons.filter((p) =>{return p.name.indexof(val) !== -1})
}}
用.filter过滤p中数据,再赋值perosn(可以改变person的值,一旦person值改变则v-for in遍历的值也会改变)。 补充:a.indexof(b):是指b是否属于a,若不属于返回-1,若是属于则返回该值的下标。
但是有一个bug是过滤之后改变了persons内容,会越查找越少,因为不满足条件的内容被过滤了,但是没有接收过滤掉的内容了,类似于覆盖了原来数据。
修改bug1:
在data中设置一个空filpersons[ ],把过滤出来内容放回过滤数组中,从过滤数组中遍历回页面,也就是v-for遍历过滤数组。
修改bug2:
过滤数组刚开始是空的,所以一打开页面时不会显示出任何数据。这样无法直到原来数组中的内容的。利用immediate:true 先调用一次。 页面文本框内容为空字符串,巧妙在空字符串是属于任何一个字符串的,(空字符串和所有字符串匹配)。所以一打开页面先调用一次空字符串匹配,因此会显示所有内容。 但是此时watch{}就不可以简写了。
3.列表排序:
步骤一:先过滤
先把过滤得到的内容用一个变量arr接收。
步骤二:在排序。
根据判断sorttype的值,再对arr(过滤之后的结果)进行排序。
补充排序:arr.sort(a,b) 若是要升序用a1- a2, 若是降序则a2-a1.
<body>
<div id="box">
<h2>人员列表</h2>
<input type="text" placeholder="输入信息" v-model="keyword">
<button @click="sorttype = 2">升序</button>
<button @click="sorttype = 1">降序</button>
<button @click="sorttype = 0">原序</button>
<ul>
<li v-for="(p,index) in filpersons" :key="index"> {{p.name}} - {{p.age}}</li>
</ul>
</div>
<Script type="text/javascript">
Vue.config.productionTip = false//阻止报错
new Vue({
el: '#box',
data: {
sorttype:0, //sorttype的值决定是什么顺序。
keyword: '',
persons: [{ id: '01', name: '马冬梅', age: 18, sex: '女' },
{ id: '02', name: '周冬雨', age: 15, sex: '女' },
{ id: '03', name: '周杰伦', age: 22, sex: '男' }],
},
computed:{ //计算出filpersons,并且对filpersons进行排序,原数组就没有动。
filpersons(){
const arr = this.persons.filter((p) => {
return p.name.indexOf(this.keyword) !== -1 //keyword是文本框内容,返回的是包含文本框的内容。并用arr接收。
})
//拿到过滤后的数据arr,从sorttype判断是否要排序
if(this.sorttype){ //若sorttype是0 则为假,就不会通过if了
arr.sort((a1,a2)=>{
return this.sorttype === 1 ? a2.age - a1.age : a1.age - a2.age //对拿到的arr进行排序处理过程
})
}
return arr
}
}
})
</Script>
</body>
记住:过滤和排序不分家的。
4.vue监测数据的原理(♥)
对于new vue,刚开始设置的data{...},data里面有谁则会对应生成谁的get和set属性,其中set很重要,直接影响到页面是否修改其值。 但是一旦new之后,再想往vue的data中添加一个属性
,如sex,则这个sex是没有对应的get和set的,就不能通过修改vue._data.student.sex = '男'使得页面的值也改变。
解决方法一:vue.set(给谁添加属性,‘属性名’,‘属性值’)
解决方法二:vm.$set(给谁添加属性,‘属性名’,‘属性值’)
注意:上面添加的方法都不可以给vue的根数据(在new中data{}或者和data{}同一等级的)加属性,只能给跟数据里面的对象添加。如:data{ school{ name‘ ’, sex‘ ’}},可以给school添加属性年龄age,不可以给data加。
上面讲的是对象,但若对于数组来说:若想要vue监测到数组发生了改变则要用数组的那七种方法:pop, push, shift(删除最后一个),unshift, reserve, sort, splice; 数组的其他方法改变数组时vue监测不到就无法更新页面,但是也可以用 vue.set(给谁添加属性,‘数组下标’,‘要更换的属性值’)来改变数组。
5.收集表单数据
补充css:lable里面有个 for=‘名字’, 文本框有个 id=‘名字’ 则是点击标签 就可以让文本获得光标。
补充vue提供的表单的功能:v-model.trim='..' //会把文本输入空格去掉
v-model.number='...' //只会收集输入的数字
文本框 <input type='text'>
v-model收集的就是value的值,用户输value
单选,<input type='radio'>
要给标签配置value,每个选项都有一个value值
多选,<input type='checkbox'>
要配置value值,并且在data中对应属性是数组。
下拉菜单,<select v-model=‘...’> <option value=‘....’>选项1</option>
<option value='..'>选项2</option> </select>
多行输入
也是正常输入文本框收集
购选同意 <input type='checkbox' v-model='...'>
是否同意就是收集true或false的,所以直接v-model=‘...’就能得到bool值了。
6.过滤器:
...................
7.v-text=‘...’指令:
会把...中的值替换掉节点中的所有内容,更常用插值语句{{...}}
8.v-html指令 :
补充 :cookie:其本质就是字符串,类似于键值对。用户在浏览器中用账号密码请求一个服务器,服务器识别后会登录并且返回请求内容,此时还会返回cookie键值对,这个cookie是独有的,而且下次登录直接认证cookie就会通过。 如果别人盗取了cookie值那么它就可以在其他网络上直接登录你的账号。
v-html会换掉节点中内容,并且解析内容。但是容易收到xss攻击,暴露cookie,泄漏信息,可能html中会获得cooike值。
9.v-cloak指令:
这个指令是没有值的。
因为引入的js可能会有延迟,无法解析js之前的html,但是又不想让那些标签暴漏在页面上,而是想让js引入后解析再显示。 就给标签加v-cloak,在style中加 [v-cloak] { display:none} 这样在未加载js前不会显示出html,而且引入后会自动取消v-cloak的值的。
10.v-once指令:
这个指令没有值,表示这个标签初始值用data中数据,但是data中数据再改变时,这个标签的数据也不会再改变了。
11.v-pre指令:
这个标签会直接跳过vue编译,如果标签中使用插值语法,指令语法时都不可以使用这个指令,否则会使得vue不会解析,对于其他普通的就可以加快编译。
12.自定义指令:
指令自己写的,并且这个指令做的事件操作也要定义。
使用时候: 在标签里面v-指令名=‘对谁执行操作’
定义时候: 在new Vue中添加 directives:{
指令名:function(){
要执行什么操作
}
}
定义可以简写为:
directives:{
指令名(element,binding){ .........
}
传的参数是element和binding含义是:element是指标签本身。
如<button v-bind='n'></button>, 而指令v-bind中directives的参数element就是指的<button> </button>
传的参数binding是一个对象,对象里面包含很多内容,但是最重要的是binding.value指的是值。
如:<input v-bind= 'n+1'> 原来n为100,此时binding.value就是n+1=101.
directives:{
bigage(ele, binding){
ele.innerText = binding.value * 20
}
}
注意:要想改变<button> </button>两个<>之间的内容的话,必须获取dom元素再修改,用js语法修改的,可不是通过return去修改中间内容的。
指令什么时候被调用:
指令和元素成功绑定时候(一打开页面),指令所在模板被重新解析时
13.自定义指令-对象式 ![](https://i-blog.csdnimg.cn/blog_migrate/c8a6b3510c34a4ff1005bffdc1d1a70b.jpeg)
如果这个指令有一些特殊的需要,指令就不可以用函数写,而是用对象的形式写:
指令名:{
bind(){}
inserted(){}
update() {}
}