封装的组件(SelectDefault.vue文件):
<template>
<div class="select-default">
<label>{{title}}</label>
<div class="textwarm">
<input type="text"
@click="showPicker"
v-model="inputText"
>
<span class="iconfont"></span>
</div>
<!--v-model属性用来控制是vant–> Popup弹出层是否显示-->
<van-popup v-model="isShow" position="bottom" :overlay="true">
<van-picker
show-toolbar
:title="title"
:columns="columns"
@cancel="onCancel"
@confirm="onConfirm"
/>
</van-popup>
</div>
</template>
<script>
import { Picker,Popup } from ‘vant‘;
export default {
name: "SelectDefault",
components: {
[Picker.name]:Picker,
[Popup.name]:Popup
},
data() {
return {
// columns: [‘杭州‘, ‘宁波‘, ‘温州‘, ‘嘉兴‘, ‘湖州‘],
isShow: false,
//设置输入框默认值
inputText: this.dataArr[0].name
}
},
props: {
value: {
type: String, //属性的类型
// required: false, //// true 必须传 false 不是必须传递的
default: ‘1‘// 默认值
},
title: {
type: String
},
//选择器展示的数据
dataArr: {
type: Array,
required: true
}
},
//转换为选择器想要的columns数据格式
computed: {
columns: function () {
let listArr = [];
this.dataArr.forEach((item, index)=>{
// console.log(item, index);
listArr.push(item.name);
});
// console.log(listArr);
return listArr;
}
},
methods: {
//显示选择器
showPicker(){
this.isShow = true;
},
//选择器确定
onConfirm(value, index) {
console.log(`当前值:${value}, 当前索引:${index}`);
//隐藏选择器
this.isShow = false;
//改变输入框的值
this.inputText = value;
//传给使用此组件上的v-model
let userID = this.dataArr[index].user_id.toString();
this.$emit(‘input‘, userID);
},
//选择器取消
onCancel() {
console.log(‘取消‘);
this.isShow = false;
}
},
created(){
//设置默认值
let userID = this.dataArr[0].user_id.toString();
this.$emit(‘input‘, userID);
}
}
</script>
<style scoped lang="stylus">
.select-default
display:flex;
justify-content:space-around;
align-items: center;
padding:15px 0;
>.textwarm
position: relative;
span
position: absolute;
top:50%;
right:19px;
font-size:12PX;
color:#d8d8d8;
transform: translateY(-50%);
label
width:150px;
font-size:28px;
color:rgba(26,26,26,1);
line-height:40px;
font-weight:400;
input
width:514px;
padding: 24px 22px;
font-size:30px;
color:rgba(26,26,26,1);
font-weight:400;
border-radius:10px;
border:1PX solid rgba(204,204,204,1);
box-sizing: border-box;
.picker
position fixed
left 0
bottom 0
width 100vw
background-color: red
z-index 222
</style>
在其他.vue文件中使用:
<template>
<div class="add-admin-user">
<p class="p-row1">
<span>用户名</span>
<span>{{userName}}</span>
</p>
<p class="p-row2">
<inputs v-model="name"><label slot="label-name">真实姓名</label></inputs>
</p>
<p class="p-row3">
<span>所属部门:</span>
<span>
<select v-model="department">
<option v-for="item, index in departmentArr" :value ="item.id">{{ item.name }}</option>
</select>
</span>
</p>
<p class="p-row4">
<span>职位:</span>
<span>
<select v-model="role">
<option v-for="item, index in roleArr" :value ="item.id" >{{ item.role_name }}</option>
</select>
</span>
</p>
<p class="p-row5">
<inputs v-model="mobile"><label slot="label-name">联系手机号</label></inputs>
</p>
<p class="p-row6">
<inputs v-model="wechat"><label slot="label-name">微信</label></inputs>
</p>
<p class="p-row7">
<inputs v-model="email"><label slot="label-name">邮箱</label></inputs>
</p>
<<--本例演示关键代码-->>
<p class="test">
<SelectDefault v-model="test" title="所属部门" :data-arr="departmentArr"></SelectDefault>
</p>
<<--本例演示关键代码END-->>
<div class="btn-group">
<span class="cancel-btn" @click="handleCancel">取消</span>
<span class="confirm-btn" @click="handleConfirm">确定</span>
</div>
</div>
</template>
<script>
import Api from "@/api/modules/adminUser"
import Input from "../components/basic/Input.vue"
/*<<--本例演示关键代码-->>*/
import SelectDefault from "../components/basic/SelectDefault"
/*<<--本例演示关键代码END-->>*/
export default {
name: "AddAdminUser",
components:{
inputs:Input,
selects:Select,
SelectDefault:SelectDefault ///*<<--本例演示关键代码-->>*/
},
data(){
return{
userName: "",
// /*<<--本例演示关键代码-->>*/
departmentArr: [
{user_id: 1, name: "老板"},
{user_id: 2, name: "秘书"},
{user_id: 3, name: "老板娘"},
{user_id: 4, name: "会计"},
{user_id: 5, name: "模特"}
],
// departmentArr: [],
/*<<--本例演示关键代码END-->>*/
roleArr: [],
//以下用户输入信息
name: "",
department: "1",
role: "1" ,
mobile: "",
wechat: "",
email: "",
test: ""
}
},
watch: {
test: function (val, oldVal) {
console.log(val);
}
},
methods: {
//初始化页面数据
initView(){
Api.getUserName().then((res)=>{
// console.log(res);
this.userName = res.data.user_name;
});
Api.departmentListAll().then((res)=>{
// console.log(res);
this.departmentArr = res.data.list;
});
Api.roleListAll().then((res)=>{
// console.log(res);
this.roleArr = res.data;
})
},
//确定
handleConfirm(){
//验证表单
let self = this;
if(!/^1(3|4|5|7|8)\d{9}$/.test(self.mobile)){
console.log(‘手机号格式不正确‘);
return;
}
if(!/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(self.email)){
console.log(‘Email格式不正确‘);
return;
}
// 发送请求
let param = {
username: this.userName.toString(),
name: this.name,
department_id: this.department,
role_id: this.role,
contact_mobile: this.mobile,
wechat: this.wechat,
email: this.email,
};
console.log(param);
Api.addAdminUser(param).then((res)=>{
console.log(res);
// alert(res.msg);
});
},
// 取消
handleCancel(){
console.log(22);
this.$router.go(-1);
}
},
created(){
// this.initView();
}
}
</script>
<style scoped lang="stylus">
p,div
box-sizing border-box
.add-admin-user
font-family:PingFangSC-Regular;
width 100vw
height 100vh
position relative
font-size 32px
text-align center
p
padding 0 30px
height 90px
.self-input label
text-align left
.p-row1
display flex
span
line-height 90px
span:nth-child(1)
font-size:28px;
font-weight:400;
color:rgba(26,26,26,1);
width 181px
text-align left
text-indent 5px
span:nth-child(2)
font-size:30px;
font-weight:400;
color:rgba(153,153,153,1);
flex 1
text-align left
select
width 300px
.btn-group
position absolute
display flex
left 0
bottom 0
height 80px
width 100%
background-color gray
span
flex 1
</style>
上面实例的效果:

再附上一个solt插槽的简单实用。v-model在组件上使用时,子组件要写的代码。通过@$emit(input,"要传给v-model的值");给组件上的v-model

原文:https://www.cnblogs.com/taohuaya/p/10306808.html