计算属性
计算属性,将模板中复杂的逻辑,提取出去,使模板变得简洁。
比如,一个字符串反转的实现:
<div id="app1">
{
{msg.split('').reverse().join('')}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app1 = new Vue({
el:'#app1',
data:{
msg:'简单字符反转'
}
});
</script>
这样看起来似乎也挺简单,但是如果改变需求了呢,要求前7个字符要求正常输出,而从第7个字符开始逆序输出。这样的逻辑是不是就复杂起来了。
这个时候,使用computed
来声明一个计算属性,然后在其内部定义函数来对字符串进行处理
<div id="app2">
{
{msg}}<br>
{
{reverseMsg}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app2 = new Vue({
el:'#app2',
data: {
msg:'abcdefg反转?'
},
computed:{
reverseMsg:function () {
let strFirst =this.msg.substring(0,7).split('').reverse().join('');
let strLast =this.msg.substring(7).split('').reverse().join('');
return ""+strFirst+strLast;
}
}
});
</script>
为啥要使用computed属性呢?而不是直接使用一个方法来处理,这样使用计算属性,会不会兜圈子?
上述的同款,改用methods实现:
<div id="app2">
{
{msg}}<br>
{
{reverseMessage()}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app2 = new Vue({
el:'#app2',
data: {
msg:'abcdefg反转?'
},
methods:{
reverseMessage:function () {
let strFirst =this.msg.substring(0,7).split('').reverse().join('');
let strLast =this.msg.substring(7).split('').reverse().join('');
return ""+strFirst+strLast;
}
}
});
</script>
两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 msg还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
class与style的绑定
上篇文章,略微的说过一些v-bind指令的用法,v-bind指令可以动态的为html元素添加属性。
我们可以传给 v-bind:class 一个对象,动态的切换class
<div id="app3" v-bind:class="classObject">app3</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app3 = new Vue({
el:'#app3',
data:{
classObject:{
active:true,
'text-danger':true
}
}
});
</script>
通过classObject对象中的属性值,来动态的决定app3的样式,由下图可见,classObject已经被绑定到了app3中
在传入对象的基础上,绑定一个计算属性(常用且强大的模式)–可以设定多个属性值来决定当前的类属性是否附加,如app4。
<div id="app4" v-bind:class="classLt">app4</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app4 =new Vue({
el:'#app4',
data:{
isActive:true,
error:null
},
computed:{
classLt:function () {
return{
active: this.isActive && !this.error,
//根据isActive和error的值,来决定active是否展露
'text-danger':this.error && this.error.type === 'fatal'
}
}
}
});
</script>
传入一个数组作为类属性:
<div id="app5" v-bind:class="[activeClass,errorClass]">app5</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app5 = new Vue({
el:'#app5',
data:{
activeClass:'active',
errorClass:'text-danger'
}
});
</script>
同样,也可以绑定内联样式,让我们的感受更明显一点(上面绑定对象也可以很明显,自己把对应的css类属性写好就ok啦)
<div id="app6" v-bind:style="{
color:activeColor,fontSize:fontSize+'px'}">内联样式app6</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app6 = new Vue({
el:'#app6',
data:{
activeColor:'red',
fontsize:30
}
});
</script>
多重值
从 2.3.0 起你可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值
<div :style="{
display: ['-webkit-box', '-ms-flexbox', 'flex'] }" id="app8">app8</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app8 =new Vue({
el:'#app8',
data:{
display:{
' -webkit-box':true,
'-ms-flexbox':true,
flex:true
}
}
});
</script>
这样写只会渲染数组中最后一个被浏览器支持的值。
条件渲染and列表渲染
v-if指令,其实就是if…else。v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式为true的时候被渲染。
不过多赘述,直接将v-if ,v-else-if,v-else结合在一块儿的一个例子
<div id="app3">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app3 = new Vue({
el:'#app3',
data:{
type:'E',
}
});
</script>
v-for指令,循环遍历渲染。可以用 v-for 指令基于一个数组来渲染一个列表。
v-for 指令需要使用 item in items 形式的特殊语法,
其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
v-for 遍历数组中的对象时,因为对象都是键值对,然后就需要设定key值来遍历?Map感觉差不多
<ul id="ulList">
<li v-for="item in items" :key="item.message">
{
{item.message}}
</li>
</ul>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var ulList = new Vue({
el:'#ulList',
data:{
items:[
{message:'第二天'},
{message: '基本语法组件过一半'}
]
}
});
在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。v-for = "(item,index) in items"
.
<ul id="ul2">
<li v-for="(item, index) in items">
{
{parentMessage}}-{
{index}}-{
{item.message}}
</li>
</ul>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var ulList = new Vue({
el:'#ul2',
data:{
items:[
{
message:'第二天'},
{
message: '基本语法组件过一半'}
]
}
});
</script>
在v-for里使用并且遍历对象
在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute。
<ul id="ul4">
<li v-for="st in students" v-bind:key="st.sid">
{
{st.sid}}+{
{st.sname}}
</li>
</ul>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let ul4 = new Vue({
el:'#ul4',
data:{
students:[
{
sid:"2020040413",sname:"叶问"},
{
sid:"2020040416",sname:"黄飞鸿"}
]
}
});
</script>
在遍历时,过滤掉自己不喜欢的数据,如下面的例子
<!--做一个过滤奇数-->
<ul id="ul5">
<li v-for="num in nums" >
{
{num}}
</li>
</ul>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let ul5 = new Vue({
el:'#ul5',
data:{
numbers:[1,2,3,4,5,8,6,11,12,78,99]
},
computed:{
nums:function () {
return this.numbers.filter(function (number) {
return number %2 === 0
})
}
}
})
啦啦啦,结束!