Vue 指令v-bind和v-on

Vue2 指令v-bind和v-on

从这篇文章开始,总结一下Vue中的指令。这篇文章总结v-bind和v-on指令。

(1)v-bind

v-bind的基本用法是动态更新HTML元素上的属性,如id,class,href,src等。
下面以class为例:

1.v-bind可以用来动态切换class
对象语法
<style>
    .left{
        color:red;
    }
</style>
<body>
<div id="app">
    <div v-bind:class="{left:isleft}">{{message}}</div>
    <div v-on:click="change">点击此处改变isleft的值</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message:"你好!",
            isleft: true
        },
        methods: {
           change:function(){
               if(this.isleft=true){
                   this.isleft=false;
               }else{
                   this.isleft=true;
               }
           }

        }
    })
</script>
</body>

上面的代码中,类left存在与否取决于isleft的值,如果isleft的值为true,则类left存在,div中的字体颜色为红色,渲染结果为:

<div class="left">你好!</div>
<div>点击此处改变isleft的值</div>

当点击了文字部分之后,isleft的值变为false,类left不再存在,因而此时的“你好!”颜色是黑色,渲染结果为:

<div class>你好!</div>
<div>点击此处改变isleft的值</div>

普通class可以和v-bind:class共存:

<div id="app">
    <div class="up" v-bind:class="{left:isleft}">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message:"你好!",
            isleft: true
        },
    })
</script>

渲染之后的结果为:

<div class="up left">你好!</div>

绑定的数据对象也可以定义在data中:

<div id="app">
    <div v-bind:class="className">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message:"你好!",
            className:{
                left:true
            },
        },
    })
</script>

渲染结果为:

<div class="left">你好!</div>

绑定的数据对象还可以是计算属性:

<div id="app">
    <div v-bind:class="className">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
            left: true,
            right: false,
            up: false,
            down: true,
        },
        computed: {
            className: function () {
                return {
                    left: this.left && this.down,
                    right: this.right && this.up
                }

            }
        }
    })
</script>

渲染结果为:

<div class="left">你好!</div>

除了计算属性,也可以绑定一个类似计算属性的方法。

数组语法

我们还可以把一个数组传给v-bind:class

<div id="app">
    <div v-bind:class="[classLeft,classRight]">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
            classLeft:"left",
            classRight:"right"
        },
    })
</script>

渲染结果为:

<div class="left right">你好!</div>

也可以使用三元表达式:

<div id="app">
    <div v-bind:class="[is?classLeft:classRight]">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
            is:true,
            classLeft:"left",
            classRight:"right"

        },
    })
</script>

渲染结果为:

<div class="left">你好!</div>

可以在数组语法中使用对象语法:

<div id="app">
    <div v-bind:class="[{left:is},classRight]">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
            is: true,
            classRight: "right"
        },
    })
</script>

渲染结果为:

<div class="left right">你好!</div>
2.v-bind可以用来绑定内联样式
<div id="app">
    <!--对象语法1-->
    <div v-bind:style="{color:Color,fontSize:fontSize+'px'}">{{message}}</div>

    <!--对象语法2-->
    <div v-bind:style="style">{{message}}</div>

    <!--数组语法-->
    <div v-bind:style="[style,style1]">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
            Color: "red",
            fontSize: 30,

            style:{
                color:"red",
                fontSize:"30px"
            },
            style1:{
                width:"30px",
                height:"30px"
            }
        },
    })
</script>

还可以为style绑定一个计算属性:

<div id="app">
    <div v-bind:style="style">{{message}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
        },
        computed:{
            style:function(){
                return {
                    color:"red",
                    fontSize:"30px"
                }
            }
        }
    })
</script>
多重值

可以为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。

3.v-bind语法糖

Vue.js为v-bind提供了语法糖,也就是缩写:

    <div v-bind:class="a"></div>
    <div :class="a"></div>

上面两种写法是等价的,也就是说,可以省略v-bind,直接写:

(2)v-on:

在上一篇文章《Vue 方法与计算属性》中提到过v-on指令的用法,这里不再赘述,补充一下前面没有提到过的。
v-on后面可以加事件修饰符(.)来指出一个指令以特殊的方式绑定。

1.事件修饰符

.stop
.prevent
.capture
.self
.once
.passive

.stop 阻止事件冒泡
<div id="app">
    <div v-on:click="do0">
        <div v-on:click.stop="do1">点击这里</div>
    </div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
        },
        methods: {
            do0: function () {
                console.log("这是外层div")
            },
            do1: function () {
                console.log("这是内层div")
            }
        }
    })
</script>

点击文字部分时,只会触发do1方法。阻止事件冒泡,不会触发do0事件。

.prevent 提交时不再重载页面
<div id="app">
    <form v-on:submit.prevent>
        <input type="text" name="username" ><br/>
        <input type="submit" name="" value="提交">
    </form>
</div>
<script>
    window.onload = function() {
        alert('页面加载 执行了 window.onload');
    };
</script>
.capture 当元素发生冒泡时,先触发带有该修饰符的元素绑定的事件
<div id="app">
    <div v-on:click.capture="do0">0
        <div v-on:click="do1">1
            <div v-on:click="do2">2
            </div>
        </div>
    </div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
        },
        methods: {
            do0: function () {
                console.log("0")
            },
            do1: function () {
                console.log("1")
            },
            do2:function(){
                console.log("2")
            }
        }
    })
