1.样式绑定
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
1.绑定class
1.对象语法
我们可以传给 v-bind:class 一个对象,以动态地切换 class,支持多个class。v-bind:class 指令也可以与普通的 class 属性共存。
<div id="app" class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div> <script> var app = new Vue({ el: '#app', data: { isActive: true, hasError: false } }) </script>
渲染后的class如下:
们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:
<div id="app" class="static" v-bind:class="classObject"></div> <script> var app = new Vue({ el: '#app', data: { isActive: true, error: null }, computed: { classObject: function() { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal' } } } }) </script>
渲染后的class如下:
2.数组语法
我们可以把一个数组传给 v-bind:class,以应用一个 class 列表
<div id="app" class="static" v-bind:class="[activeClass, errorClass]"></div> <script> var app = new Vue({ el: '#app', data: { activeClass: 'active', errorClass: 'text-danger' } }) </script>
结果:
也可以用三元表达式:
<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>
渲染后的class如下:
在数组语法中也可以使用对象语法:
<div id="app"> <div v-bind:class="[{ active: isActive }, errorClass]"></div> </div> <script> new Vue({ el: '#app', data: { isActive: true, errorClass: 'text-danger' } }) </script>
渲染后的class如下:
2.绑定内联样式
1.对象语法
v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
<div id="app"> <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">vue 6a!</div> </div> <script> new Vue({ el: '#app', data: { activeColor: 'green', fontSize: 30 } }) </script>
结果:
渲染后css:
直接绑定到一个样式对象通常更好,这会让模板更清晰
<div id="app"> <div v-bind:style="styleObject">vue 6a!</div> </div> <script> new Vue({ el: '#app', data: { styleObject: { color: 'red', fontSize: '13px' } } }) </script>
结果:
渲染后css:
对象语法常常结合返回对象的计算属性使用。
2.数组语法
数组语法可以将多个样式对象应用到同一个元素上:
<div id="app"> <div v-bind:style="[baseStyles, overridingStyles]">vue 6a!</div> </div> <script> new Vue({ el: '#app', data: { baseStyles: { color: 'red', fontSize: '13px' }, overridingStyles: { color: 'black' } } }) </script>
结果:
渲染后css:
3.自动添加前缀
当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。
2. 事件监听
1. 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<div id="example-1"> <button v-on:click="counter += 1">Add 1</button> <p>The button above has been clicked {{ counter }} times.</p> </div> <script type="text/javascript"> var example1 = new Vue({ el: '#example-1', data: { counter: 0 } }) </script>
结果:
2. v-on 还可以接收一个需要调用的方法名称。
<div id="example-2"> <!-- `greet` 是在下面定义的方法名 --> <button v-on:click="greet">Greet</button> </div> <script type="text/javascript"> var example2 = new Vue({ el: '#example-2', data: { name: 'Vue.js' }, // 在 `methods` 对象中定义方法 methods: { greet: function(event) { // `this` 在方法里指向当前 Vue 实例 console.log('Hello ' + this.name + '!') // `event` 是原生 DOM 事件 if(event) { console.log(event.target.tagName) } } } }) // 也可以用 JavaScript 直接调用方法, 不会调用event里面的console // example2.greet() // => 'Hello Vue.js!' </script>
结果:
3.除了直接绑定到一个方法,也可以用内联 JavaScript 语句:
<div id="example-3"> <button v-on:click="say('hi')">Say hi</button> <button v-on:click="say('what')">Say what</button> </div> <script type="text/javascript"> new Vue({ el: '#example-3', methods: { say: function(message) { alert(message) } } }) </script>
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法:
<div id="example-3"> <button v-on:click="warn('Form cannot be submitted yet.', $event)"> Submit </button> </div> <script type="text/javascript"> new Vue({ el: '#example-3', methods: { warn: function(message, event) { // 现在我们可以访问原生事件对象 if(event) event.preventDefault() alert(message) } } }) </script>
4.事件修饰符
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。Vue.js通过由点(.)表示的指令后缀来调用修饰符。
<!-- 阻止单击事件冒泡 --> <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>
5.按键修饰符
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
3.表单输入绑定
可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
注意:(1)v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
(2)v-model 会根据控件类型自动选取正确的方法来更新元素。v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
1.基本使用
例如:(表单元素的演示)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script src="js/vue.min.js"></script> </head> <body> <h3>输入框</h3> <div id="app"> <p>input 元素:</p> <input v-model="message" placeholder="编辑我……"> <p>消息是: {{ message }}</p> <p>textarea 元素:</p> <p style="white-space: pre">{{ message2 }}</p> <textarea v-model="message2" placeholder="多行文本输入……"></textarea> </div> <script> new Vue({ el: '#app', data: { message: 'vue', message2: '百度 http://www.baidu.com' } }) </script> <h3>复选框如果是一个为逻辑值,如果是多个则绑定到同一个数组:</h3> <div id="app2"> <p>单个复选框:</p> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label> <p>多个复选框:</p> <input type="checkbox" id="vue" value="vue" v-model="checkedNames"> <label for="vue">vue</label> <input type="checkbox" id="google" value="Google" v-model="checkedNames"> <label for="google">Google</label> <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames"> <label for="taobao">taobao</label> <br> <span>选择的值为: {{ checkedNames }}</span> </div> <script> new Vue({ el: '#app2', data: { checked: false, checkedNames: ['vue', 'Google'] } }) </script> <h3>单选按钮</h3> <div id="app3"> <input type="radio" id="vue" value="vue" v-model="picked"> <label for="vue">vue</label> <input type="radio" id="google" value="Google" v-model="picked"> <label for="google">Google</label> <br> <span>选中值为: {{ picked }}</span> </div> <script> new Vue({ el: '#app3', data: { picked: 'vue' } }) </script> <h3>下拉列表</h3> <div id="app4"> <select v-model="selected" name="fruit"> <option value="">选择一个网站</option> <option value="www.baidu.com">Baidu</option> <option value="www.google.com">Google</option> </select> <div id="output"> 选择的网站是: {{selected}} </div> </div> <script> new Vue({ el: '#app4', data: { selected: 'www.google.com' } }) </script> </body> </html>
结果:
2.修饰符
.lazy:在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步。(相当于onchange事件)
.number:如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值。
.trim:如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入。
例如:
<h3>输入框</h3> <div id="app"> <input v-model.trim="name"> <p>name是: {{ name }}</p> <input v-model.number="age"> <p>age是: {{ age }}</p> <input v-model.lazy="sex"> <p>sex是: {{ sex }}</p> </div> <script> new Vue({ el: '#app', data: { name: 'zs', age: '25.5', sex: '女', } }) </script>
4.响应接口
Vue 可以添加数据动态响应接口
1.通过使用 $watch 属性来实现数据的监听,$watch 必须添加在 Vue 实例之外才能实现正确的响应。
<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 + '!'); }); setTimeout( function() { vm.counter += 20; }, 10000 ); </script>
Vue 不能检测到对象属性的添加或删除,最好的方式就是在初始化实例前声明根级响应式属性,哪怕只是一个空值。
如果我们需要在运行过程中实现属性的添加或删除,则可以使用全局 Vue,Vue.set 和 Vue.delete 方法。
2.Vue.set-用于设置对象的属性
Vue.set 方法用于设置对象的属性,它可以解决 Vue 无法检测添加属性的限制,语法格式如下:
Vue.set( target, key, value )
(1)基本的给对象添加属性的方法
<div id = "app"> <p style = "font-size:25px;">计数器: {{ products.id }}</p> <button @click = "products.id++" style = "font-size:25px;">点我</button> </div> <script type = "text/javascript"> var myproduct = {"id":1, name:"book", "price":"20.00"}; var vm = new Vue({ el: '#app', data: { products: myproduct } }); vm.products.qty = "1"; console.log(vm); vm.$watch('products.id', function(nval, oval) { alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!'); }); </script>
结果:
在产品中添加了数量属性 qty,但是 get/set 方法只可用于 id,name 和 price 属性,却不能在 qty 属性中使用。不能通过添加 Vue 对象来实现响应。 Vue 主要在开始时创建所有属性。
(2)通过Vue.set设置
<div id="app"> <p style="font-size:25px;">计数器: {{ products.id }}</p> <button @click="products.id++" style="font-size:25px;">点我</button> </div> <script type="text/javascript"> var myproduct = { "id": 1, "name": "book", "price": "20.00" }; var vm = new Vue({ el: '#app', data: { products: myproduct } }); Vue.set(myproduct, 'qty', 1); console.log(1); console.log(vm); vm.$watch('products.id', function(nval, oval) { alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!'); }); </script>
结果:从控制台输出的结果可以看出 get/set 方法可用于qty 属性。
3.Vue.delete-删除动态添加的属性
语法如下:
Vue.delete( target, key )
例如:使用 Vue.delete 来删除 price 属性
<div id="app"> <p style="font-size:25px;">计数器: {{ products.id }}</p> <button @click="products.id++" style="font-size:25px;">点我</button> </div> <script type="text/javascript"> var myproduct = { "id": 1, name: "book", "price": "20.00" }; var vm = new Vue({ el: '#app', data: { products: myproduct } }); Vue.delete(myproduct, 'price'); console.log(vm); vm.$watch('products.id', function(nval, oval) { alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!'); }); </script>
结果:可以看到 price 属性已删除,只剩下了 id 和 name 属性,price 属性的 get/set 方法也已删除。