vue学习记录之模版语法2
绑定Class和Style
v-bind
指令可以绑定任意常规类型的变量,而vue对class
和style
样式的绑定做了一定的优化,绑定它们时还可以绑定数组、对象类型的变量。
<!-- class 绑定 -->
<div :class="{ red: isRed }"></div><!-- 此处isRed根据是否真值控制red类是否启用 -->
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 可以绑定多个值,针对提供多前缀的属性,浏览器不支持的前缀将不会被渲染(vue还支持自动添加前缀) -->
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
动态绑定的样式可以与常规的class
、style
属性共存。
计算属性和侦听器
计算属性
虽然模版语法支持js表达式,但是它并不适用复杂计算式,如果需要用到复杂计算时我们可以用组件的methods
去实现,而Vue
还提供了一个计算属性让我们专门用来做这样一件事。先来看下示例:
<h1>{{ tips }}</h1>
<div>{{divMsg}}</div>
<div>{{divMsg}}</div>
<div>{{divMsg}}</div>
<div>{{divMsg2()}}</div>
<div>{{divMsg2()}}</div>
<div>{{divMsg2()}}</div>
export default {
name: "Demo",
data() {
return {
tips: 'this is a demo data'
}
},
methods: {
divMsg2() {
// ... do something
console.log('tips has method.');
return this.tips + ' by method.'
}
},
computed: {
// 计算属性的getter函数
divMsg() {
// ... do something
console.log('tips has computed.');
return this.tips + ' by computed.'
}
}
}
可以看到,computed
与methods
看上去几乎一样,那么不一样的点是什么呢?Vue
与Java
比较像,按Java
解释就是methods
是类里定义的常规函数,computed
里定义的是类里的属性和它的setter
、getter
函数,只是属性可以不写,可以只写个getter
函数,就像上面的方式一样。完整定义方式如下:
// ...
computed: {
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue) {
const names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
// ...
还有一点是computed
会用到缓存,计算属性只在相关响应式依赖发生改变时它们才会重新求值。上面的示例可以看到divMsg
函数的仅被调用了一次,而实际上有3个地方被用到,所以剩下2次都是用的缓存。而divMsg2
则是用到了3次也就被调用了3次,如果是在一个数据比较多的循环中这样用,那将会造成很多的开销。
计算属性会将计算结果放到页面缓存中,只要这个属性没有发生变化就不会更改缓存。
侦听器
上面的计算属性虽然已经很好用了,但是总有需要自己控制什么时候修改数据的需求,Vue也提供了一个更加通用的方式watch
。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
下面是Vue官方的提供的一个示例:
<div id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question" />
</p>
<p>{{ answer }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script>
const watchExampleVM = Vue.createApp({
data() {
return {
question: '',
answer: 'Questions usually contain a question mark. ;-)'
}
},
watch: {
// whenever question changes, this function will run
question(newQuestion, oldQuestion) {
if (newQuestion.indexOf('?') > -1) {
this.getAnswer()
}
}
},
methods: {
getAnswer() {
this.answer = 'Thinking...'
axios
.get('https://yesno.wtf/api')
.then(response => {
this.answer = response.data.answer
})
.catch(error => {
this.answer = 'Error! Could not reach the API. ' + error
})
}
}
}).mount('#watch-example')
</script>