</script>

当点击了“2”之后,依次输出:0,2,1。点击了“2”之后先触发带有.capture修饰符的元素绑定的事件do0,之后是事件冒泡的过程,由内到外依次触发do2、do1事件。
更为复杂的例子:

<div id="app">
    <div id="a0" v-on:click.capture="doq">a0
        <div id="a1" v-on:click="doq">a1
            <div id="a2" v-on:click.capture="doq">a2
                <div id="a3" v-on:click="doq">a3
                    <div id="a4" v-on:click="doq">a4

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
        },
        methods: {
            doq: function () {
                let id= event.currentTarget.id;
                console.log(id);
                //a0
                //a2
                //a4
                //a3
                //a1
            },
        }
    })
</script>

在点击时,先从外到内触发具有.capture修饰符的元素上的事件,之后是事件冒泡的过程,也就是剩下的元素的事件由内到外触发。

上面是点击a4之后输出的结果:a0、a2、a4、a3、a1
如果点击a3,依次输出的结果为:a0、a2、a3、a1
如果点击a2,依次输出的结果为:a0、a2、a1
如果点击a1,依次输出的结果为:a0、a1

.self 只当事件在该元素本身(而不是子元素)触发时才执行相应的操作
<div id="app">
    <div v-on:click="do1">这是1
        <div v-on:click.self="do2">这是2
            <div v-on:click="do3">这是3

            </div>
        </div>
    </div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
        },
        methods: {
            do1: function () {
                console.log("1")
            },
            do2: function () {
                console.log("2")
            },
            do3:function(){
                console.log("3")
            }
        }
    })
</script>

上面代码中:
点击这是3,依次输出:3,1
点击这是2,依次输出:2,1
在“这是2”上具有.self修饰符,.self会监听事件是否直接作用在“这是2”上,如果不是就在事件冒泡过程中跳过该元素 ,也就是说如果不点击“这是2”,就无法触发上面绑定的事件。

.once事件只会触发一次
<div id="app">
    <div v-on:click.once="do1">这是1</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        methods: {
            do1: function () {
                console.log("这是1")
            },
        }
    })
</script>

多次点击“这是1”,只会输出一次。

.passive不会阻止事件的默认行为

现在addEventListener有三个参数:

addEventListener(type, function, {
    capture: false,
    passive: false,
    once: false
})

第一个是监听的事件类型,第二个是事件触发时执行的函数,第三个可以是一个对象,是可选的。
1、capture指定事件是在捕获或冒泡阶段执行,false为默认值。
true - 事件在捕获阶段执行。false-事件在冒泡阶段执行。
2、once 表明该监听器只监听一次。
3、passive表示不会阻止事件的默认行为,也就是说设置了passive之后,再调用 preventDefault()是无效的。
移动端页面经常会监听touchstart等事件:

document.addEventListener("touchstart", function(e){
    // 浏览器不知道这里会不会有 e.preventDefault()
})

touchstart 事件的默认行为是滚动当前页面,可以被监听器通过 preventDefault() 方法阻止。但浏览器无法预先知道一个监听器会不会调用 preventDefault(),它只有等监听器执行完后再看是否执行默认行为,而监听器执行是要耗时的,这样就可能导致页面卡顿。
passive表示不会阻止事件的默认行为,设置了passive之后,就可以在两个线程里同时执行监听器中的 JavaScript 代码和浏览器的默认行为了。
.passive 修饰符就是对应 addEventListener 中的 passive 选项。
所以说.passive 修饰符尤其能够提升移动端的性能。
.passive 和 .prevent 一起使用时 .prevent 将会被忽略。

修饰符可以串联,也可以只使用修饰符
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
2.按键修饰符

在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 `keyCode` 是 13 时调用 `submit方法` -->
<input v-on:keyup.13="submit">

Vue 为最常用的按键提供了别名:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
可以通过全局 config.keyCodes 对象自定义按键修饰符别名:

<div id="app">
    <input type="text" v-on:keyup.qwe="do0" >
</div>
<script>
    Vue.config.keyCodes.qwe =16 ;
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好!",
        },
        methods: {
            do0: function () {
                console.log("0")
            },
        }
    });
</script>

上面代码,把shift键的别名定义为qwe,之后可以使用v-on:keyup.qwe="do0"去触发事件do0。

3.自动匹配按键修饰符
4.系统修饰符

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta

<input @keyup.ctrl="clear">

请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 不会触发事件。
如果想要释放 ctrl 触发事件,为 ctrl 换用 keyCode:keyup.17:

<input @keyup.17="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

上面代码,点击的同时需要按住ctrl键才会触发事件,但是在按住ctrl键的同时按住其它的键也会触发事件。

.exact 修饰符允许控制由精确的系统修饰符组合触发的事件。

<!-- Ctrl和其它键被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>
5.鼠标按钮修饰符

.left
.right
.middle

参考:
1.Vue.js官方文档
2.关于.passive修饰符

猜你喜欢

转载自blog.csdn.net/weixin_42695446/article/details/84680018