vue实现底部弹窗多选

本文实例为大家分享了vue实现底部弹窗多选的具体代码,供大家参考,具体内容如下

代码:

<template>
  <div class="release-post">
    <div class="resume_main">
      <div class="resume_content">
        <van-form>
          <div class="table_list post_welfare">
            <p class="name_title">岗位福利<span class="required">*</span></p>
            <van-field
              class="calendar"
              input-align="left"
              v-model="benefits"
              placeholder="请选择岗位福利"
              @focus="onFocus"
              :class="{ borderStyle: welfareChange }"
              @click.stop="clickWelfare"
              :disabled="true"
            />
          </div>
        </van-form>
        <!-- 岗位福利 -->
        <van-popup v-model="showWelfare" position="bottom">
          <div class="welfare_top">
            <p></p>
            <p class="welfare_title">福利待遇(可多选)</p>
            <p class="welfare_btn" @click.stop="onConfirmSpeed">完成</p>
          </div>
          <div class="welfare_content">
            <div
              v-for="(item, index) in welfareList"
              :key="index"
              :class="{ active: item.active }"
              id="welfare_item"
              @click.stop="clickWelfareItem(item, index)"
            >
              <p :class="item.active ? 'welfare_text' : 'not_welfare_text'">
                {{ item.text }}
              </p>
            </div>
          </div>
        </van-popup>
      </div>
    </div>
    <div>
      <div class="mask">
        <button
          class="btn"
          @click="submit"
          :class="{ btnBg: colorChange() }"
          v-preventReClick="1000"
        >
          完成
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import Vue from 'vue';
import { Circle, DatetimePicker, Form, Field, Toast, Calendar, Picker, Overlay, ActionSheet, Popup } from 'vant';
import 'vant/lib/index.less';
Vue.use(Circle).use(DatetimePicker).use(Form).use(Field).use(Toast).use(Calendar).use(Picker).use(Overlay).use(ActionSheet).use(Popup);

export default {
  name: "PerfectPost",
  data () {
    return {
      welfareList: [
        {
          id: 1,
          text: "包吃"
        },
        {
          id: 2,
          text: "包住"
        },
        {
          id: 3,
          text: "五险一金"
        },
        {
          id: 4,
          text: "年底双薪"
        },
        {
          id: 5,
          text: "商业险"
        },
        {
          id: 6,
          text: "意外险"
        },
        {
          id: 7,
          text: "团建"
        },
        {
          id: 8,
          text: "周末双休"
        },
        {
          id: 9,
          text: "下午茶"
        },
        {
          id: 10,
          text: "餐补"
        },
        {
          id: 11,
          text: "交通补助"
        },
        {
          id: 12,
          text: "班车接送"
        },
        {
          id: 13,
          text: "奖金"
        },
        {
          id: 14,
          text: "公费培训"
        },
        {
          id: 15,
          text: "公费旅游"
        },
      ],
      showWelfare: false,//岗位福利
      onlineForm: {
        benefits: "",//岗位福利
      },
      checkedList: [],
      welfareChange: false,
    };
  },
  methods: {
    //弹出岗位福利
    clickWelfare () {
      this.showRedTips()
      this.showWelfare = true
    },
    //选择福利项
    clickWelfareItem (v) {
      if (v.active) {
        Vue.set(v, 'active', false)
      } else if (this.checkedList.length < 5) {
        Vue.set(v, 'active', true)
      }
      this.checkedList = this.welfareList.filter(function (item) {
        return item.active
      })
      if (this.checkedList.length >= 5) {
        Toast('最多只能选择5个哦')
      }
    },
    //完成福利选项
    onConfirmSpeed () {
      this.showWelfare = false
      this.welfareChange = false
      let itemList = this.checkedList.map((item) => {
        return item.text
      });
      let str = itemList.join('/')
      let str1 = itemList.join(';')
      this.benefits = str ? str : this.benefits
      this.onlineForm.benefits = str1 ? str1 : this.benefits
    },
    showRedTips () {
      this.welfareChange = false
    },
    onFocus () {
      this.showRedTips()
    },
    //下一步按钮色值
    colorChange () {
      if (this.onlineForm.benefits) {
        return true
      }
    },
    // 验证
    validateOnlineForm () {
      let valid = true;
      if (!this.onlineForm.benefits || !this.onlineForm.benefits.trim()) {
        valid = false;
        Toast('请选择岗位福利')
        this.welfareChange = true
      }
      return valid;
    },
    //提交
    submit () {
      if (this.validateOnlineForm()) {
        Toast('提交')
      }
    },
  },
};
</script>

