v-model

497 阅读1分钟

基础概念

Vue中使用v-model指令来实现表单元和数据的双向绑定

基本使用

最重要的特征**实现表单元素和数据的双向绑定

<body>
  <div id="app">
    <input type="text" v-model="message">
    {{message}}
  </div> 
  
<script src="../vue.js"></script>
<script>
  var app = new Vue({
    el:'#app',
    data:{
      message:"hello world"
    }
  })
</script>
</body>

v-model原理

  1. 实现双向绑定的原理相当于两个指令的集合。分别是v-on和v-bind
  2. v-model是一个语法糖,它本质上包含两个操作 (1)v-bind绑定一个value属性 (2)v-on指令给当前元素绑定input事件

使用v-bind

只使用v-bind(只能实现数据响应,视图不影响数据)

v-bind和v-on同时使用

(1)当输入框输入内容时,因为input中的v-model绑定message,所以会实时将输入内容传递给message,message发生改变 (2)message发生改变时,因为使用了Mustache语法,于是将message的值插到DOM中,DOM发生响应的改变

<body>
  <div id="app">
    //<!-- @input监听用户输入-->
    <input type="text" :value="message" @input="change"> 
    <input type="text" :value="message" @input="message =  $event.target.value">
  </div> 

<script src="../vue.js"></script>
<script>
  var app = new Vue({
    el:'#app',
    data:{
      message:"hello world"
    },
    methods:{
    //事件对象
      change(event) {
        this.message = event.target.value;
      }
    }
  })
</script>
</body>

结合表单元素使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 
        v-model 称之为 数据双向绑定,大多数情况下用于表单元素
        数据会影响视图
        input:text 影响它的value
        textarea 影响它的innerText
        input:checkbox 影响它的checked
            根据布尔值的真假来决定,checked选中与否
        input:radio  影响它的checked
            根据数据和 radio的 value 做对比
        select 影响它的selected
            数据与 option的value做比对

        视图也影响数据
     -->
</head>
<body> 
    <div id="app">
        <h1>表单输入绑定</h1>
        <h2>文本框</h2>
        <!-- <input type="text" :value='user.name'> -->
        <input type="text" v-model='user.name'>
        <p>{{ user.name }}</p>

        <h2>多行文本框</h2>
        <textarea  cols="30" rows="10" v-model='user.bio'></textarea>
        <p>{{ user.bio }}</p>

        <h2>复选框</h2>
        <input type="checkbox" v-model='user.isSuccess'>
        <p>{{ user.isSuccess }}</p>

        <h2>单选按钮</h2>
        <input type="radio" value="0" v-model='user.gender'>女
        <input type="radio" value="1" v-model='user.gender'>男
        <p>{{ user.gender }}</p>

        <select v-model='user.city'>
            <option value="sh">上海</option>
            <option value="bj">北京</option>
            <option value="sz">深圳</option>
            <option value="tj">天津</option>
        </select>
        <p>{{ user.city }}</p>

        <h2>如果不想让视图影响数据,使用 v-bind 绑定</h2>
        <input type="text" :value='user.name'>
        <h2>如果只想绑定一次,之后不受数据影响,使用 v-once 绑定</h2>
        <input type="text" v-once  :value='user.name'>
        <p v-once>{{ user.name }}</p>
    </div>
    <script src="js/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data:{
                message:'Hello vue.js!',
                user:{
                    name:'张三',
                    age:12,
                    gender:1,
                    isSuccess:true,
                    bio:'求佛',
                    city:'bj'
                },
            },
            methods:{}
        });
    </script>
</body>
</html>

v-model修饰符

lazy修饰符

  1. 默认情况下,v-model默认是在input事件中同步输入框的数据,即一旦有数据发生改变时,对应的data中的数据就会自动发生改变
  2. lazy修饰符可以让数据在失去焦点或者回车时才会更新

number修饰符

  1. 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理
  2. 如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理
  3. number修饰符可以让在输入框中输入的内容自动转成数字类型

trim修饰符

  1. 如果输入的内容首尾有很多空格,通常我们希望将其去除
  2. trim修饰符可以过滤内容左右两边的空格

在组件中使用

核心点: 1.父组件啥也不用干只需要绑定v-model值 2.子组件接收绑定的props属性必须为value 3.子组件data中必须定义一个属性接收value的值 4.子组件watch监听value的值同步给定义的属性 5.子组件watch监听定义属性的值通过$emit('input')同步给父组件

父组件

<template>
	<div>
		<p>父组件当前的值:{{num}}</p>
	    <button @click="btnClick">减少</button> 
	    <child v-modal="num" />
	</div>
</template>

<script>
import Child from './child.vue';
export default {
	name: 'parent',
	components: {
		Child 
	},
    data() {
        return { num: 0 };
    },
    methods: {
        btnClick() {
            this.num--;
        },
    },
};
</script>


子组件

<template>
	<div>
		<p>子组件当前的值:{{num}}</p>
    	<button @click="btnClick">增加</button> 
    </div>
</template>

<script>
export default {
	name: 'child',
    props: {
        value: Number,
    },
    data() {
        return { num: 0 };
    },
    watch: {
        value(val) {
            this.num = val;
        },
        num(num) {
            this.$emit('input', num);
        },
    },
    methods: {
        btnClick() {
            this.num++;
        },
    },
};
</script>