# 事件和表单

# 事件处理

# 监听事件

可以用 v-on 指令来监听 DOM 事件,简写为@

# 事件处理方法

直接把 JavaScript 代码写在 v-on 指令中是不可行的,我们需要接收一个方法来进行调用

# 内联处理器中的方法

除了绑定方法外,可以直接加上括号来调用方法,有事需要在内联语句处理器中访问原始的 DOM 事件对象。可以用特殊变量$event将其传入方法中。

<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
// ...
methods: {
  warn: function (message, event) {
    // 现在我们可以访问原生事件对象
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

# 事件修饰符

在事件处理程序中调用 event.preventDefault()或 event.stopPropagation()是非常常见的需求,虽然可以在方法中轻松事件这点,但显然不够优雅。Vue.js 为 v-on 提供了事件修饰符

.stop 阻止事件继续传播
.prevent 阻止事件默认行为,比如 submit 的页面重载
.capture 设置为事件捕获模式
.self 只在当前元素自身触发
.once 只触发一次
.passive 立即触发默认行为

修饰符可以串联使用,但是顺序很重要,比如用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

# 按键修饰符

可以直接将 KeyboardEvent.key (opens new window) 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。

此时可以在全局设置一个别名对应键盘上的按键,比如

Vue.config.keyCodes.a = 65;

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名

.enter .tab
.delete .esc
.space .up
.down .left
.right

系统修饰键,通过系统修饰键来达到组合按键触发事件的效果

.ctrl .alt
.shift .meta
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear" />

<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>

.exact 修饰符允许你控制有精切的系统修饰符组合触发的事件(2.5.0 新增)

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button v-on:click.ctrl="onClick">A</button>

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

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">A</button>

鼠标按钮修饰符

.left .right
.middle

# 表单双向绑定

# 基础用法

​ 可以用v-model指令在表单上创建双向数据绑定,v-model在内部为不同的输入元素使用不同的property并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。
  1. 文本

<input v-model="message" placeholder="edit me" />
<p>Message is: {{ message }}</p>
  1. 多行文本

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines">{{这里的插值是没有用的}}</textarea>
  1. 复选框

单个复选框,一般绑定到布尔值,多个复选框,则绑定到同一个数组

  1. 单选按钮

<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked" />
  <label for="one">One</label>
  <br />
  <input type="radio" id="two" value="Two" v-model="picked" />
  <label for="two">Two</label>
  <br />
  <span>Picked: {{ picked }}</span>
</div>
  1. 选择框

写在 select 标签中,获取 option 中的内容或者标签中的 value 值,value 值优先,多选时同样绑定到一个数组

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>

# 值绑定

<!-- 当选中时,`picked` 为字符串 "a" -->
<input type="radio" v-model="picked" value="a" />

<!-- `toggle` 为 true 或 false -->
<input type="checkbox" v-model="toggle" />

<!-- 当选中第一个选项时,`selected` 为字符串 "abc" -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>

<!-- 多选按钮true-value/false-value-->
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
// 当选中时 vm.toggle === 'yes' // 当没有选中时 vm.toggle === 'no'

<!-- 单选按钮value-->
<input type="radio" v-model="pick" v-bind:value="a" />
// 当选中时 vm.pick === vm.a

<!-- 选择框value-->
<select v-model="selected">
  <!-- 内联对象字面量 -->
  <option v-bind:value="{ number: 123 }">123</option>
</select>

# 修饰符

  1. .lazy 在默认情况下,v-model 会在每次 input 事件触发后更新数据,添加 lazy 修饰符后,则转为在 change 事件之后进行同步数据
  2. .number,自动将用户的输入值转为数值类型
  3. .trim,自动过滤用户输入的首位空白字符

# 在组件上使用 v-model

可以自定义输入组件

<script>
export default {
  model: {
    props: "",
    event: ""
  }
};
</script>