<style scoped lang="less" >
* {
  margin: 0;
  padding: 0;
}
::v-deep .van-picker__title {
  font-size: 17px;
  font-family: PingFangSC, PingFangSC-Medium;
  font-weight: 500;
  text-align: center;
  color: #333333;
}
.release-post {
  width: 100%;
  padding-bottom: 64px;
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
}
.post_welfare {
  ::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;
  }
  ::v-deep input::-webkit-input-placeholder {
    font-size: 15px;
    font-family: PingFangSC, PingFangSC-Regular;
    font-weight: 400;
    text-align: left;
    color: #999999;
    -webkit-text-fill-color: #999999;
  }
}
::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;
}

.welfare_content {
  padding-top: 10px;
  padding-bottom: 30px;
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-wrap: wrap;
  margin: 0 16px;
}
#welfare_item {
  width: 31%;
}
.welfare_top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 13px 0;
  border-bottom: solid 0.5px #e5e5e5;
}
.welfare_title {
  font-size: 17px;
  font-family: PingFangSC, PingFangSC-Medium;
  font-weight: 500;
  text-align: center;
  color: #333333;
  margin-right: -16px;
}
.welfare_btn {
  font-size: 16px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  text-align: right;
  color: #333333;
  margin-right: 16px;
}
.welfare_text {
  height: 36px;
  background: #f4f8ff;
  border: 1px solid #bbdcff;
  border-radius: 4px;
  margin-top: 10px;
  line-height: 36px;

  font-size: 14px;
  font-family: PingFangSC, PingFangSC-Medium;
  font-weight: 500;
  text-align: center;
  color: #1283ff;
}
.not_welfare_text {
  height: 36px;
  background: #ffffff;
  border: 1px solid #e5e5e5;
  border-radius: 4px;
  margin-top: 10px;
  line-height: 36px;

  font-size: 14px;
  font-family: PingFang, PingFang-SC;
  font-weight: 500;
  text-align: center;
  color: #333333;
}

.resume_content {
  margin-left: 30px;
  margin-right: 30px;
  ::v-deep {
    .van-popup--bottom {
      border-top-left-radius: 12px;
      border-top-right-radius: 12px;
    }
  }
}
.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-Medium;
  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-Medium;
  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-Medium;
  font-weight: 500;
  color: #333333;
}

