目录
计算属性
当模板中放入太多的逻辑会使得模板过重且难以维护,如下所示:
<div id="exam">
{{ message.split('').reverse().join('') }}
</div>
上例中,模板不是简单的声明式逻辑,而是较为复杂的逻辑,不是一目了然,而是需要看一会儿才能看出是要显示变量的翻转字符串。当想要在模板的多处包含该逻辑时,就会比较难以处理。故对于复杂逻辑,就可以用到计算属性。
计算属性关键词:computed
上例中改成用计算属性进行改良如下:
<div id="exam">
<p>原始字符串:{{ message }}</p>
<p>翻转字符串:{{ reverseMessage }}</p>
</div>
<script>
new Vue({
el:'#exam',
data:{
message:'string'
},
computed:{
//计算属性的getter
reverseMessage:function(){
return this.message.split('').reverse().join('')
}
}
})
</script>
上例中声明一个计算属性reverseMessage,提供的函数将用作属性vm.reverseMessage的getter函数,vm.reverseMessage的值始终取决于vm.message的值,前者依赖于后者。
计算属性缓存
上例中当我们使用methods方法也可以实现翻转效果,如下所示:
<div id="exam">
<p>原始字符串:{{ message }}</p>
<p>翻转字符串:{{ reverseMessage() }}</p>
</div>
<script>
new Vue({
el:'#exam',
data:{
message:'string'
},
methods:{
reverseMessage:function(){
return this.message.split('').reverse().join('')
}
}
})
</script>
也就是说将同一函数定义为一个方法而不是一个计算属性也可以达到相同效果,但两者不同点在于:计算属性是基于它的响应式依赖进行缓存的,只有在相关响应式以来发生改变时它们才会重新求值,也就是reverseMessage计算一个结果之后会缓存上次的计算结果,再度访问直接发送之前的计算结果,只有当message发生改变时才会重新求值。但methods在重新渲染时,函数总会重新调用执行。故计算属性性能性相对来说更好。
计算属性的setter
计算属性默认只有getter,其使用我们在上述例子中已经见过了,但是在实例操作需要时,我们也可以提供一个setter:
<div id="exam">
{{ res }}
</div>
<script>
let vm = new Vue({
el:'#exam',
data:{
name:'张三',
gender:'男',
age:20
},
computed:{
res:{
//getter
get:function(){
return this.name+' '+this.gender+' '+this.age;
},
//setter
set:function(e){
let newvalue = e.split(' ');
this.name = newvalue[0];
this.gender = newvalue[1];
this.age = newvalue[newvalue.length - 1]
}
}
}
})
//调用setter,更新数据
vm.res = '李四 女 18';
</script>
侦听属性
Vue提供侦听属性来观察和响应Vue实例上的数据变动。
计数器示例:
<div id="exam">
<h3>计数器:{{ counter }}</h3>
<button @click="counter++">增加</button>
<button @click="counter--">减小</button>
<div>
<p>计数器的变化:<span id="pre"></span>变为<span id="curr"></span></p>
</div>
</div>
<script>
let get = document.getElementById('test')
let vm = new Vue({
el:'#exam',
data:{
counter:1
}
});
//监听
vm.$watch('counter',function(curr,pre){
document.getElementById('pre').innerHTML = pre;
document.getElementById('curr').innerHTML = curr;
})
</script>
实现效果:
样式绑定
数据绑定常常需要操作元素的class列表和内联样式,我们可以用v-bind进行处理,Vue.js对于这两种需求做了专门的增强,表达式结果的类型除了字符串之外,还可以是对象或者数组。
Class绑定
我们可以传给v-bind:class一个对象,动态地切换class
<style>
.active{
width: 100px;
height: 100px;
background-color: pink;
}
</style>
<body>
<div id="exam">
<div v-bind:class="{'active':isActive}"></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
isActive:true
}
})
</script>
</body>
上例中active这个class存在取决于数据属性isActive,设置为true则显示,反之则不显示。我们也可以在对象中传入更多属性来动态切换多个class,并且v-bind:class指令可以与普通class属性共存:
<div
class="set"
v-bind:class="{'active':isActive,'textChange':isChange}"
></div>
绑定数据内的对象
绑定的数据对象不需要定义在模板里,我们也可以直接绑定数据里的一个对象:
<body>
<div id="exam">
<div v-bind:class="obj" ></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
obj:{
active:true
}
}
})
</script>
</body>
绑定对象计算属性
我们还可以绑定一个返回对象的计算属性:
<div id="exam">
<div v-bind:class="obj" ></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
isActive:true,
error:null
},
computed:{
obj:function(){
return {
active:this.isActive && !this.error
}
}
}
})
</script>
数组语法
应用一个class列表时,我们可以传递一个数组,如下所示:
<div id="exam">
<div v-bind:class="[isActive,isChange]" ></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
isActive:'active',
isChange:'change'
}
})
</script>
三元表达式切换
我们还可以使用三元表达式切换列表中的class
<div id="exam">
<div v-bind:class="[isActive,Change ? isChange : '']" ></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
Change:true,
isActive:'active',
isChange:'change'
}
})
</script>
内联样式绑定
绑定内联样式使用v-bind:style,css属性命名可以使用驼峰式或者短横线分隔(a-b式,引号括起来)进行命名,一般我们采用驼峰式命名法
示例:
<div id="exam">
<div v-bind:style="{backgroundColor:doColor,width:doWidth,height:doHeight}"></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
doColor:'pink',
doWidth:100+'px',
doHeight:100+'px'
}
})
</script>
绑定对象
我们可以直接绑定到一个样式对象上,这样可以使得模板更加清晰
<div id="exam">
<div v-bind:style="obj"></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
obj:{
backgroundColor:'pink',
width:'100px',
height:'100px'
}
}
})
</script>
数组语法
同样,样式绑定也可以使用数组将多给我样式对象应用到一个元素上:
<div id="exam">
<div v-bind:style="[style1,style2]"></div>
</div>
<script>
new Vue({
el:'#exam',
data:{
style1:{
backgroundColor:'pink',
},
style2:{
width:'100px',
height:'100px'
}
}
})
</script>