Vue模板语法(下)

简介: Vue模板语法(下)

一、事件处理

1.1 监听事件

我们可以使用 v-on 指令 (简写为 @) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript。用法:v-on:click="handler"@click="handler"

事件处理器 (handler) 的值可以是:

  • 内联事件处理器:事件被触发时执行的内联 JavaScript 语句 (与 onclick 类似)。
  • 方法事件处理器:一个指向组件上定义的方法的属性名或是路径。

这两种在前面的博客已经有体现

1.2 事件修饰符

在处理事件时调用 event.preventDefault() 或 event.stopPropagation() 是很常见的。尽管我们可以直接在方法内调用,但如果方法能更专注于数据逻辑而不用去处理 DOM 事件的细节会更好。

为解决这一问题,Vue 为 v-on 提供了事件修饰符。修饰符是用 . 表示的指令后缀,包含以下这些:

  • .stop
  • .prevent
  • .self
  • .capture
  • .once
  • .passive
<!-- 单击事件将停止传递 -->
<a @click.stop="doThis"></a>
<!-- 提交事件将不再重新加载页面 -->
<form @submit.prevent="onSubmit"></form>
<!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a>
<!-- 也可以只有修饰符 -->
<form @submit.prevent></form>
<!-- 仅当 event.target 是元素本身时才会触发事件处理器 -->
<!-- 例如:事件处理器不来自子元素 -->
<div @click.self="doThat">...</div>

使用修饰符时需要注意调用顺序,因为相关代码是以相同的顺序生成的。因此使用@click.prevent.self会阻止元素及其子元素的所有点击事件的默认行为,而@click.self.prevent 则只会阻止对元素本身的点击事件的默认行为。

<!-- 添加事件监听器时,使用 `capture` 捕获模式 -->
<!-- 例如:指向内部元素的事件,在被内部元素处理前,先被外部处理 -->
<div @click.capture="doThis">...</div>
<!-- 点击事件最多被触发一次 -->
<a @click.once="doThis"></a>
<!-- 滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成 -->
<!-- 以防其中包含 `event.preventDefault()` -->
<div @scroll.passive="onScroll">...</div>

.capture、.once 和 .passive 修饰符与原生 addEventListener 事件相对应

请勿同时使用 .passive 和 .prevent,因为 .passive 已经向浏览器表明了你不想阻止事件的默认行为。如果你这么做了,则.prevent 会被忽略,并且浏览器会抛出警告。

1.3 按键修饰符

在监听键盘事件时,我们经常需要检查特定的按键。Vue 允许在 v-on 或 @ 监听按键事件时添加按键修饰符。

<!-- 仅在 `key` 为 `Enter` 时调用 `submit` -->
<input @keyup.enter="submit" />

你可以直接使用 KeyboardEvent.key 暴露的按键名称作为修饰符,但需要转为 kebab-case 形式。

<input @keyup.page-down="onPageDown" />

在上面的例子中,仅会在 $event.key 为 ‘PageDown’ 时调用事件处理。

按鍵別名

Vue 为一些常用的按键提供了别名:

  • .enter
  • .tab
  • .delete (捕获“Delete”和“Backspace”两个按键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

1.4 实例

事件冒泡

是指在计算机编程中的一种事件传递机制。

在事件驱动的编程模型中,当用户与程序交互时,例如点击鼠标或按下键盘,这些操作会触发相应的事件。事件冒泡是指当一个元素上的事件被触发时,它会向上级元素传递,直到根元素,这个过程就像气泡从底部冒到顶部一样。

那有时候我们不需要这种情况发生,该怎么解决呢?用咱们的事件修饰符

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
    <style>
      .red{
        width: 400px;
        height: 400px;
        background-color: red;
      }
      .orange{
        width: 300px;
        height: 300px;
        background-color: orange;
      }
      .blue{
        width: 200px;
        height: 200px;
        background-color: blue;
      }
      .black{
        width: 100px;
        height: 100px;
        background-color: black;
      }
    </style>
  </head>
  <body>
    <!-- 定义边界 -->
    <div id="app">
      <p>冒泡事件</p>
      <div class="red" @click="red">
        <div class="orange" @click="orange">
          <div class="blue" @click="blue">
            <!-- 添加stop修饰符阻止冒泡 -->
            <div class="black" @click.stop="black"></div>
          </div>
        </div>
      </div>
      <p>提交答案</p>
        <!-- 只能点一次 -->
      <button @click.once="dosub">提交</button>
      <p>按键修饰符</p>
      <input v-on:keyup.enter="dosub" />
    </div>
  </body>
  <script type="text/javascript">
    // 绑定边界 ES6具体体现
    new Vue({
      el: '#app',
      data() {
        return {
          f200: 'f200'
        };
      },
      methods: {
        red() {
          alert("red");
        },
        orange() {
          alert("orange");
        },
        blue() {
          alert("blue");
        },
        black() {
          alert("black");
        },
        dosub(){
          alert("提交");
        }
      }
    })
  </script>
</html>

二、表单综合案例

在前端处理表单时,我们常常需要将表单输入框的内容同步给 JavaScript 中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦:

<input
  :value="text"
  @input="event => text = event.target.value">

v-model 指令帮我们简化了这一步骤:

<input v-model="text">

另外,v-model 还可以用于各种不同类型的输入,<textarea>、<select> 元素。它会根据所使用的元素自动使用对应的 DOM 属性和事件组合:

  • 文本类型的 <input><textarea> 元素会绑定 value property 并侦听 input 事件;
  • <input type="checkbox"><input type="radio"> 会绑定 checked property 并侦听 change 事件;
  • <select> 会绑定 value property 并侦听 change 事件。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <title>表单</title>
  </head>
  <body>
    <div id="app">
      <h1>vue表单</h1>
          <label>姓名:</label><input v-model="uname" /><br />
          <label>密码:</label><input v-model="upwd" type="password" /><br />
          <!-- 将用户的输入值转为 Number 类型 -->
          <label>年龄:</label><input v-model.number="age" /><br />
          <label>性别:</label>
          <input type="radio" v-model="sex" name="sex" value="1" />男
          <input type="radio" v-model="sex" name="sex" value="0" />女<br />
          <label>爱好:</label>
          <div v-for="h in hobby">
            <input type="checkbox" v-model="hobbies" v-bind:value="h.id" />{{h.name}}
          </div>
          <label>类别:</label>
          <select v-model="type">
            <option value="-1">===请选择===</option>
            <option v-for="t in types" v-bind:value="t.id">{{t.name}}</option>
          </select><br />
          <label>备注:</label>
          <textarea v-bind:value="mark"></textarea><br />
          确认<input type="checkbox" v-model="flag" />
          <input type="submit" v-bind:disabled="show" v-on:click="doSubmit" />
    </div>
  </body>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data() {
        return {
          uname: null,
          upwd: null,
          age: 10,
          sex: 1,
          hobby: [{
            id: 1,
            name: '唱'
          }, {
            id: 2,
            name: '跳'
          }, {
            id: 3,
            name: 'rap'
          }, {
            id: 4,
            name: '篮球'
          }],
          hobbies: [],
          types: [{
            id: 1,
            name: '天帝'
          }, {
            id: 2,
            name: '仙王'
          }, {
            id: 3,
            name: '人皇'
          }],
          type: null,
          mark: '学生备注',
          flag: false
        }
      },
      computed: {
        show: function() {
          return !this.flag;
        }
      },
      methods: {
        doSubmit: function() {
          console.log('doSubmit')
          var obj = {
            uname: this.uname,
            upwd: this.upwd,
            age:this.age+10,
            sex: this.sex,
            hobbies:this.hobbies,
            type: this.type,
            mark: this.mark,
          }
          console.log(obj);
        }
      }
    })
  </script>
