使用uniapp编写一款简洁实用的注册页面

介绍

随着移动设备的广泛普及,应用程序开发变得越来越流行。其中,跨平台开发和开发工具也被重视,uniapp正是其中一种很好的跨平台开发工具。

在本文中,我们将使用uniapp编写一款简洁实用的注册页面,其中包含了一些基本的表单验证和交互功能。

创建uniapp项目

首先,您需要安装node.js和HBuilderX,然后打开HBuilderX并创建一个新的uniapp项目。

打开HBuilderX,然后点击“新建”,选择“uni-app”模板。输入应用程序的名称和存放位置,然后点击“创建”按钮,即可创建您的uniapp项目。

创建注册页面

在HBuilderX中,在uniapp项目的“pages”目录下创建一个名为“register”的新页面。然后,根据需求,添加必要的表单与元素到“register.vue”文件中。


<template>
  <div class="register-page">
    <div class="form-wrapper">
      <div class="form-item">
        <label for="username">用户名</label>
        <input type="text" id="username" v-model="username" placeholder="请输入用户名">
      </div>
      <div class="form-item">
        <label for="password">密码</label>
        <input type="password" id="password" v-model="password" placeholder="请输入密码">
      </div>
      <div class="form-item">
        <label for="password-confirm">确认密码</label>
        <input type="password" id="password-confirm" v-model="passwordConfirm" placeholder="请再次输入密码">
      </div>
      <div class="submit-btn">
        <button @click="submit">提交</button>
      </div>
    </div>
  </div>
</template>

添加表单验证

为了确保用户输入完整的信息并防止他们输入非法的信息,我们需要添加表单验证。在本实例中,我们将确保输入字段不为空、密码与确认密码相同,并且用户名不与现有用户名冲突。

用户名验证

我们可以使用uniapp的Ajax功能来检查输入的用户名是否已经存在于数据库中。在此之前,您需要编写一个基本的后端接口以接受和返回用户名数据。


const checkUsername = (username) => {
  return new Promise((resolve, reject) => {
    uni.request({
      url: 'https://example.com/check-username',
      method: 'POST',
      data: {
        username: username
      },
      success(res) {
        if (res.data.exists) { // 用户名已存在
          reject('该用户名已被注册')
        } else {
          resolve()
        }
      },
      fail(error) {
        reject('验证失败')
      }
    })
  })
}

当用户离开“用户名”输入字段时,我们可以触发该函数并处理验证结果。将下面的代码放入“register.vue”的“methods”对象中:


checkUsername() {
  if (!this.username) {
    this.usernameError = '请输入用户名'
    return
  }
  const reg = /^[a-zA-Z0-9_]+$/
  if (!reg.test(this.username)) {
    this.usernameError = '用户名只能包含字母、数字和下划线'
    return
  }
  checkUsername(this.username).catch(error => {
    this.usernameError = error
  })
}

密码验证

我们可以在每个密码输入框失去焦点时检查密码是否与确认密码相同。表示这些密码是否相同的字段是“passwordError”和“passwordConfirmError”。


checkPassword() {
  if (this.password !== this.passwordConfirm) {
    this.passwordError = '两次输入的密码不同'
    this.passwordConfirmError = '请再次输入密码'
  }
}

添加交互功能

我们可以利用uniapp提供的一些交互功能来提高用户体验。这些功能包括:toast、modal、actionSheet、popup、picker等。您可以根据自己的需求自由使用这些组件。

toast组件

toast组件可以在页面顶部显示一条信息,例如:注册成功或注册失败。


showToast(msg, duration) { // duration默认为2000ms
  uni.showToast({
    title: msg,
    icon: 'none',
    duration: duration || 2000
  })
}

modal组件

modal组件可以在页面弹出一个对话框,例如:确认提交或取消操作。


showModal(title, content) {
  return new Promise((resolve, reject) => {
    uni.showModal({
      title: title,
      content: content,
      success(res) {
        if (res.confirm) { // 点击确认按钮
          resolve()
        } else if (res.cancel) { // 点击取消按钮
          reject()
        }
      }
    })
  })
}

actionSheet组件

actionSheet组件可以在页面底部显示一个选项卡,用户可以选择一个操作,例如:选择性别、绑定第三方账户等。


showActions(actions) { // actions的格式为[{name: ''}, {name: '', color: ''}]
  uni.showActionSheet({
    itemList: actions.map(item => item.name),
    itemColor: actions.map(item => item.color || '#000000'),
    success(res) { // 用户选择预设项
      actions[res.tapIndex].callback()
    }
  })
}

popup组件

popup组件可以在页面弹出一个浮动框,可以用来显示如下拉菜单,弹出表单等。


showPopup() {
  this.isPopupVisible = true // 设置popup的显隐状态为true
}
hidePopup() {
  this.isPopupVisible = false
}

picker组件

picker组件可以弹出一个滚动选择器,例如:选择日期、选择城市等。


showPicker() {
  const pickerData = [[], []] // 显示两列选择器
  uni.showLoading() // 显示加载状态
  Promise.all([ // 同时获得两个下拉框的数据,然后将其处理成一个数组pickerData
    uni.request({
      url: 'https://example.com/province-data',
      method: 'GET'
    }),
    uni.request({
      url: 'https://example.com/city-data',
      method: 'GET'
    })
  ]).then(responses => {
    const provinces = responses[0].data
    const cities = responses[1].data
    pickerData[0] = provinces.map(item => item.name)
    provinces.forEach(item => {
      pickerData[1].push(cities.filter(city => city.province_id === item.id))
    })
    pickerData[1].forEach(item => {
      item = item.map(city => city.name)
    })
    this.pickerData = pickerData
    this.showPopup() // 显示picker浮层
  }).catch(error => {
    this.showToast('获取数据失败')
  }).finally(() => {
    uni.hideLoading() // 隐藏加载状态
  })
}

