美文网首页
Vue 子传父 表单控件二次封装

Vue 子传父 表单控件二次封装

作者: 逸笛 | 来源:发表于2021-03-31 16:49 被阅读0次
    图片.png
    图片.png

    需求:
    实现上图表单,封装成组件
    实现过程:
    1.子组件:Child

    <template>
    <div>
    <span>{{title}}</span>
       <el-input v-show="registerType===1" class="code" placeholder="请输入邮箱"  @input="setEmail" v-model="email"></el-input></div>
    </template>
    
    <script>
    export default {
      name: '',
      data () {
        return {
          email: '',
        }
      },
    //父传子:通过props传递
      props: {
        title: String,
      },
      methods: {
    //子传父:通过this.$emit传递
        setEmail () {
          this.$emit('setEmail', this.email)
        },
      }
    }
    </script>
    
    

    2.父组件使用Child组件

    <template>
    <Child @setEmail ="setEmail " :title="title"></Child>
    </template>
    
    <script>
    export default {
      name: '',
      data () {
        return {
          email: '',
    title:"向子组件传递来自接口的数据"
        }
      },
     components: {
    Child
      }
      methods: {
    //获取来自Child动态值
        setEmail (val) {
         this.email=val //可使用来自子组件的动态值
        },
      }
    }
    </script>
    
    

    实战:

    子组件:RegisterModel:

    <template>
      <div class="globalLoginBox" v-show="isRegisterFlag">
        <div
          class="globalRegister"
          :class="{globalPhoneRegister:registerType===2}"
          v-loading="loginLoad"
        >
          <img class="close" @click="closeModel()" :src="$utils.getPng('login_close')" />
          <div class="loginContent">
            <img class="logo" :src="$utils.getPng('menu_logo')" />
            <div class="loginType">
              <span class="type" :class="{on:registerType===1}" @click="modelTabChange(1)">邮箱注册</span>
              <span class="line"></span>
              <span class="type" :class="{on:registerType===2}" @click="modelTabChange(2)">手机注册</span>
            </div>
            <div class="userForm">
              <el-input v-show="registerType===1" class="code" placeholder="请输入邮箱"  @input="setEmail" v-model="email"></el-input>
    
              <el-input
                v-show="registerType===2"
                placeholder="请输入手机号"
                v-model="phone"
                @input="setPhone"
                class="input-with-select"
              >
                <el-select v-model="pcode" @change="setPcode" style="width:80px" slot="prepend">
                  <el-option
                    :label="item.id"
                    :value="item.id"
                    v-for="item in cty"
                    :key="item.id"
                  >{{item.name}}</el-option>
                </el-select>
              </el-input>
    
              <el-input
                v-show="registerType===2"
                class="pwd pcode"
                placeholder="请输入验证码"
                v-model="vcode"
                @input="setVcode"
              >
                <template slot="suffix">
                  <div class="pcodeSlot">
                    <span class="line"></span>
                    <span class="getCode" @click="verifyfun('sendRegCode')" v-if="getCodeFlag">获取验证码</span>
                    <span class="waitBtn" v-else>已发送({{waitTime}})</span>
                  </div>
                </template>
              </el-input>
              <el-input class="pwd" placeholder="请输入用户名" v-model="username" @input="setNameVal"></el-input>
              <el-input class="pwd" placeholder="请输入密码" @input="setPwdVal" v-model="pwd" show-password></el-input>
              <el-input
                class="pwd"
                placeholder="请再次输入密码"
                @keyup.enter.native="verifyfun('dealRegister')"
                v-model="confirmPwd"
                @input="setConfirmPwd"
                show-password
              ></el-input>
              <div class="loginTool">
                <div class="toolLeft">
                  <el-checkbox v-model="checked" @change="setChecked">
                    <span>我同意</span>
                    <a target="_blank" href="https://help.feimaoyun.com/archives/125">《飞猫云用户服务协议》</a>
                  </el-checkbox>
                </div>
              </div>
              <div class="loginBtn" @click="verifyfun('dealRegister')">立即注册</div>
            </div>
          </div>
        </div>
      </div>
    </template>
    <script>
    export default {
      name: 'RegisterModel',
      data () {
        return {
          checked: true,
          confirmPwd: '',
          username: '',
          pwd: '',
          vcode: '',
          email: '',
          pcode: '+86',
          phone: ''
        }
      },
      props: {
        loginLoad: Boolean,
        cty: Array,
        registerType: Number,
        isRegisterFlag: Boolean,
        waitTime: String, // 验证码等待时间
        getCodeFlag: Boolean // 判断是显示获取验证码还是显示倒计时,默认显示获取验证码
      },
      methods: {
        setNameVal () {
          this.$emit('setNameVal', this.username)
        },
        setChecked () {
          this.$emit('setChecked', this.checked)
        },
        setConfirmPwd () {
          this.$emit('setConfirmPwd', this.confirmPwd)
        },
        setPwdVal () {
          this.$emit('setPwdVal', this.pwd)
        },
        setVcode () {
          this.$emit('setVcode', this.vcode)
        },
        setEmail () {
          this.$emit('setEmail', this.email)
        },
        setPhone () {
          this.$emit('setPhone', this.phone)
        },
        setPcode () {
          this.$emit('setPcode', this.pcode)
        },
        verifyfun (type) {
          this.$emit('verifyfun', type)
        },
        closeModel () {
          this.$emit('closeModel')
        },
        modelTabChange (val) {
          this.checked = true
          this.username = ''
          this.pwd = '' // 密码
          this.confirmPwd = '' // 确认密码
          this.vcode = '' // 验证码
          this.pcode = '+86' // 区号
          this.email = ''
          this.$emit('modelTabChange', 'register', val)
        },
        findPwd () {
          this.$emit('findPwd')
        }
      }
    }
    </script>
    
    

    页面使用(父组件):

    <template>
      <div class="downAppPage">
        <!-- 注册-邮箱注册|手机注册 -->
        <RegisterModel
          :loginLoad="loginLoad"
          :cty="cty"
          :isRegisterFlag="isRegisterFlag"
          :registerType="registerType"
          :waitTime="waitTime"
          :getCodeFlag="getCodeFlag"
          @setNameVal="setNameVal"
          @setChecked="setChecked"
          @setConfirmPwd="setConfirmPwd"
          @setPwdVal="setPwdVal"
          @setVcode="setVcode"
          @setEmail="setEmail"
          @setPhone="setPhone"
          @setPcode="setPcode"
          @closeModel="closeModel"
          @verifyfun="verifyfun"
          @modelTabChange="modelTabChange"
        ></RegisterModel>
      </div>
    </template>
    
    <script>
    import cty from '..//ishuowww/Tpl/Public/api/cty'
    import qrcode from 'qrcode'
    import WxLogin from 'WxLogin'
    import RegisterModel from '../components/RegisterModel'
    export default {
      name: 'downApp',
      data () {
        return {
          // 登录注册所需数据对象--S
          loginLoad: false,
          checked: true,
          cty: cty,
          username: '', // 用户名
          phone: '',
          pwd: '', // 密码
          confirmPwd: '', // 确认密码
          ifauto: true, // true-1记住密码,false-0不记录
          vcode: '', // 验证码
          vid: '', // 验证码id
          pcode: '+86', // 区号
          email: '',
          waitTime: '', // 验证码等待时间
          selectType: 'username', // 1.用户名 2.手机号
          loginType: 1,
          findType: 1, // 找回密码方式  1.手机 2.邮箱
          registerType: 1,
          getCodeFlag: true, // 判断是显示获取验证码还是显示倒计时,默认显示获取验证码
          isFindPwdFlag: false, // 找回密码弹窗
          isRegisterFlag: false, // 注册弹窗
          isLoginFlag: false, // 登录弹窗
          // 极验
          captchaObj: null,
          validate: [],
          gtswitch: 1,
          capbtn: 'login',
          loginTimer: null, // 扫码登录定时器
          editPwdTimer: null, // 修改密码 用来记录定时器,防止点击时触发多个setInterval
          wxInfo: {}, // 微信配置信息
          showWXbox: false // 微信快速登录
          // 登录注册所需数据对象--S
        }
      },
      created () {},
      methods: {
        setNameVal (value) {
          this.username = value
        },
        setPwdVal (value) {
          this.pwd = value
        },
        setIfauto (value) {
          this.ifauto = value
        },
        setSelectType (value) {
          this.selectType = value
        },
        setConfirmPwd (value) {
          this.confirmPwd = value
        },
        setVcode (value) {
          this.vcode = value
        },
        setPcode (value) {
          this.pcode = value
        },
        setEmail (value) {
          this.email = value
        },
        setPhone (value) {
          this.phone = value
        },
        setChecked (value) {
          this.checked = value
        },
        // 找回密码|注册tab切换
        modelTabChange (type, val) {
          if (type === 'findPwd') {
            this.findType = val
          } else {
            this.registerType = val
          }
          this.resetLogin()
        },
    
        // 关闭登录注册Model
        closeModel () {
          this.showWXbox = false
          this.isLoginFlag = false
          this.isFindPwdFlag = false
          this.isRegisterFlag = false
          this.hideFmScanf()
          this.loginType = 1
          this.findType = 1
          this.registerType = 1
        },
        // 打开注册Model
        openRegister () {
          this.isRegisterFlag = true
          this.getgeswitch()
        },
        // step1: 获取开关
        getgeswitch () {
          this.$api.post('/api/getgt', {}, (res) => {
            this.gtswitch = res.data
          })
        },
        // step4: 回调
        geetcallback (captchaObj, validate) {
          this.captchaObj = captchaObj
          this.validate = validate
          this[this.capbtn]()
        },
        // step2: 传入函数名 验证后调用函数 eg:login
        verifyfun (name) {
          if (this.gtswitch === 1) {
            this.capbtn = name
            if (!this.captchaObj) {
              this.$api.post('/api/getgeconfig', {}, (data) => {
                // step3: 传入极验官方的必填数据,回调
                this.$utils.initge(data, this.geetcallback)
              })
            } else {
              this.captchaObj.verify()
            }
          } else {
            this[name]()
          }
        },
    
    
    
        // 重置登录注册数据
        resetLogin () {
          this.username = '' // 用户名
          this.phone = ''
          this.pwd = '' // 密码
          this.confirmPwd = '' // 确认密码
          this.ifauto = true // true-1记住密码,false-0不记录
          this.vcode = '' // 验证码
          this.pcode = '+86' // 区号
          this.email = ''
          this.waitTime = '' // 验证码等待时间
        },
     
        // 注册手机获取验证码
        sendRegCode () {
          // registerType:1.'email' 2.'phone'
          if (this.phone === '') {
            this.$notify.warning({
              title: '提示',
              message: '请输入手机号'
            })
            return
          }
          this.getCodeFlag = false
          this.waitTime = 30
          clearInterval(this.editPwdTimer) // 清除定时器
          this.loginLoad = true
          // 需要验证邮箱的接口
          this.$api.post(
            '/user/sendregmsg',
            {
              pcode: this.pcode,
              phone: this.phone,
              geetest_challenge: this.validate.geetest_challenge,
              geetest_validate: this.validate.geetest_validate,
              geetest_seccode: this.validate.geetest_seccode
            },
            (res) => {
              this.loginLoad = false
              if (res.status) {
                this.$notify.success({
                  title: '提示',
                  message: res.msg
                })
                this.vid = res.data
                // 30秒结束,getCodeFlag为true,显示获取验证码;
                this.editPwdTimer = setInterval(() => {
                  this.waitTime -= 1
                  if (this.waitTime < 1) {
                    this.getCodeFlag = true
                    clearInterval(this.editPwdTimer)
                  }
                }, 1000)
              } else {
                if (res.msg === '请进行重新验证') {
                  this.gtswitch = 1
                }
                this.getCodeFlag = true
                this.$notify.warning({
                  title: '提示',
                  message: res.msg
                })
              }
            }
          )
        },
        // 立即注册
        dealRegister () {
          if (!this.checked) {
            this.$notify.warning({
              title: '提示',
              message: '请同意协议'
            })
            return
          }
          if (this.registerType === 2 && (this.phone === '' || this.vcode === '')) {
            this.$notify.warning({
              title: '提示',
              message: '手机号和验证码不能为空'
            })
            return
          }
          if (this.registerType === 1 && this.email === '') {
            this.$notify.warning({
              title: '提示',
              message: '邮箱不能为空'
            })
            return
          }
          if (this.username === '') {
            this.$notify.warning({
              title: '提示',
              message: '用户名不能为空'
            })
            return
          }
          if (this.pwd === '') {
            this.$notify.warning({
              title: '提示',
              message: '请填写密码'
            })
            return
          }
          if (this.confirmPwd === '') {
            this.$notify.warning({
              title: '提示',
              message: '请填写确认密码'
            })
            return
          }
          if (this.pwd !== this.confirmPwd) {
            this.$notify.warning({
              title: '提示',
              message: '两次输入的密码不一致'
            })
            return
          }
    
          this.$api.post(
            '/user/bothreg',
            {
              pcode: this.pcode,
              phone: this.phone,
              email: this.email,
              code: this.vcode,
              msgid: this.vid,
              username: this.username,
              password: this.pwd,
              cpassword: this.confirmPwd,
              geetest_challenge: this.validate.geetest_challenge,
              geetest_validate: this.validate.geetest_validate,
              geetest_seccode: this.validate.geetest_seccode
            },
            (res) => {
              if (res.status) {
                this.$notify.success({
                  title: '提示',
                  message: res.msg
                })
                window.location.reload()
              } else {
                this.$notify.warning({
                  title: '提示',
                  message: res.msg
                })
              }
            }
          )
        }
      },
      components: {
        RegisterModel
      }
    }
    </script>
    
    

    相关文章

      网友评论

          本文标题:Vue 子传父 表单控件二次封装

          本文链接:https://www.haomeiwen.com/subject/mchahltx.html