vue如何实现简易的弹出框

目录
  • vue实现弹出框
    • 1.Template
    • 2.script => data 中定义
    • 3.script => methods 中定义关闭方法
    • 4.样式
  • vue实现弹窗选择
    • 1.创建一个ImproveResume.vue
    • 2.创建PickerPopup.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>

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

(0)

相关推荐

  • vue实现简单的登录弹出框

    本文实例为大家分享了vue实现简单的登录弹出框的具体代码,供大家参考,具体内容如下 初学vue框架,小小的写了一个登录弹出框效果 各路大佬多多指教. 不多废话,直接上代码: CSS: *{margin:0;padding:0;} /*登陆按钮*/ #app{ width:140px; height:36px; margin:10px auto; } #login,#login a{ width: 200px; height: 38px; line-height:38px; text-align:

  • 使用vue实现各类弹出框组件

    简单介绍一下vue中常用dialog组件的封装: 实现动态传入内容,实现取消,确认等回调函数. 首先写一个基本的弹窗样式,如上图所示. 在需要用到弹窗的地方中引入组件: import dialogBar from './dialog.vue' components:{ 'dialog-bar': dialogBar, }, <dialog-bar></dialog-bar> 点击一个按钮显示弹窗,并保证关闭弹窗后再次点击依旧显示 在弹窗组件中定义一个value值:v-model=&

  • Vue组件化开发之通用型弹出框的实现

    本文主要分享关于组件化开发的理解,让刚入门的小伙伴少走一些弯路,提高开发效率,作者本人也是新手,如有不当之处,请大佬指出,感谢. 相信很多刚入门的小伙伴,经常会写很多重复的代码,而这些代码一般情况下也都是大同小异,在这种情况下,如何让开发和学习变得更加高效,组件化的思想就显得尤为重要.这里通过设计一个简单的弹出框,给小伙伴们分享组件化的应用. 组件&组件化 组件化是对某些可以进行复用的功能进行封装的标准化工作.组件一般会内含自身的内部UI元素.样式和JS逻辑代码,它可以很方便的在应用的任何地方进

  • vue实现点击出现操作弹出框的示例

    如上图所示,这次要实现一个点击出现操作弹框的效果:并将这个功能封装成一个函数,便于在项目的多个地方使用. 具体思路是: 封装一个组件,组件保护一个插槽,我们可以根据不同的场景,利用插槽随意在这个弹框里插入任何元素,这个弹框显示时根据我鼠标的点击位置,定位弹窗的位置,并在组件里面监听鼠标抬起事件,触发事件时将弹窗隐藏: 接着在函数中利用createElement和appendChild方法将弹出框创建并插入到页面中:   本次实现基于vuecli3 接下来,具体实现: 首先,我们先写一个demo组

  • vue组件实现弹出框点击显示隐藏效果

    本文实例为大家分享了vue实现弹出框点击显示隐藏的具体代码,供大家参考,具体内容如下 效果如下图 由于我的更改密码弹出框是一个组件引用的,所以在一开始是隐藏的,这就需要在当前的页面上对弹出框组件设置v-show,但是在弹出框显示出来的时候,操作执行完后当前页面的更改按钮已经被弹出框覆盖了.所以只能在弹出页面点击取消实现关闭隐藏弹出框.这样就需要写两个点击事件,但是两个点击事件就会有冲突,需要点击两下才能使弹出框显示和隐藏.然后我就用的以下方法,希望可以帮到大家!!! 代码如下 1.在当前页面中(

  • vue如何实现简易的弹出框

    目录 vue实现弹出框 1.Template 2.script => data 中定义 3.script => methods 中定义关闭方法 4.样式 vue实现弹窗选择 1.创建一个ImproveResume.vue 2.创建PickerPopup.vue组件 vue实现弹出框 说明:点击查询弹出模态,单击表格选中,点击模态外取消模态显示效果. 如图: 1.Template  <!-- 模态 - 选择人员 -->     <div class="model&qu

  • elementUI vue this.$confirm 和el-dialog 弹出框 移动 示例demo

    调试了好久, 还能凑合用, 请直接看DOME 示例,复制就能用: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- import CSS --> <link rel="stylesheet" href="https://u

  • 详解用vue编写弹出框组件

    前言 最近研究了用vue编写弹出框的组件,发现其实这里面的门道还是有很多的.这篇文完全是用来记录总结下最近的学习成果,同时也希望能够帮得上正在学习纠结的你~ps:本文假设你已经了解vue2.0相关框架,因此适合有一定vue2.0基础的同学阅读. 设计组件的思考 其实单纯的编写一个弹出框组件并不难,写一个模板,然后用v-if或者v-show指令还控制组件的出现与消失.真正困扰我的是,这个组件的调用方式,这个问题纠结了我好久. 调研了下资料,有些人建议,直接把组件标签插进模板中,然后通过直接控制组件

  • vue弹出框组件封装实例代码

    新学vue,参考别人封装弹出层组件.好用! 1.你需要先建一个弹出框的模板: //首先创建一个mack.vue <template> <div class="mack" v-if="isShow"> <div class="mackWeb" :style="text.mackStyle"> <div class="title font_b" v-if="t

  • 解决element DateTimePicker+vue弹出框只显示小时

    三个知识点: 1.css 后代选择器 https://www.w3school.com.cn/css/css_selector_descendant.asp 2.vue深度选择器 https://vue-loader.vuejs.org/zh/guide/scoped-css.html 3.element ui DateTimePicker 指定下拉框类名 popper-class https://element.eleme.cn/#/zh-CN/component/datetime-picke

随机推荐