vue实现弹出框
说明:点击查询弹出模态,单击表格选中,点击模态外取消模态显示效果。
如图:
1.Template
<!-- 模态 - 选择人员 -->
<div class="model" v-show="isShowMultiple" @click="setMaskShow($event)">
<div class="modelFixed" ref="child">
此处为内容区
</div>
</div>
2.script => data 中定义
isShowMultiple: false
3.script => methods 中定义关闭方法
setMaskShow(e) {
if (!this.$refs.child.contains(e.target)) {
this.isShowMultiple = false;
}
},
4.样式
.model {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
.modelFixed {
position: absolute;
top: 120px;
left: 10px;
padding: 5px;
background: #ffffff;
box-shadow: 3px 2px 5px #7777;
}
vue实现弹窗选择
1.创建一个ImproveResume.vue
<template>
<div class="release-post">
<div class="header">
<img
class="header_left"
src="./images/left_header.png"
alt=""
@click="clickGoBack"
/>
<p class="header_title">完善简历</p>
</div>
<div class="resume_main">
<div class="resume_content">
<van-form>
<div class="table_list">
<p class="name_title">期望薪资</p>
<van-field
class="calendar"
v-model="onlineForm.salary"
:value="onlineForm.salary"
placeholder="请选择"
@click="clickPicker(1)"
:class="{ borderStyle: salaryChange }"
:disabled="true"
/>
</div>
<div class="table_list">
<p class="name_title">最高学历</p>
<van-field
:style="{ color: '#323233' }"
class="calendar"
v-model="onlineForm.education"
:value="onlineForm.education"
placeholder="请选择"
@click="clickPicker(2)"
:class="{ borderStyle: educationChange }"
:disabled="true"
/>
</div>
<div class="table_list">
<p class="name_title">工作年限</p>
<van-field
class="calendar"
v-model="onlineForm.workYears"
:value="onlineForm.workYears"
placeholder="请选择"
@click="clickPicker(3)"
:class="{ borderStyle: workYearsChange }"
:disabled="true"
/>
</div>
</van-form>
<!-- 薪资范围 -->
<van-popup v-model="showPickerPopup" position="bottom" round>
<div>
<div class="resume_picker">
<div
@click.stop="clickPicker(1)"
:class="selectIndex == 1 ? 'select_title' : 'not_title'"
>
<p :class="selectIndex == 1 ? 'select_text' : 'not_text'">
期望薪资
</p>
<p :class="selectIndex == 1 ? 'select_data' : 'not_data'">
{{ onlineForm.salary ? onlineForm.salary : "请选择" }}
</p>
</div>
<div
@click.stop="clickPicker(2)"
:class="selectIndex == 2 ? 'select_title' : 'not_title'"
>
<p :class="selectIndex == 2 ? 'select_text' : 'not_text'">
选择学历
</p>
<p :class="selectIndex == 2 ? 'select_data' : 'not_data'">
{{ onlineForm.education ? onlineForm.education : "请选择" }}
</p>
</div>
<div
@click.stop="clickPicker(3)"
:class="selectIndex == 3 ? 'select_title' : 'not_title'"
>
<p :class="selectIndex == 3 ? 'select_text' : 'not_text'">
工作年限
</p>
<p :class="selectIndex == 3 ? 'select_data' : 'not_data'">
{{ onlineForm.workYears ? onlineForm.workYears : "请选择" }}
</p>
</div>
</div>
<PickerPopup
@clickClose="clickClose"
@clickConFirm="clickConFirm"
:showPickerPopup="showPickerPopup"
:pickerTitle="pickerTitle"
:columnsData="columnsData"
:selectIndex="selectIndex"
></PickerPopup>
</div>
</van-popup>
</div>
</div>
<div>
<div class="mask">
<button
class="btn"
@click="submit"
:class="{ btnBg: colorChange() }"
v-preventReClick="1000"
>
下一步
</button>
</div>
</div>
<return-left-modal
class="modal"
:show="isShowModal"
title="温馨提示"
@hideModal="hideModal"
@submit="submitModal"
leftBtnText="取消"
rightBtnText="继续完善"
>
<p class="tips_text">完善简历,24小时好工作主动联系您</p>
</return-left-modal>
</div>
</template>
<script>
import Vue from 'vue';
import { Circle, DatetimePicker, Form, Field, Toast, Calendar, Picker, Overlay, ActionSheet, Popup, Tab, Tabs } from 'vant';
import 'vant/lib/index.less';
Vue.use(Circle).use(DatetimePicker).use(Form).use(Field).use(Calendar).use(Picker).use(Overlay).use(ActionSheet).use(Popup);
import ReturnLeftModal from '../perfectResume/ReturnLeftModal'
import { objBlurFun } from '@/utils/resize';
import request from './api'
import PickerPopup from './PickerPopup'
import Vconsole from 'vconsole'
if (process.env.NODE_ENV === "development") {
new Vconsole();
}
export default {
name: "ImproveResume",
components: {
ReturnLeftModal,
PickerPopup,
},
data () {
return {
showPickerPopup: false,//选择弹窗
pickerTitle: '',//弹窗标题
columnsData: [],//弹窗数据
isShowModal: false,
workingYears: ['应届毕业', '1-3年', '3-5年', '6-9年', '10年以上'],
educationColumns: ['不限', '初中以下', '中专/中技', '高中', '大专', '本科', '硕士', '博士'],
columnsSalary: ['面议', '1000元以下/月', '1000-2000元/月', '2000-3000元/月', '3000-5000元/月', '5000-8000元/月', '8000-12000元/月', '12000-20000元/月', '20000-25000元/月', '25000元以上/月'],
perDiem: ['面议', '10-50元/日', '50-100元/日', '100-200元/日', '200-300元/日', '300-500元/日', '500元及以上/日'],
onlineForm: {
type: 0, //0全职1兼职
salary: "",//薪资
education: "",//学历
workYears: '',
},
salaryChange: false,
educationChange: false,
workYearsChange: false,
docmHeight: window.innerHeight,
showHeight: window.innerHeight,
selectIndex: 1,
};
},
watch: {
//监听屏幕高度变化(软键盘弹出)
showHeight: function (newValue) {
if (this.docmHeight > newValue) {
this.hideshow = false
} else {
this.hideshow = true
}
}
},
mounted () {
objBlurFun('input')
objBlurFun('textarea')
document.documentElement.style.background = '#fff';
// 解决安卓软件盘弹出把底部fixed顶上去,window.onresize监听页面高度的变化
window.onresize = () => {
return (() => {
this.showHeight = window.innerHeight;
})()
}
},
methods: {
clickClose () {
console.log('取消')
this.showPickerPopup = false
},
clickConFirm (v, index) {
console.log(v, index, '点击确认')
this.columnsData = index == 1 ? this.columnsSalary : index == 2 ? this.educationColumns : index == 3 ? this.workingYears : []
this.selectIndex = index
if (index == 1) {
this.onlineForm.salary = v
this.clickPicker(index + 1)
} else if (index == 2) {
this.onlineForm.education = v
this.clickPicker(index + 1)
} else if (index == 3) {
this.onlineForm.workYears = v
this.showPickerPopup = false
}
},
clickPicker (v) {
console.log(v, '点击index')
this.showPickerPopup = true
this.pickerTitle = v == 1 ? '请选择期望薪资' : v == 2 ? "请选择最高学历" : v == 3 ? '请选择工作年限' : '请选择'
this.columnsData = v == 1 ? this.columnsSalary : v == 2 ? this.educationColumns : v == 3 ? this.workingYears : []
this.selectIndex = v
},
clickGoBack () {
this.userPhoneChange = false
this.isShowModal = true
},
hideModal () {
this.$store.commit('noScroll', true);
this.isShowModal = false
this.$store.state.entry === this.$route.path ? this.$ZhiYue.closePage() : this.$router.back();
},
submitModal () {
this.$store.commit('noScroll', false);
this.isShowModal = false
},
//下一步按钮色值
colorChange () {
if (
this.onlineForm.salary &&
this.onlineForm.education &&
this.workYears
) {
return true
}
},
// 验证
validateOnlineForm (btn) {
let valid = true;
if (!this.onlineForm.salary || !this.onlineForm.salary.trim()) {
valid = false;
this.$shq.toast('请选择期望薪资')
this.welfareChange = true
} else if (!this.onlineForm.education || !this.onlineForm.education.trim()) {
valid = false;
this.$shq.toast('请选择最高学历')
this.postAgeChange = true
} else if (!this.onlineForm.workYears || !this.onlineForm.workYears.trim()) {
valid = false;
this.$shq.toast('请选择工作年限')
this.educationnge = true
}
return valid;
},
//提交
submit () {
this.onlineForm.telephone = this.onlineForm.contact
if (this.validateOnlineForm()) {
request.saveNew(
this.onlineForm
).then(resp => {
if (resp && resp.code == 0) {
Toast.success({
message: '完善成功',
onClose: () => {
this.$store.state.entry === this.$route.path ? this.$ZhiYue.closePage() : this.$router.back();
}
})
} else {
resp.message && this.$shq.toast(resp.message);
}
}).catch(() => {
this.btnDisable = false
this.$shq.toast('操作失败,请再次尝试')
})
}
},
},
destroyed () {
this.$store.commit('noScroll', false);
},
};
</script>
<style scoped lang="less" >
* {
margin: 0;
padding: 0;
}
::v-deep .van-cell::after {
border-bottom: none !important;
}
::v-deep .van-picker__cancel {
opacity: 0;
}
.release-post {
width: 100%;
padding-bottom: 64px;
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
}
::v-deep .van-field__control:disabled {
font-size: 15px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
text-align: left;
color: #333333;
-webkit-text-fill-color: #333333;
}
.resume_main {
width: 100%;
margin-top: 64px;
padding-bottom: 74px;
}
.resume_content {
margin-left: 30px;
margin-right: 30px;
}
.mask {
width: 100%;
background: #ffffff;
box-shadow: 0px 0px 8px 0px rgba(204, 204, 204, 0.3);
position: fixed;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
padding: 10px 0;
padding-bottom: calc(env(safe-area-inset-bottom)+15px);
padding-bottom: calc(env(safe-area-inset-bottom) + 15px);
}
.btn {
font-size: 16px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 500;
text-align: left;
color: #ffffff;
margin: 0 auto;
text-align: center;
line-height: 1.6rem;
width: 100%;
margin: 0 16px;
height: 48px;
background: #d8d8d8;
}
.btnBg {
font-size: 16px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 500;
text-align: left;
color: #ffffff;
margin: 0 auto;
text-align: center;
line-height: 1.6rem;
width: 100%;
margin: 0 16px;
height: 48px;
background: #d8d8d8;
border: none;
outline: none;
background: linear-gradient(90deg, #50a3ff, #1283ff);
border-radius: 4px;
}
.name_title {
font-size: 16px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: bold;
color: #333333;
}
.calendar {
width: 100%;
height: 49px;
background: #ffffff;
border: 1px solid #e5e5e5;
border-radius: 5px;
margin-top: 10px;
padding-left: 20px;
background: url("./images/drop-down.png") no-repeat 96% center;
background-size: 10px 7px;
padding-right: 25px;
::v-deep .van-field__control {
font-size: 15px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
text-align: left;
color: #333333;
margin-top: 12px;
}
}
::v-deep input::-webkit-input-placeholder {
font-size: 15px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
text-align: left;
color: #afadad;
-webkit-text-fill-color: #afadad;
}
.table_list {
margin-top: 16px;
}
.header {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
position: fixed;
top: 0;
height: 44px;
background: #ffffff;
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
border-bottom: solid 0.5px #e5e5e5;
z-index: 99;
}
.header_left {
width: 20px;
height: 20px;
padding: 12px;
}
.header_title {
width: 100%;
margin: 0;
margin-right: 44px;
font-size: 18px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 500;
text-align: center;
color: #333333;
}
.borderStyle {
border: solid 1px #ff1d28 !important;
border-radius: 3px !important;
}
.tips_text {
font-size: 12px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
text-align: center;
color: #333333;
padding-top: 8px;
padding-bottom: 18px;
}
input::-webkit-input-placeholder {
font-size: 15px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
text-align: left;
color: #999999;
}
textarea::-webkit-input-placeholder {
font-size: 15px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
text-align: left;
color: #999999;
}
.van-field__control {
color: #333333;
}
.resume_picker {
display: flex;
justify-content: space-around;
align-items: center;
flex: 1;
}
.select_title {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 16px 0;
flex: 3;
border-top: solid 3px #1283ff;
background: linear-gradient(
180deg,
rgba(18, 131, 255, 0.08) 0%,
rgba(255, 255, 255, 0) 100%
);
}
.not_title {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 16px 0;
flex: 3;
border-top: solid 3px #ffffff;
}
.select_text {
font-size: 12px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
color: #666666;
}
.not_text {
font-size: 12px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
color: #666666;
}
.select_data {
font-size: 16px;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: bold;
color: #1283ff;
margin-top: 5px;
}
.not_data {
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: bold;
color: #c2c2c2;
margin-top: 5px;
}
</style>
2.创建PickerPopup.vue组件
<template>
<div class="release-post" v-show="showPickerPopup">
<!-- 薪资、学历、工作年限 -->
<van-picker
show-toolbar
:title="pickerTitle"
:columns="columnsData"
:default-index="2"
@cancel="clickClose"
@confirm="clickConFirm"
:style="(height = 0)"
:cancel-button-text="null"
/>
</div>
</template>
<script>
export default {
name: "PickerPopup",
props: {
showPickerPopup: {
type: Boolean,
default: false
},
pickerTitle: {
type: String,
default: '默认'
},
columnsData: {
type: Array,
default: []
},
selectIndex: {
type: Number,
default: 1
}
},
data () {
return {
oSelectIndex: 1
};
},
watch: {
selectIndex: {
handler (newVal) {
this.oSelectIndex = newVal
},
immediate: true,
},
},
methods: {
clickClose () {
this.$emit('clickClose')
},
clickConFirm (value) {
this.$emit('clickConFirm', value, this.oSelectIndex)
},
},
};
</script>
<style scoped lang="less" >
</style>
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。