Vue.js 计算属性
计算属性关键词: computed。
计算属性在处理一些复杂逻辑时是很有用的。
可以看下以下反转字符串的例子:
<template>
<div id="app">
<p>{{info}}</p>
<p>{{reverse}}</p>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
info:'califonia'
}
},
computed:{
reverse(){
return this.info.split('').reverse().join('');
}
}
}
</script>
<style scoped>
</style>
computed vs methods
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter
在使用 reversedMessage 这个计算属性的时候,第一次会执行代码,得到一个值,以后再使用 reversedMessage 这个计算属性,因为 vm 对象没有发生改变,于是界面渲染就直接用这个值,不再重复执行代码。而 reversedMessage2 没有这个缓存,只要用一次,函数代码就执行一次,于是每次返回值都不一样。
<template>
<div id="app">
<p>{{info}}</p>
computed计算,不需要加()
<p>第一次:{{reverse1}}</p>
<p>第二次:{{reverse1}}</p>
methods方法,需要加()
<p>第一次:{{reverse2()}}</p>
<p>第二次:{{reverse2()}}</p>
</div>
</template>
<script>
var count=1;
export default {
name: 'App',
data(){
return{
info:'baidu'
}
},
computed:{
reverse1(){
count+=1;
return count+this.info.split('').reverse().join('');
}
},
methods:{
reverse2(){
count+=1;
return count+this.info.split('').reverse().join('');
}
}
}
</script>
<style scoped>
</style>
当你没有使用到计算属性的依赖缓存的时候,可以使用定义方法来代替计算属性,在 methods 里定义一个方法可以实现相同的效果,甚至该方法还可以接受参数,使用起来更灵活。
在vue.js中,有methods和computed两种方式来动态当作方法来用的。
- 1.首先最明显的不同 就是调用的时候,methods要加上()
- 2.我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。
而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
Vue.js 监听属性
可以通过 watch 来响应数据的变化。
以下实例通过使用 watch 实现计数器:
<template>
<div id="app">
<p>{{count}}</p>
<button @click="count++">click me</button>
</div>
</template>
<script>
var count=1;
export default {
name: 'App',
data(){
return{
count:1
}
},
watch:{
count(nVal,oVal){
console.log('oldValue: '+nVal+' newValue: '+oVal);
}
}
}
</script>
<style scoped>
</style>
以下实例进行千米与米之间的换算:
<template>
<div id="app">
kilometers:
<input type="text" v-model="kilometers">
<br>
meters:
<input type="text" v-model="meters">
</div>
</template>
<script>
var count=1;
export default {
name: 'App',
data(){
return{
kilometers:0,
meters:0
}
},
watch:{
kilometers(val){
this.kilometers=val;
this.meters=val*1000;
},
meters(val){
this.meters=val;
this.kilometers=val/1000;
},
}
}
</script>
<style scoped>
</style>
模拟购物车效果
<template>
<div id="app">
<table>
<tr>
<th>序号</th>
<th>商品名</th>
<th>价格</th>
<th>数量</th>
<th>操作</th>
</tr>
<tr v-for="item in list" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>
<button v-bind:disabled="item.count===0" v-on:click="item.count--">-</button>
{{item.count}}
<button v-on:click="item.count++">+</button>
</td>
<td><button v-on:click="item.count=0">移除</button></td>
</tr>
</table>
<p>总价:{{total()}}</p>
</div>
</template>
<script>
var count=1;
export default {
name: 'App',
data(){
return{
list:[
{
id:1,
name:'iphone6',
price:6000,
count:1
},
{
id:2,
name:'iphone8',
price:7000,
count:1
},
{
id:3,
name:'iphonex',
price:8000,
count:1
}
]
}
},
methods:{
total(){
var totalPrice=0;
for(var i=0;i<this.list.length;i++){
totalPrice+=this.list[i].price*this.list[i].count;
}
return totalPrice;
}
}
}
</script>
<style scoped>
table {
border: 1px solid black;
}
table {
width: 100%;
}
th {
height: 50px;
}
th, td {
border-bottom: 1px solid #ddd;
}
</style>
简单的省市联动
<template>
<div id="app">
省:
<select v-model="province">
<option>请选择</option>
<option v-bind:value="p" v-for="p in provinces" :key="p">{{p}}</option>
</select>
市:
<select v-model="city">
<option>请选择</option>
<option v-bind:value="c" v-for="c in cityList" :key="c">{{c}}</option>
</select>
</div>
</template>
<script>
var count=1;
export default {
name: 'App',
data(){
return{
city: '请选择',
province: '请选择',
provinces: ['广东', '湖南', '湖北', '北京'],
cityList: [],
area: [{
name: '广东',
id: 1,
child: ['广州', '深圳', '东莞']
},
{
name: '湖南',
id: 2,
child: ['长沙', '株洲', '湘潭']
},
{
name: '湖北',
id: 3,
child: ['武汉']
},
{
name: '北京',
id: 4,
child: ['北京']
}]
}
},
watch:{
province(nVal,oVal){
if(nVal==='请选择'){
this.cityList=[];
}
if(nVal!==oVal){
for(var i=0;i<this.area.length;i++){
if(this.area[i].name===nVal){
this.cityList=this.area[i].child;
}
}
}
this.city='请选择';
}
}
}
</script>
<style scoped>
</style>
来源:oschina
链接:https://my.oschina.net/u/4410617/blog/3290467