.required {
  font-size: 13px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  color: #ff1d28;
  position: absolute;
}
.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;
}
.borderStyle {
  border: solid 1px #ff1d28;
  border-radius: 3px;
}
input::-webkit-input-placeholder {
  font-size: 15px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  text-align: left;
  color: #999999;
}
.van-field__control {
  color: #333333;
}
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue的toast弹窗组件实例详解

    相信普通的vue组件大家都会写, 定义 -> 引入 -> 注册 -> 使用 ,行云流水,一气呵成,但是如果我们今天是要自定义一个弹窗组件呢? 首先,我们来分析一下弹窗组件的特性(需求): 0. 轻量 --一个组件小于 1Kib (实际打包完不到0.8k) 1.一般都是多处使用 --需要解决每个页面重复引用+注册 1.一般都是跟js交互的 --无需 在 <template> 里面写 <toast :show="true" text="弹窗消息

  • vue弹窗消息组件的使用方法

    本文实例为大家分享了vue弹窗消息组件的具体代码,供大家参考,具体内容如下 本来打算写一个那种提示完了自动消失的弹窗的,但是没有想好淡入淡出的效果.所以暂时算是半成品. 练习代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ys-alert-component</title> <style

  • VUE实现可随意拖动的弹窗组件

    背景:项目需要,我们引入了前端框架就是目前最流行的框架之一vue,同时引入了一套由饿了吗维护的ui库,由于我们是在pc端使用发现它竟然没有提供可随意拖动的窗口,可能用的更多的时移动端吧吧,于是就随手写了一个,比较简单吧,但是做过的就会知道也是有一些小小的技巧,记录下吧留作备用. 由于不是很难,就不做过多解释了,直接上代码: <template> <el-container v-bind:id="id" v-if="dialogVisible">

  • vue 弹窗时 监听手机返回键关闭弹窗功能(页面不跳转)

    [注]:popstate 事件 a.当活动历史记录条目更改时,将触发popstate事件. b.如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对history.replaceState()的调用的影响,popstate事件的state属性包含历史条目的状态对象的副本. c.需要注意的是调用history.pushState()或history.replaceState()不会触发popstate事件. d.只有在做出浏览器动作时,才会触发该事件,如用

  • 关于vue.js弹窗组件的知识点总结

    首先在开发时需要考虑以下三点: 1.进入和弹出的动画效果. 2.z-index 的控制 3.overlay 遮盖层 关于动画 vue 对于动画的处理相对简单,给组件加入css transition 动画即可 <template> <div class="modal" transition="modal-scale"> <!--省略其它内容--> </div> </template> <script&g

  • 使用Vue组件实现一个简单弹窗效果

    最近在使用element-ui框架,用到了Dialog对话框组件,大致实现的效果,跟我之前自己在移动端项目里面弄的一个弹窗组件差不太多.然后就想着把这种弹窗组件的实现方式与大家分享一下,下面本文会带着大家手摸手实现一个弹窗组件. 本文主要内容会涉及到弹窗遮罩的实现, slot 插槽的使用方式, props . $emit 传参,具体组件代码也传上去了.如果喜欢的话可以点波赞/关注,支持一下,希望大家看完本文可以有所收获. 组件最后实现的效果 实现步骤 先搭建组件的html和css样式,遮罩层和内

  • Vue中关闭弹窗组件时销毁并隐藏操作

    背景:在dialog弹窗组件中执行mounted钩子,将数据初始化,等取消关闭弹窗后,发现mounted钩子不执行 原因:在vue的生命周期中,在页面初始化的时候mounted只会执行一次,关闭弹窗页面并没有销毁,所以不会再次执行 <select-experience-group :trialMoneyRecordID=trialMoneyRecordID :showExperienceGroup='showExperienceGroup' @closeCover="handleExper

  • 使用VUE实现在table中文字信息超过5个隐藏鼠标移到时弹窗显示全部

    具体代码如下所示: <template> <div> <table> <tr v-for="item in tableData" :value="item.value" :key="item"> <td> <div> <template> {{item.id}} </template> </div> </td> <td&g

  • 很棒的vue弹窗组件

    弹窗是一个项目必备的复用利器,所以封装起来,保证项目ui一致,是很有必要的.学了一段时间vue,想想还是用vue写一下吧.用的很小白,但是会写出来了,说明我也有进步一丢丢了.继续加油-. 代码贴图如下,样式比较丑,不要介意- <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ys-vue-modal-component

  • vue实现点击按钮“查看详情”弹窗展示详情列表操作

    html: <template> <div> <Modal v-model="classStatus" width="900" title="详情:" :styles="{top: '80px'}"> <Table stripe class="task-table" :columns="columnsName4" :data="task

随机推荐