vue样式绑定、事件监听、表单输入绑定、响应接口

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: '百度\r\nhttp://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 方法也已删除。

 

posted @ 2019-11-20 21:39  QiaoZhi  阅读(1126)  评论(0编辑  收藏  举报