vue如何实现简易的弹出框

 更新时间:2022年04月22日 10:03:13   作者:zqian1994  
这篇文章主要介绍了vue如何实现简易的弹出框,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅析vue3项目中自定义指令的运用

    浅析vue3项目中自定义指令的运用

    自定义指令是一种在Vue应用程序中扩展HTML标签的能力,通过自定义指令,我们可以直接在模板中使用指令名,下面我们就来看看项目中具体如何使用自定义指令的吧
    2023-08-08
  • Vue中原生template标签失效如何解决

    Vue中原生template标签失效如何解决

    这篇文章主要介绍了Vue中原生template标签失效如何解决,找了整一天也没找着这事件为什么触发不了,第二天意识到原生代码里的template可能有问题,在原生环境中template标签内部的东西是不会渲染出来的,虽然解析器在加载页面的时候确实会处理这部分代码片段
    2023-02-02
  • vue使用echarts时created里拿到的数据无法渲染的解决

    vue使用echarts时created里拿到的数据无法渲染的解决

    这篇文章主要介绍了vue使用echarts时created里拿到的数据无法渲染的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Vue 自适应高度表格的实现方法

    Vue 自适应高度表格的实现方法

    这篇文章主要介绍了Vue 自适应高度表格的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • 在Vue3中实现拖拽文件上传功能的过程详解

    在Vue3中实现拖拽文件上传功能的过程详解

    文件上传是我们在开发Web应用时经常遇到的功能之一,为了提升用户体验,我们可以利用HTML5的拖放API来实现拖拽文件上传的功能,本文将介绍如何在Vue3中实现这一功能,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2023-12-12
  • vue cli3适配所有端方案的实现

    vue cli3适配所有端方案的实现

    这篇文章主要介绍了vue cli3适配所有端方案的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 基于vue2.x的电商图片放大镜插件的使用

    基于vue2.x的电商图片放大镜插件的使用

    本篇文章主要介绍了基于vue2.x的电商图片放大镜插件的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • vue前端开发keepAlive使用详解

    vue前端开发keepAlive使用详解

    在开发中经常有从列表跳到详情页,然后返回详情页的时候需要缓存列表页的状态(比如滚动位置信息),这个时候就需要保存状态,要缓存状态
    2021-10-10
  • vue中element 的upload组件发送请求给后端操作

    vue中element 的upload组件发送请求给后端操作

    这篇文章主要介绍了vue中element 的upload组件发送请求给后端操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • uni-app自定义导航栏按钮|uniapp仿微信顶部导航条功能

    uni-app自定义导航栏按钮|uniapp仿微信顶部导航条功能

    这篇文章主要介绍了uni-app自定义导航栏按钮|uniapp仿微信顶部导航条,需要的朋友可以参考下
    2019-11-11

最新评论