问题描述
在我们的印象中,v-model的用法好像就是绑定一个data中的数据(比如输入框)。比如下面的常见用法:
<el-input v-model="input" placeholder="请输入内容"></el-input>
<script>
export default {
data() {
return {
input: ''
}
}
}
</script>
这样就会给我们造成一个错觉,好像v-model就是绑定一个数据字符串。其实v-model不仅可以绑定字符串,还可以结合v-for绑定数组。如下面的用法:
<template>
<div id="app">
<!-- 这里v-model动态绑定inputArr下的value -->
<el-input
v-model="item.value"
placeholder="请输入内容"
v-for="(item,index) in inputArr"
:key="index"
></el-input>
</div>
</template>
<script>
export default {
data() {
return {
inputArr:[
{
value:"",
},
{
value:"",
},
{
value:"",
},
]
};
},
};
</script>
结合vue的调试工具看一下数据双向绑定的效果图:
需求如下
下图中的这个效果图,就用到了v-model绑定数组的用法。
需求分析
有一个表单,作品项中默认有两个输入框,当点击增加作品按钮时,可以新增输入框。新增输入框的左边有一个可以删除的小图标(也就是从第三个输入框开始),点击删除小图标,就可以把对应的输入框删除掉。当然表单中的输入框都是必填项。没填写就做一个提示吧。
思路分析
首先是要放一个el-form的结构。下面的作品项el-form-item中的el-input通过v-for循环bookArr同时v-model绑定数组中的每一项的value。至于删除小图标,也一并写好,只不过第一个和第二个输入框不显示,也就是v-show判断一下,当index为0或者为1的时候隐藏。当点击增加作品时,往bookArr中输增加一项,当点击删除小图标时,根据删除的哪一项的索引,通过splice方法从第i个位置,删除1项。当然点击确认的时候要看看输入框内容是否为空,为空就提示一下,要是输入框全部都填写了,就可以使用输入框的参数作为参数发请求发给后台了了。
代码步骤
html部分
<template>
<div id="app">
<div class="content">
<div class="contentHeader">
<span>新增作家信息</span>
<i class="el-icon-close"></i>
</div>
<div class="contentBody">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="名字:">
<el-input
v-model.trim="form.name"
placeholder="请输入作家姓名"
></el-input>
</el-form-item>
<el-form-item label="作品:">
<!-- 这个div里面的是细节重点 -->
<div class="itemitem" v-for="(item, index) in bookArr" :key="index">
<!-- 删除小图标 -->
<i
v-show="show(index)"
@click="deleteItem(index)"
class="el-icon-remove-outline dingwei"
></i>
<!-- 输入框v-model绑定数组 -->
<el-input
v-model.trim="item.value"
placeholder="请输入作家著作"
></el-input>
</div>
<el-button type="text" size="small" @click="addBook"
>+增加作品</el-button
>
</el-form-item>
</el-form>
</div>
<div class="contentFooter">
<el-button size="small">取消</el-button>
<el-button size="small" type="primary" @click="getFormValue">确认</el-button>
</div>
</div>
</div>
</template>
js部分
<script>
export default {
data() {
return {
form: {
name: "",
},
bookArr: [
{
value: "",
},
{
value: "",
},
],
};
},
methods: {
// 添加一项
addBook() {
this.bookArr.push({ value: "" });
},
// 从第三项开始才展示
show(i){
if(i==0 | i==1){
return false
}else{
return true
}
},
// 根据索引删除对应哪一项
deleteItem(i){
this.bookArr.splice(i,1)
},
// 点击确认按钮
getFormValue(){
if(this.form.name == ""){
this.$message.error('作家名字为必填项');
return
}
// 这里也可以用数组的every方法做判断
let num = 0
this.bookArr.forEach((item)=>{
if(item.value == ""){
num = num + 0
}else{
num = num + 1
}
})
// 当num等于this.bookArr.length的时候,说明都填写了
if(num == this.bookArr.length){
this.form.bookArr = this.bookArr
console.log("发请求",this.form);
}else{
this.$message.error('作家作品需全部填写');
}
}
},
};
</script>
css部分
<style lang="less" scoped>
#app {
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.3);
display: flex;
justify-content: center;
align-items: center;
.content {
width: 480px;
height: 360px;
background-color: #fff;
border-radius: 5px;
.contentHeader {
width: 100%;
height: 50px;
border-bottom: 1px solid #e9e9e9;
box-sizing: border-box;
padding: 0 25px;
display: flex;
justify-content: space-between;
align-items: center;
span {
font-size: 20px;
}
i {
font-size: 25px;
cursor: pointer;
}
}
.contentBody {
overflow-y: auto;
width: 100%;
height: calc(100% - 100px);
display: flex;
justify-content: center;
padding-top: 20px;
box-sizing: border-box;
padding-right: 25px;
// align-items: center;
.el-form {
.itemitem {
display: flex;
align-items: center;
position: relative;
.dingwei {
position: absolute;
left: -30px;
top: 12px;
}
i {
font-size: 20px;
margin-right: 6px;
}
.el-input {
margin-bottom: 8px;
width: 206px;
}
}
}
}
.contentFooter {
width: 100%;
height: 50px;
line-height: 50px;
border-top: 1px solid #e9e9e9;
text-align: center;
}
}
}
</style>
总结
好记性不如烂笔头,记录一下吧。如果本篇文章的思路帮助到您了,欢迎各位看官大佬们赏赐个赞吧。手动比心
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。