Vue事件处理

作者: 小小的开发人员 | 来源:发表于2019-03-29 15:51 被阅读26次

      Vue事件监听的方式貌似违背了关注点分离(separation of concern)的传统理念。实际上,所有的Vue.js事件处理方法和表达式都严格绑定在当前视图的ViewModel上,它不会导致维护上的困难,使用v-on有以下好处:
      1、扫一眼HTML模板便能轻松定位在JS代码里对应的方法。
      2、无须在JS里手动绑定事件,ViewModel代码可以是非常纯粹的逻辑,和DOM完全解耦,更易于测试。
      3、当一个ViewModel被销毁时,所有的事件处理器都会自动被删除,无须担心自己如何清理它们。

    事件监听

      通过v-on指令来绑定事件监听器。

    <div id="app">
      <button v-on:click="counter += 1">增加 1</button>
      <p>这个按钮被点击了 {{ counter }} 次。</p>
    </div>
    
    <script>
    var vm = new Vue({
      el: '#app',
      data: {
        counter: 0
      }
    })
    </script>
    

    【方法】
      许多事件处理的逻辑都很复杂,所以直接把JS代码写在 v-on 指令中有时并不可行,v-on指令可以接收一个定义的方法来调用。
      【注意】不应该使用箭头函数来定义methods函数,因为箭头函数绑定了父级作用域的上下文,所以this将不会按照期望指向 Vue 实例。

    <div id="app">
       <button v-on:click="num">测试按钮</button>
       <p>{{message}}</p>
    </div>
    
    <script>
    var vm = new Vue({
      el: '#app',
      data:{
        counter:0,
        message:''
      },
      methods: {
        num: function (event) {
          if (event) {
            this.message = event.target.innerHTML + '被按下' + ++this.counter + '次';
          }
        }
      }
    })
    </script>
    

    【内联语句】
      除了直接绑定到一个方法,也可以用内联JS语句。

    <div id="app">
      <button v-on:click="say('hi')">Say hi</button>
      <button v-on:click="say('what')">Say what</button>
       <p>{{message}}</p>
    </div>
    
    <script>
    var vm = new Vue({
      el: '#app',
      data:{
        message:''
      },
      methods: {
        say: function (message) {this.message = message;}
      }
    })
    </script>
    

      有时也需要在内联语句处理器中访问原生 DOM 事件,可以用特殊变量 $event 把它传入方法 。

    <div id="app">
      <button v-on:click="say('hi',$event)">Say hi</button>
      <button v-on:click="say('what',$event)">Say what</button>
       <p>{{message}}</p>
    </div>
    
    <script>
    var example = new Vue({
      el: '#app',
      data:{
        message:''
      },
      methods: {
        say: function (message,event) {
          if(event){
            event.preventDefault();
          }  
          this.message = message;
        }
      }
    })
    </script>
    

    事件修饰符

      在事件处理程序中调用event.preventDefault()或event.stopPropagation()是非常常见的需求。尽管可以在methods中轻松实现这点,但更好的方式:methods只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
      为了解决这个问题, Vue.js 为v-on提供了事件修饰符,通过由点(.)表示的指令后缀来调用修饰符。

    .stop 阻止冒泡
    .prevent 阻止默认事件
    .capture 使用事件捕获模式
    .self 只在当前元素本身触发
    .once 只触发一次
    

    下面是一些例子

    <!-- 阻止单击事件冒泡 -->
    <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>
    <!-- 点击事件将只会触发一次 -->
    <a v-on:click.once="doThis"></a>
    

    [注意]使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 @click.prevent.self 会阻止所有的点击,而 @click.self.prevent 只会阻止元素上的点击。

    【stop】
      阻止冒泡

    <div id="app" @click="setVal1" style="border:1px solid black;width:300px;">
      <button @click="setVal">普通按钮</button>
      <button @click.stop="setVal">阻止冒泡</button>
      <button @click="reset">还原</button>
      <div>{{result}}</div>
    </div>
    
    <script>var vm = new Vue({
      el: '#app',
      data:{
        result:''
      },
      methods:{
        setVal(event){
          this.result+=' 子级 ';
        },
        setVal1(){
          this.result+=' 父级 ';
        },
        reset(){
          history.go()
        }
      }
    })
    </script>
    

    【prevent】
      取消默认事件

    <div id="app">
      <a href="http://cnblogs.com" target="_blank">普通链接</a>
      <a @click.prevent href="http://cnblogs.com" target="_blank">取消默认行为</a>
    </div>
    
    <script>
    var vm = new Vue({
      el: '#app'
    })
    </script>
    

    【capture】
      事件捕获模式

    <div id="app" @click.capture="setVal1" style="border:1px solid black;width:300px;">
      <button @click.capture="setVal">事件捕获</button>
      <button @click="reset">还原</button>
      <div>{{result}}</div>
    </div>
    
    <script>var vm = new Vue({
      el: '#app',
      data:{
        result:''
      },
      methods:{
        setVal(event){
          this.result+=' 子级 ';
        },
        setVal1(){
          this.result+=' 父级 ';
        },
        reset(){
          history.go()
        }
      }
    })
    </script>
    

    【self】

    <div id="app">
      <div @click="setVal" :style="styleObj1">
        <div :style="styleObj2">普通</div>
        <button @click="reset">还原</button>
      </div>
      <div @click.self="setVal" :style="styleObj1">
        <div :style="styleObj2">self</div>
        <button @click="reset">还原</button>
      </div>  
    </div>
    
    <script>
    var styleObj1 = {
      display:'inline-block',
      height:'60px',
      width:'120px',
      'background-color': 'lightblue'
    };
    var styleObj2 = {
      display:'inline-block',
      height:'30px',
      width:'60px',
      'background-color': 'lightgreen'
    };
    var vm = new Vue({
      el: '#app',
      data:{
        styleObj1:styleObj1,
        styleObj2:styleObj2
      },
      methods:{
        setVal(event){
          event.target.style.outline="solid"
        },
        reset(){
          history.go()
        }
      }
    })
    </script>
    

    【once】
      只触发一次

    <div id="app">
      <button @click="setVal">普通按钮</button>
      <button @click.once="setVal">触发一次</button>
      <button @click="reset">还原</button>
      <div>{{result}}</div>
    </div>
    
    <script>
    var vm = new Vue({
      el: '#app',
      data:{
        result:''
      },
      methods:{
        setVal(event){
          this.result+=' 内容 ';
        },
        reset(){
          history.go()
        }
      }
    })
    </script>
    

    相关文章

      网友评论

        本文标题:Vue事件处理

        本文链接:https://www.haomeiwen.com/subject/pkblbqtx.html