Vue计算属性
计算属性关键词: computed。计算属性在处理一些复杂逻辑时是很有用的。可以看下以下反转字符串的例子:实例 1:
<div id="app">
{{ message.split('').reverse().join('') }}
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Vue!'
}
})
</script>
输出结果为:!euV
实例 1 中模板变的很复杂起来,也不容易看懂理解。接下来看看使用了计算属性的实例:实例 2:
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Vue!'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
</script>
输出结果为:
原始字符串: Vue!
计算后反转字符串: !euV
实例 2 中声明了一个计算属性 reversedMessage 。提供的函数将用作属性 vm.reversedMessage 的 getter 。vm.reversedMessage 依赖于 vm.message,在 vm.message 发生改变时vm.reversedMessage 也会更新。
computed 和 methods
可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。实例 3:
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>计算后反转字符串: {{ reversedMessage }}</p>
<p>使用方法后反转字符串: {{ reversedMessage2() }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Vue!'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
},
methods: {
reversedMessage2: function () {
return this.message.split('').reverse().join('')
}
}
})
</script>
输出结果为:
原始字符串: Vue!
计算后反转字符串: !euV
使用方法后反转字符串: !euV
可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
computed setter
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter ,实例 4:
<div id="app">
<p>{{ site }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'Google',
url: 'http://www.google.com'
},
computed: {
site: {
// getter
get: function () {
return this.name + ' ' + this.url
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.name = names[0]
this.url = names[names.length - 1]
}
}
}
})
// 调用 setter, vm.name 和 vm.url 也会被对应更新
vm.site = 'Vue教程 http://www.cn.vuejs.org';
document.write('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);
</script>
输出结果为:
Vue教程 http://www.cn.vuejs.org
name: Vue教程
url: http://www.cn.vuejs.org
从实例运行结果看在运行 vm.site = ‘Vue教程 http://www.cn.vuejs.org’; 时,setter 会被调用, vm.name 和 vm.url 也会被对应更新。
Vue监听属性
Vue.js 监听属性 watch,可以通过 watch 来响应数据的变化。以下实例通过使用 watch 实现计数器:
<div id = "app">
<p style = "font-size:25px;">计数器: {{ counter }}</p>
<button @click = "counter++" style = "font-size:25px;">点我</button>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#app',
data: {
counter: 1
}
});
vm.$watch('counter', function(nval, oval) {
alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
</script>
以下实例进行千米与米之间的换算:
<div id = "computed_props">
千米 : <input type = "text" v-model = "kilometers">
米 : <input type = "text" v-model = "meters">
</div>
<p id="info"></p>
<script type = "text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers : 0,
meters:0
},
methods: {
},
computed :{
},
watch : {
kilometers:function(val) {
this.kilometers = val;
this.meters = this.kilometers * 1000
},
meters : function (val) {
this.kilometers = val/ 1000;
this.meters = val;
}
}
});
// $watch 是一个实例方法
vm.$watch('kilometers', function (newValue, oldValue) {
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>
输出结果为:
以上代码中创建了两个输入框,data 属性中, kilometers 和 meters 初始值都为 0。watch 对象创建了两个方法 kilometers 和 meters。当我们在输入框输入数据时,watch 会实时监听数据变化并改变自身的值。
Vue样式属性
Vue.js class
class 与 style 是 HTML 元素的属性,用于设置元素的样式,可以用 v-bind 来设置样式属性。Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。
class 属性绑定
可以为 v-bind:class 设置一个对象,从而动态的切换 class:实例 1:
实例中将 isActive 设置为 true 显示了一个绿色的 div 块,如果设置为 false 则不显示:
<div id="app">
<div v-bind:class="{ 'active': isActive }"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true
}
})
</script>
结果为:
以上实例 div class 为:
<div class="active"></div>
我们也可以在对象中传入更多属性用来动态切换多个 class 。
实例 2:text-danger 类背景颜色覆盖了 active 类的背景色:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
</head>
<body>
<div id="app">
<div class="static"
v-bind:class="{ 'active': isActive, 'text-danger': hasError }">
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
hasError: true
}
})
</script>
</body>
</html>
结果为:
以上实例 div class 为:
<div class="static active text-danger"></div>
我们也可以直接绑定数据里的一个对象:实例 3:text-danger 类背景颜色覆盖了 active 类的背景色:
<div id="app">
<div v-bind:class="classObject"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
classObject: {
active: true,
'text-danger': true
}
}
})
</script>
实例 3 与 实例 2 的渲染结果是一样的。
此外,我们也可以在这里绑定返回对象的计算属性。这是一个常用且强大的模式:实例 4:
new Vue({
el: '#app',
data: {
isActive: true,
error: {
value: true,
type: 'fatal'
}
},
computed: {
classObject: function () {
return {
base: true,
active: this.isActive && !this.error.value,
'text-danger': this.error.value && this.error.type === 'fatal',
}
}
}
})
数组语法
我们可以把一个数组传给 v-bind:class ,实例如下:实例 5:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
</head>
<body>
<div id="app">
<div v-bind:class="[activeClass, errorClass]"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
})
</script>
</body>
</html>
以上实例 div class 为:
<div class="active text-danger"></div>
我们还可以使用三元表达式来切换列表中的 class :实例 6:
errorClass 是始终存在的,isActive 为 true 时添加 activeClass 类:
<div id="app">
<div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
activeClass: 'active',
errorClass: 'text-danger'
}
})
</script>
结果为:
Vue.js style(内联样式)
我们可以在 v-bind:style 直接设置样式:实例 7:
<div id="app">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">Vue教程</div>
</div>
<script>
new Vue({
el: '#app',
data: {
activeColor: 'green',
fontSize: 30
}
})
</script>
结果为:
以上实例 div style 为:
<div style="color: green; font-size: 30px;">Vue教程</div>
也可以直接绑定到一个样式对象,让模板更清晰:实例 8:
<div id="app">
<div v-bind:style="styleObject">Vue教程</div>
</div>
<script>
new Vue({
el: '#app',
data: {
styleObject: {
color: 'green',
fontSize: '30px'
}
}
})
</script>
v-bind:style 可以使用数组将多个样式对象应用到一个元素上:实例 9:
<div id="app">
<div v-bind:style="[baseStyles, overridingStyles]">Vue教程</div>
</div>
<script>
new Vue({
el: '#app',
data: {
baseStyles: {
color: 'green',
fontSize: '30px'
},
overridingStyles: {
'font-weight': 'bold'
}
}
})
</script>
Vue事件处理器
事件监听可以使用 v-on 指令:
<div id="app">
<button v-on:click="counter += 1">增加 1</button>
<p>这个按钮被点击了 {{ counter }} 次。</p>
</div>
<script>
new Vue({
el: '#app',
data: {
counter: 0
}
})
</script>
输出结果为:
通常情况下,我们需要使用一个方法来调用 JavaScript 方法。v-on 可以接收一个定义的方法来调用:
<div id="app">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
// 也可以用 JavaScript 直接调用方法,运行程序直接弹出窗口结果
app.greet() // -> 'Hello Vue.js!'
</script>
输出结果为:
除了直接绑定到一个方法,也可以用内联 JavaScript 语句:
<div id="app">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
say: function (message) {
alert(message)
}
}
})
</script>
事件修饰符
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault()
或 event.stopPropagation()
。Vue.js 通过由点 .
表示的指令后缀来调用修饰符。
.stop - 阻止冒泡
.prevent - 阻止默认事件
.capture - 阻止捕获
.self - 只监听触发该元素的事件
.once - 只触发一次
.left - 左键事件
.right - 右键事件
.middle - 中间滚轮事件
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- click 事件只能点击一次,2.1.4版本新增 -->
<a v-on:click.once="doThis"></a>
按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">
记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
全部的按键别名:
.enter
.tab
.delete (捕获 "删除" 和 "退格" 键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
实例
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>