这是我参与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配置起步(一)
- Vue事件绑定(二)
- Vue渲染指令(三)
- Vue动画过渡(四)
- Vue - Todo案例(五)
- Vue表单数据绑定、Ref(六)
- Vue组件
- Vue插槽&过滤器
- Vue的反向传值 ($emit事件)