vue系列教程-05vue常用指令
本内容为系列内容,全部内容请看我的vue教程分类
v-bind
上面讲了页面怎么渲染数据,那么vue如何给一些空间绑定数据呢?
比如 图片链接、单选框、样式等等 这里就要使用到 v-bind
首先初始化一个 vue项目,定义一个图片链接字符串
<script>
let vm = new Vue({
el: '#app',
data() {
return {
avatar: 'https://www.baidu.com/img/bd_logo1.png',
}
},
created() {
},
})
</script>
先回想一下我们在页面中是如何使用图片地址的
<img src="https://www.baidu.com/img/bd_logo1.png" alt="">
但是我们这里 这个图片地址是定义在 data中的那么如何使用呢?使用 v-bind命令并且指明是绑定 src 属性
<img v-bind:src="avatar" alt="">
打开浏览器看下效果为了方便展示我们给全页面的img都指定一个样式
<style>
img {
height: 100px;
width: 100px;
}
</style>
是完全可以的 而且这个 v-bind是可以简写的,直接写 :就可以了
<img :src="avatar" alt="">
那么这里你就疑问了?这个绑定到底有啥用啊?我不如直接把链接写到页面中啊
我们还是在data里面定义这个userlist这个数据,然后每个用户我们都添加一个 avatar属性
data() {
return {
avatar: 'https://www.baidu.com/img/bd_logo1.png',
userlist: [
{ name: 'lookroot', age: 20, sex: 1, avatar: 'https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=218375221,1552855610&fm=111&gp=0.jpg' },
{ name: 'lili', age: 21, sex: 2, avatar: 'https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1305353222,2352820043&fm=26&gp=0.jpg' }
]
}
},
那么现在我要在页面中展示这个userlist数据 并展示头像该怎么做?这个时候就要用到 v-bind了
<ul>
<li v-for="(user,index) in userlist" :key="index">
<img :src="user.avatar" alt="">
{{user.name+'-'+user.age}}
</li>
</ul>
诶你上面说的绑定单选框是怎么回事啊?那么我们这里就在循环中给添加一个节点,性别为1的用户,单选框为选中状态
使用:checked
<ul>
<li v-for="(user,index) in userlist" :key="index">
<img :src="user.avatar" alt="">
{{user.name+'-'+user.age}}
<input type="checkbox" name="" id="" :checked="user.sex===1">
</li>
</ul>
来我们到浏览器看下效果
当然 v-bind还可以绑定其他,我们在后面会提到
v-model
v-model就是数据的双向绑定, 是:value和v-on的结合,这个v-on下一节会讲到,反正通俗点说既可以绑定数据,又可以监控数据的变化同步到 data中,常用在表单中
首先我们在这个 data中定义一个字符串
title: 'lookroot',
然后在页面中使用 v-model将title绑定一个input输入框,并且同时在页面上渲染这个 title字符串
输入<input type="text" v-model="title">输出:<span>{{title}}</span>
打开浏览器查看效果我们可以发现,当修改input框的值的时候,dev-tools插件里面显示 data中的title在发生变化,同时页面中的输出渲染也跟着变化了,这就是v-model的双向绑定
说好的绑定表单呢?来一个吧
首先表单不可能是一个一个字符串的定义吧,我们直接定义一个 user对象来当做表单,你说你这个对象里面有些字段怎么还有值啊,这个就是表单的初始化,你看很多地方叫你填写表单都有个默认值吧!
user: {
name: 'lookroot',
age: 12,
sex: 2,
avatar: ''
},
然后来到页面中,这里有个问题啊,加入我们使用 select来选择性别,还得一个一个写男女吗?学以致用啊!上面不是学了循环和绑定数据了吗!
定义一个性别数组,这个count就是对应上面 user中的 sex 因为最终绑定的是这个数字,而不是字符串啊
sexlist: [
{ count: 1, name: '男' },
{ count: 2, name: '女' },
]
我们来到页面中 绑定这个表单对象,这里要注意性别使用了循环和绑定哦!
<form action="">
<input type="text" v-model="user.name">
<input type="text" v-model="user.age">
//循环出 性别的选项
<select v-model="user.sex">
<option :value="sex.count" v-for="(sex,index) in sexlist">{{sex.name}}</option>
</select>
<button >存储</button>
</form>
打开浏览器查看效果,这就完成绑定了!
哎呀你说搞这些有个啥用啊?以前表单直接一个 name属性 就直接提交后台了,但是现在前后端分离,前端就需要收集这些数据,然后将这些数据传递给后台,如果绑定了这些表单数据的话,我是不是触发点击事件的时候,直接就把data中的数据传递给后台就行了啊!
v-if和v-show
还记得jquery里面的 show()
和hide()
用来控制显示与隐藏的方法吗?
vue同样有用来控制显示的方法就是 v-if
和v-show
示例
我们初始化一个vue项目,定义一个属性isShow值为false
<script>
let vm = new Vue({
el: '#app',
data() {
return {
//是否显示
isShow: false,
}
},
created() {
},
})
</script>
我们来到页面中,两个div分别绑定了 v-if
和 v-show
绑定的属性都是 isShow
,也就是都是绑定的 false当前两个盒子默认不显示
<div id="app">
<div v-if="isShow">v-if isShow</div>
<div v-show="isShow">v-show isShow</div>
</div>
然后打开浏览器查看效果,发现一片空白,
我们打开dev-tools,修改isshow的值为true,发现盒子展示出来了
那么你说这个 v-if和 v-show都能控制它显示和隐藏,那么有什么区别呢?
我们来到浏览器的elements页面,通过切换显示与隐藏,然后截图可以发现,v-show的切换显示与隐藏知识加了一个display:none
,而v-if是删除掉了这个节点
那么分别用在什么场景呢?
v-if有更高的切换消耗,v-show有更高的初始渲染消耗,
所以经常切换显示与隐藏的使用 v-show;初始化页面的时候就控制是否显示与隐藏的使用 v-if,减轻渲染压力
这里举一个例子,我们添加一个 loginUser 对象,sex性别为2
data() {
return {
//是否显示
isShow: false,
//用户
loginUser: { name: 'lookroot', sex: 2 }
}
},
那么我们在页面中定义好,只显示性别为1的用户,这样做页面一开始就不会渲染了,减轻了渲染压力
<!-- 性别为1的才显示 -->
<div v-if="loginUser.sex===1">{{loginUser.name+'-'+loginUser.sex}}</div>
v-if和v-for不建议在一起使用
为什么?因为v-if和v-for在同一个节点上使用,v-for具有更高的优先级,也就是循环一个元素就要进行一次判断
比如我们定义一个新的数据
userlist: [
{ name: 'lookroot', sex: 2 },
{ name: 'lili', sex: 1 }
]
然后我们在页面中使用 v-for循环渲染出用户数据,并且使用 v-if来判断 sex===1的人才显示
<ul>
<li v-for="(loginUser,index) in userlist" v-if="loginUser.sex===1">{{loginUser.name+'-'+loginUser.sex}}</li>
</ul>
打开浏览器查看效果,是完全可以的
但是这里就有一个问题如果修改了 userlist的数据,页面会重新渲染,哪怕你只修改了一个用户的数据,页面都要重新渲染一次,每次都要循环再判断性别,很大的性能消耗
那么正确的方式应该是怎么做呢?
官方推荐是使用 计算属性这个我们后面会讲,但是这里我可以先讲思路,就是这个v-for循环的数据我们给它的就是处理过后的,不给它完整的数组
比如修改一下刚刚的 data中定义的userlist,这样v-for在循环的时候就已经是只有sex===1的用户数组了,也就用不上 v-if了
userlist: [
{ name: 'lookroot', sex: 2 },
{ name: 'lili', sex: 1 }
].filter(function (user) {
return user.sex === 1;
})
watch监听器
顾名思义,就是监听,那么监听什么呢?就是监听data中的属性,就好比网警,你出界了可不行
我们来简单实践一下吧 定义一个 fontsize 属性
<script>
let vm = new Vue({
el: '#app',
data() {
return {
fontSize: 24,
}
},
})
</script>
这个监听器怎么写呢,它是vue的一个属性,所以要传递到实例化vue的属性中,然后他可以定义多个监听器,监听器的名称就是你要监听data中哪个属性的名称,这里我们监听 fontSize 括号两个参数,第一个是当前最新数据,第二个是上一次的数据,每当这个 fontsize数据变化的时候 监听器就会执行 ,这里我们先打印一下
let vm = new Vue({
el: '#app',
data() {
return {
fontSize: 24,
}
},
//监听器
watch: {
fontSize(newval, oldval) {
console.log(newval,oldval);
}
},
})
那么怎么去修改这个 fontsize的值呢,我们在页面中使用 v-model绑定给一个拖动条
<input type="range" v-model="fontSize" min="0" max="100" step="5" />
浏览器查看一下效果
那你说这个有啥用啊?这个比如这个字体太大了我们就阻止它修改
watch: {
fontSize(newval, oldval) {
// console.log(newval,oldval);
if (newval > 50) {
alert('字体太大了啊!');
//同时把旧的值又赋值给fontsize 这样就阻止它拖动了
this.fontSize = oldval;
return;
}
}
},
查看一下效果
computed计算属性
这个也是顾明思议,就是计算嘛那么怎么个计算法呢?
在data中定义两个数字
count1: null,
count2: null,
并在页面中使用 v-model绑定
<input type="text" v-model.number="count1">
<input type="text" v-model.number="count2">
那么我现在想我输入这两个输入框的时候就计算出他们的和该怎么做?使用 computed计算属性,他和监听器一样也是vue的属性,所以需要在vue属性中定义,这里我们定义一个 num的计算属性,我们不需要在data中定义,因为它本身就是一个属性,可以直接使用
let vm = new Vue({
el: '#app',
data() {
return {
count1: null,
count2: null,
}
},
// 计算属性
computed: {
//计算和
num() {
//计算和
return this.count1 + this.count2;
},
},
})
我们在页面中渲染出这个 num
<div>输出:{{num}}</div>
打开浏览器看下效果
还记得在讲 v-if的时候说过 v-if和 v-for不建议一起使用吗?官方推荐先处理数据,当时我提过使用计算属性来处理
我们来实践一下,我们把userlist复制过来
userlist: [
{ name: 'lookroot', sex: 2 },
{ name: 'lili', sex: 1 }
],
然后新增一个计算属性showuserlist
那么他的值就是处理过的 userlist
// 计算属性
computed: {
//计算和
num() {
return this.count1 + this.count2;
},
//返回应该渲染的数组
showuserlist() {
return this.userlist.filter((user) => {
return user.sex === 1;
})
}
},
我们在页面中就可以直接渲染这个计算属性了
<ul>
<li v-for="(loginUser,index) in showuserlist">{{loginUser.name+'-'+loginUser.sex}}</li>
</ul>
看下效果