</html>

三、自定义组件

Props

Props是一种特别的 attributes,你可以在组件上声明注册。当一个值被传递给 prop 时,它将成为该组件实例上的一个属性。该属性的值可以像其他组件属性一样,在模板和组件的 this 上下文中访问。

一个组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值。

父传子

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
  </head>
  <body>
    <div id="app">
          <h1>{{msg}}</h1>
          <!-- 使用自定义组件my-button的时候进行传值(相当于jsp标签往助手类中传值的概念) -->
          <my-button m="荒 "@click="nb"></my-button>
    </div>
  </body>
  <script>
    // 定义全局组件的方式
    Vue.component('my-button', {
      props: ['m'],
      template: '<button v-on:click="doClickMyButton">我是一个自定义组件,被{{m}}点了{{n}}次</button>',
      data: function() {
        return {
          n: 0
        };
      },
      methods: {
        doClickMyButton: function() {
          console.log('doClickMyButton方法被调用');
          this.n++;
        }
      }
    }),
     new Vue({
      el: "#app",
      data(){
        return{
        msg:'自定义组件'
        };
      }
    });
  </script>
</html>

子传父

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <h1>{{msg}}</h1>
      <!-- 使用自定义组件my-button的时候进行传值(相当于jsp标签往助手类中传值的概念) -->
      <my-button m="荒 " @click='nb'></my-button>
    </div>
  </body>
  <script>
    // 定义全局组件的方式
    Vue.component('my-button', {
        props: ['m'],
        template: '<button v-on:click="doClickMyButton">我是一个自定义组件,被{{m}}点了{{n}}次</button>',
        data: function() {
          return {
            n: 0
          };
        },
        methods: {
          doClickMyButton: function() {
            console.log('doClickMyButton方法被调用');
            this.n++;
            this.$emit('click', this.n, '荒', '石昊');
          }
        }
      }),
      new Vue({
        el: "#app",
        data() {
          return {
            msg: '自定义组件'
          };
        },
        methods: {
          nb: function(a, b, c) {
            console.log('方法被调用');
            console.log(a, b, c);
          }
        }
      });
  </script>
</html>

目录
相关文章
|
1天前
|
JavaScript 前端开发
Vue,如何引入样式文件
Vue,如何引入样式文件
|
1天前
|
JavaScript
|
1天前
|
JavaScript
vue滚动到页面底部时加载
vue滚动到页面底部时加载
5 1
|
1天前
|
JavaScript
|
1天前
|
JavaScript
Vue搭配ELEMENT之后,右侧点击栏点击跳转到空白页解决方法
Vue搭配ELEMENT之后,右侧点击栏点击跳转到空白页解决方法
|
JavaScript UED 前端开发
Vue1.0常用语法
var vm = new Vue({   el: "选择器", 挂载到页面的那个元素里,即确定vue的作用范围 外部可通过vm.$el访问,得到的是一个原生dom元素,可进行对应操作   a: '', //自定义属性 外部可通过vm.$options访问   data: {
3536 0
|
1天前
|
JavaScript 前端开发 API
|
1天前
|
JavaScript 前端开发 网络架构
Vue如何实现页面跳转路由,实现单页面跳转
Vue如何实现页面跳转路由,实现单页面跳转
|
1天前
|
JavaScript
Vue搭配ELEMENT组件,路由不能正确跳转bug
Vue搭配ELEMENT组件,路由不能正确跳转bug
Vue搭配ELEMENT组件,路由不能正确跳转bug
|
1天前
|
JavaScript
vue : 无法将“vue”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保 路径正确,然后再试一次。
vue : 无法将“vue”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保 路径正确,然后再试一次。