Vue表单数据绑定、Ref(六)

4,444 阅读3分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

前言

今天我们来看看数据绑定Ref,开发的时候数据绑定所谓是几乎到处都有它的身影呀!ref 被用来给元素或子组件注册引用信息!直接整起!

表单数据绑定

介绍

在开发中我们经常需要创建一些表单元素,表单元素的内容由vue实例中的data控制。而用户在表单上的输入操作由可以修改实例中的数据。上面行为我们称之为表单的双向绑定。

例子: 下面的代码就是input实现表单双向绑定的例子

<div id="app">
        <input v-bind:value="str" @input="inputHandel">
        {{str}}
</div>

<script>
        new Vue({
            el: "#app",
            data: {
                str: 'hello world'
            },
            methods: {
                inputHandel(evt) {
                    this.str = evt.target.value 
                }
            }
        })
</script>

Vue为了简化表单元素的数据绑定, input select textarea 这些值绑定全部统一使用value属性 但是单复选框依然是checked属性

<div id=app>    
    <input v-bind:value="str" @input="inputHandel">
    {{str}}
    <textarea :value="str"></textarea>
    <select :value="city">
        <option value="bj">北京</option>
        <option value="sh">上海</option>
        <option value="gz">广州</option>
        <option value="sz">深圳</option>
    </select>
    
    <input type="checkbox" :checked="true">
</div>

<script>
        new Vue({
            el: "#app",
            data: {
                str: 'hello world',
                city: 'sz'
            },
            methods: {
                inputHandel(evt) {
                    this.str = evt.target.value 
                }
            }
        })
</script>

虽然Vue帮我们简化了表单元素值得绑定,但是在不同表单元素之间依然有一些差距的。因为这些差异要实现表单双向绑定,要根据不同的表单元素绑定不同的属性与方法。这时Vue为了帮我们解决表单的差异,提供了一个v-model的指令,v-model本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

语法: v-model="data属性"

<div id="app">

    <input v-model="str">
    {{str}}
    <textarea v-model="str"></textarea>
    <p>{{city}}</p>
    <select v-model="city">
        <option value="bj">北京</option>
        <option value="sh">上海</option>
        <option value="gz">广州</option>
        <option value="sz">深圳</option>
    </select>
    <p>{{agree? '同意' : '不同意'}}</p>
    <input type="checkbox" v-model="agree">
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            str: 'hello world',
            city: 'sz',
            agree: false
        }
    })
</script>

注意: v-model 绑定支持复选表单元素时,v-model绑定的数据请使用数组类型

// 选择器当设置了可复选属性时,会自动将v-model中的数据转化为数组
 <select v-model="city" multiple>
            <option value="" disabled>请选择你所在的城市</option>
            <option value="bj">北京</option>
            <option value="sh">上海</option>
            <option value="gz">广州</option>
            <option value="sz">深圳</option>
 </select>
 
 // 复选框要实现复选时,必须将v-model中的数据设置为数组
 <p>爱好{{hobbys}}</p> []
<label>
     抽烟
     <input type="checkbox" value="抽烟" v-model="hobbys">
 </label>
<label>
    喝酒
    <input type="checkbox" value="喝酒" v-model="hobbys">
</label>
<label>
    烫头
    <input type="checkbox" value="烫头" v-model="hobbys">
</label>
<label>
    玩摇滚
    <input type="checkbox" value="玩摇滚" v-model="hobbys">
</label>

修饰符

.lazy

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

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">

.number

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

<input v-model.number="age" type="number">

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

.trim

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

<input v-model.trim="msg">

Ref

介绍

Vue给组件元素提供了一个ref属性,绑定了ref属性的组件元素可以在当前vue实例对象中通过$refs访问其真实DOM节点(标签元素)或实例对象(组件)。

在原生html标签中使用ref

语法: <div ref="变量名"></div> 当前组件内部 this.$refs.变量名 访问其真实DOM节点

 <div id="app">
        <audio ref="myAudio" src="./药水歌.mp3" controls></audio>
        <button @click="showAudio">show</button>
 </div>   
 
<script>
 new Vue({
     el: '#app',
     methods: {
         showAudio() {
             console.log(this.$refs.myAudio)
         }           
    }
})
</script> 

在组件中中使用ref

语法: <MyComponent ref="变量名" /> 当前组件内部 this.$refs.变量名 访问这个子组件的实例对象,可以获取这个组件实例的属性和方法(尽量避免使用该模式,因为他会增加组件间的耦合性)

<Demo ref="myDemo" />
<script>
import Demo from './components/Demo'

export default {
  name: 'App',

  methods: {
    show() {
      // 子组件Demo的方法在父组件中被调用了
      this.$refs.myDemo.sayHello()
    }
  },
  components: {
    Demo
  }
}
</script>

注意

1. vue实例中每个标签或组件都可以设置ref属性,绑定了ref属性的元素可以有任意个

<div id="app">
        <audio ref="myAudio" src="./药水歌.mp3" controls></audio>
        <button ref="myBtn" @click="showAudio">show</button>
        <p ref="textEl">text</p>
</div>  
// 这时可以在组件中通过 this.$refs不同的变量名访问对应的DOM元素 

2. ref配合列表渲染(v-for)使用时,$refs返回值为包含列表渲染出来的所有元素的一个数组

<div id="app">
   // 与v-for同级的ref 返回值都是列表渲染出来当前元素数组集合
    <p v-for="num in arr" :key="num" ref="numList">
    //v-for 内部的ref 返回值也是列表渲染出来当前元素数组集合
        <span ref="spanList">{{num}}-span</span>
        <a>没用的a</a>
        {{num}}
    </p>
    <button @click="showRefList">click</button>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            arr: [1, 2, 3, 4, 5]
        },
        methods: {
            showRefList() {
                // [p,p,p,p,p]
                console.log(this.$refs.numList,
                 this.$refs.spanList)
                 //[span,span,span,span,span]  
            }
        }
    })
</script>

结尾

今天就先到这里啦!我们下期再见!码字不易,觉得不错的可以动动小指头点点赞啥的哟~

系列文章

Vue系列

Vue-Router系列

Vuex系列