Vue.js реализует настраиваемую форму входа

внешний интерфейс Element Vue.js Vuex

Форма является обычным компонентом в фоновом бизнесе проекта. На этот раз функция входа в систему была реконструирована для удовлетворения потребностей настраиваемых методов входа. Запишите и поделитесь ею здесь.

Деловая сцена

В прошлом проект поддерживал только номер мобильного телефона + вход в систему с паролем, а внешний интерфейс напрямую записывал форму до смерти.Позже некоторые клиенты надеялись поддерживать вход с кодом подтверждения, а некоторые клиенты также надеялись иметь номер мобильного телефона + код подтверждения. + метод входа в систему с паролем.. Таким образом, гибкость метода входа требует поддержки настраиваемой формы, поэтому я разделил компонент входа.

Принимая элементы формы за детализацию, номер мобильного телефона, пароль и код подтверждения SMS разделены.У них есть свои собственные методы проверки формы.Благодаря комбинации вы можете быстро заполнить такие компоненты формы, как логин, регистрация и восстановление пароля. . Высокая сплоченность и низкая связанность, высокая сплоченность и низкая связанность... и прочтите это десять раз~

.
├ common #拆分的表单元素组件
|   ├ captcha.vue  #短信验证码
|   ├ password.vue #密码
|   └ phone.vue    #手机号
├ login #登录组件
|   └ index.vue
├ register #注册组件
|   └ index.vue
└ resetPassword #找回密码组件
    └ index.vue

Здесь мы используем логин в качестве родительского компонента, читаем конфигурацию входа, возвращенную сервером, и рендерим в шаблоне условно, вызываем проверку формы внутри дочернего компонента при входе в систему и, наконец, получаем интерфейс вызова данных через Vuex. Логика всей настраиваемой формы входа — соус, а затем код.

код

Запрашивая данные конфигурации сервера:

/* 参数说明:
 * 'password': 密码登录 
 * 'captcha': 短信验证码登录
 * 'password_or_captcha': 密码或短信登录 
 * 'password_with_captcha': 密码+短信登录
 */
config: {
  login_methods: 'password'
}

Основной код рендеринга (pug) компонента входа в систему:

.login-card
  .login-header
      h3 登录

  .login-content
  	 //- 手机号作为通用的账户名
    phone(ref="phone")
    //- 密码组件
    password(
      v-if="isPasswordMode"
      ref="password"
    )
    //- 短信验证码组件
    captcha(
      v-if="isCaptchaMode"
      ref="captcha"
    )
    
    //- 短信验证码 和 密码
    template(v-if="isPasswordWithCaptchaMode")
      captcha(ref="captcha")
      password(ref="password")
    
    //- 短信验证码 或 密码
    template(v-if="isPasswordOrCaptchaMode")
      ...
    
    el-button(@click="login") 登录

При входе в систему требуется три шага: проверка формы, сборка данных и вызов интерфейса:

async login () {
  if (!this.validate()) return // 表单验证
  const loginData = this.getLoginData() // 组装数据
  await this.postLogin(loginData) // 调用接口(vuex actions)
  ...
}

Проверка формы входа фактически для всех компонентов в текущем методе входа.validate()метод логических рассуждений:

/**
 * @return {Boolean} isPass
 */
validate () {
  const phone = this.$refs.phone.validate()
  let isPass = false
    
  if (this.isPasswordMode) {
    if (this.$refs.password) isPass = this.$refs.password.validate()
  }
    
  if (this.isCaptchaMode) {
    if (this.$refs.captcha) isPass = this.$refs.captcha.validate()
  }
    
  if (this.isPasswordWithCaptchaMode) ...
    
  if (this.isPasswordOrCaptchaMode) ...
    
  isPass = phone && isPass
  return isPass
}

Из-за использования element-ui подкомпонентvalidate()методомel-formпредоставляемый компонентом.

Как вы можете видеть из шаблона компонента пароля ниже, мы рассматриваем каждый подкомпонент как полную форму (это было сделано для работы с несколькими элементами формы внутри некоторых подкомпонентов, а логика взаимодействия и проверки между ними была более сложной):

.login-password
  el-form(
    :model="form"
    :rules="rules"
    ref="form"
    @submit.native.prevent=""
  )
    el-form-item(prop="password")
      el-input(
        v-model="form.password"
        type="password"
        name="password"
      )

W3C: When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.

Обратите внимание, что согласноСтандарт W3C, когда в элементе формы есть только одно поле ввода, нажатие Enter в поле ввода автоматически отправит форму. в<el-form>Добавить к@submit.native.preventЭто поведение по умолчанию можно предотвратить.

Проверка формы для компонента пароля (с использованием формы element-ui):

/**
 * @return {Boolean} res
 */
validate () {
  let res = false
  this.$refs.form.validate((valid) => {
    res = valid
  })
  return res
}

Наконец, получите все данные формы из Vuex и соберите их:

computed: {
  ...mapState('login', {
    phone: state => state.phone,
    password: state => state.password,
    captcha: state => state.captcha
  }),  
},
methods: {
  ...
  
  /**
   * @return {Object} data
   */
  getLoginData () {
    let mode = ''
    const phone = this.phone
    ...
    const data = { phone }
    
    if (this.isPasswordMode) {
      mode = 'password'
      data.password = password
    }
    
    if (this.isCaptchaMode) {
      mode = 'captcha'
      data.captcha = captcha
    }
    
    if (this.isPasswordWithCaptchaMode) ...
    
    if (this.isPasswordOrCaptchaMode) ...
    
    data.mode = mode
    return data
  }
}

Интерфейс вызова:

const loginData = this.getLoginData()
await this.postLogin(loginData)
...