Vue表单与v-model

表单输入绑定

基础用法

你可以用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。

提示

v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将当前活动实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

text 和 textarea 元素使用 value propertyinput 事件;
checkbox 和 radio 使用 checked propertychange 事件;
select 字段将 value 作为 prop 并将 change 作为事件。

提示

对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model 不会在输入法组织文字过程中得到更新。如果你也想响应这些更新,请使用 input 事件监听器和 value 绑定,而不是使用 v-model。

文本 (Text)

<template>
  <div id="app">
    <input v-model="message" placeholder="edit me" />
    <p>Message is: {{ message }}</p>
    <button @click="message = 'jingxi'">set message to jingxi</button>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  data() {
    return {
      message: "su",
    };
  },
  components: {},
};
</script>
复制代码

image.png

多行文本 (Textarea)

<template>
  <div id="app">
    <textarea v-model="message" placeholder="edit me" />
    <p>Message is: {{ message }}</p>
    <button @click="message = 'jingxi'">set message to jingxi</button>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  data() {
    return {
      message: "su",
    };
  },
  components: {},
};
</script>
复制代码

image.png

在文本区域插值不起作用,应该使用 v-model 来代替。

<!-- bad -->
<textarea>{{ text }}</textarea>

<!-- good -->
<textarea v-model="text"></textarea>
复制代码

复选框 (Checkbox)

单个复选框,绑定到布尔值:

<template>
  <div id="app">
    <label>
      <input type="checkbox" v-model="x" />
      <span>抽烟:{{x}}</span>
    </label>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";
12;
export default {
  name: "App",
  data() {
    return {
      x: true,
    };
  },
  components: {},
};
</script>
复制代码

多个复选框,绑定到同一个数组:

<template>
  <div id="app">
    爱好:{{x}}
    <label>
      <input type="checkbox" v-model="x" value="抽烟" />
      <span>抽烟</span>
    </label>
    <label>
      <input type="checkbox" v-model="x" :value="2"/>
      <span>喝酒</span>
    </label>
    <label>
      <input type="checkbox" v-model="x" value="3"/>
      <span>烫头</span>
    </label>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";
12;
export default {
  name: "App",
  data() {
    return {
      x: [],
    };
  },
  components: {},
};
</script>
复制代码

image.png

单选框 (Radio)

<template>
  <div id="app">
    爱好:{{x}}
    <label>
      <input name="want(可以不加name)" type="radio" v-model="x" value="抽烟" />
      <span>抽烟</span>
    </label>
    <label>
      <input name="want(可以不加name)" type="radio" v-model="x" value="喝酒"/>
      <span>喝酒</span>
    </label>
    <label>
      <input name="want(可以不加name)" type="radio" v-model="x" value="烫头"/>
      <span>烫头</span>
    </label>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";
12;
export default {
  name: "App",
  data() {
    return {
      x: '',
    };
  },
  components: {},
};
</script>
复制代码

image.png

选择框 (Select)

单选时

<template>
  <div id="app">
    你想要:{{ x }}
    <select v-model="x">
      <option value="">Please select one</option>
      <option v-for="item in array" :value="item.value" :key="item.value">
        {{ item.text }}
      </option>
    </select>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      array: [
        { text: "抽烟", value: 1 },
        { text: "喝酒", value: 2 },
        { text: "烫头", value: 3 },
      ],
      x: "",
    };
  },
  components: {},
};
</script>
复制代码

注意

如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像<option disabled value="">Please select one</option>这样提供一个值为空的禁用选项。

多选时 (绑定到一个数组,用的少):

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
<br />
<span>Selected: {{ selected }}</span>
复制代码

form(表单)

<template>
  <div id="app">
    登录
    <form @submit.prevent="onSubmit">
      <label>
        <span>用户名</span>
        <input type="text" v-model="user.username" />
      </label>
      <label>
        <span>密码</span>
        <input type="password" v-model="user.password" />
      </label>
      <button type="submit">登录</button>
    </form>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      user: {
        username: "",
        password: "",
      },
      x: "",
    };
  },
  methods: {
    onSubmit() {
      console.log(this.user);
    },
  },
  components: {},
};
</script>
复制代码

修饰符

.lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组织文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" />
复制代码
  • input事件,键盘、鼠标、任何输入设备的输入
  • change事件,只在input失去焦点时触发

.number

如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

<input v-model.number="age" type="number" />
复制代码

这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

.trim

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

<input v-model.trim="msg" />
复制代码

v-model

v-model本质上是一个语法糖。如下代码<input v-model="test">本质上是<input :value="test" @input="test = $event.target.value">,其中@input是对<input>输入事件的一个监听:value="test"是将监听事件中的数据放入到input。在这边需要强调一点,v-model不仅可以给input赋值还可以获取input中的数据,而且数据的获取是实时的,因为语法糖中是用@input对输入框进行监听的。

本质:

<input type="text" v-model="user.username" />

<input type="text" :value="user.username" @input="user.username=$event.target.value" />
复制代码

总结

面试问如何实现Vue 的双向绑定,就说v-model的用法。

  • 双向绑定
    • v-model可以实现绑定一个数据,在这个数据变化的时候,UI会变化。
    • 在用户改变UI的时候,数据也会变化。
  • 深入
    • v-modelv-bind:valuev-on:input的语法糖。v-on:input="xxx=$event.target.value"

ant-design-vue

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享