完整代码

下面是完整的注册页面代码,包括上述所有的功能和交互。


<template>
  <div class="register-page">
    <div class="form-wrapper">
      <div class="form-item">
        <label for="username">用户名</label>
        <input type="text" id="username" v-model="username" placeholder="请输入用户名" @blur="checkUsername">
        <p class="error-msg" v-if="usernameError">{{ usernameError }}</p>
      </div>
      <div class="form-item">
        <label for="password">密码</label>
        <input type="password" id="password" v-model="password" placeholder="请输入密码" @blur="checkPassword">
        <p class="error-msg" v-if="passwordError">{{ passwordError }}</p>
      </div>
      <div class="form-item">
        <label for="password-confirm">确认密码</label>
        <input type="password" id="password-confirm" v-model="passwordConfirm" placeholder="请再次输入密码" @blur="checkPassword">
        <p class="error-msg" v-if="passwordConfirmError">{{ passwordConfirmError }}</p>
      </div>
      <div class="submit-btn">
        <button @click="submit">提交</button>
      </div>
    </div>
    <popup v-if="isPopupVisible">
      <picker :value="pickerValue" :range="pickerData" @change="pickerChange"></picker>
      <div slot="footer">
        <button @click="hidePopup">取消</button>
        <button @click="submitPopup">确认</button>
      </div>
    </popup>
  </div>
</template>
<script>
const checkUsername = (username) => {
  return new Promise((resolve, reject) => {
    uni.request({
      url: 'https://example.com/check-username',
      method: 'POST',
      data: {
        username: username
      },
      success(res) {
        if (res.data.exists) { // 用户名已存在
          reject('该用户名已被注册')
        } else {
          resolve()
        }
      },
      fail(error) {
        reject('验证失败')
      }
    })
  })
}
export default {
  data() {
    return {
      username: '', // 用户名
      password: '', // 密码
      passwordConfirm: '', // 确认密码
      usernameError: '', // 用户名错误提示
      passwordError: '', // 密码错误提示
      passwordConfirmError: '', // 确认密码错误提示
      isPopupVisible: false, // popup显隐状态
      pickerValue: [0, 0], // picker选中的项
      pickerData: [[], []] // picker的数据列表
    }
  },
  methods: {
    submit() {
      if (!this.username) {
        this.usernameError = '请输入用户名'
        return
      }
      const reg = /^[a-zA-Z0-9_]+$/
      if (!reg.test(this.username)) {
        this.usernameError = '用户名只能包含字母、数字和下划线'
        return
      }
      if (this.password !== this.passwordConfirm) {
        this.passwordError = '两次输入的密码不同'
        this.passwordConfirmError = '请再次输入密码'
        return
      }
      uni.showLoading({
        title: '提交中'
      })
      setTimeout(() => {
        uni.hideLoading()
        uni.showModal({
          title: '注册成功',
          content: '请登录您的账号',
          showCancel: false,
          success: (res) => {
            uni.navigateBack()
          }
        })
      }, 1000)
    },
    checkUsername() {
      if (!this.username) {
        this.usernameError = '请输入用户名'
        return
      }
      const reg = /^[a-zA-Z0-9_]+$/
      if (!reg.test(this.username)) {
        this.usernameError = '用户名只能包含字母、数字和下划线'
        return
      }
      checkUsername(this.username).catch(error => {
        this.usernameError = error
      })
    },
    checkPassword() {
      if (this.password !== this.passwordConfirm) {
        this.passwordError = '两次输入的密码不同'
        this.passwordConfirmError = '请再次输入密码'
      }
    },
    showPopup() {
      this.isPopupVisible = true
    },
    hidePopup() {
      this.isPopupVisible = false
    },
    pickerChange(e) {
      this.pickerValue = e.detail.value
    },
    submitPopup() {
      this.hidePopup()
      this.showToast('选择了' + this.pickerData[0][this.pickerValue[0]] + this.pickerData[1][this.pickerValue[0]][this.pickerValue[1]])
    },
    showToast(msg, duration) { // duration默认为2000ms
      uni.showToast({
        title: msg,
        icon: 'none',
        duration: duration || 2000
      })
    },
    showModal(title, content) {
      return new Promise((resolve, reject) => {
        uni.showModal({
          title: title,
          content: content,
          success(res) {
            if (res.confirm) { // 点击确认按钮
              resolve()
            } else if (res.cancel) { // 点击取消按钮
              reject()
            }
          }
        })
      })
    },
    showActions(actions) { // actions的格式为[{name: ''}, {name: '', color: ''}]
      uni.showActionSheet({
        itemList: actions.map(item => item.name),
        itemColor: actions.map(item => item.color || '#000000'),
        success(res) { // 用户选择预设项
          actions[res.tapIndex].callback()
        }
      })
    }
  }
}
</script>

结论

完整代码可以帮助您了解uniapp的功能和交互方式,并帮助您编写实用的多平台移动应用程序。通过掌握表单验证和交互技术,您可以改进用户体验,提高用户满意度。