封裝的組件(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

