vue3项目-小兔鲜儿笔记-商品详情页03和登录页01
作者:互联网
1.封装数量选择组件
功能分析:
-
默认值为1
-
可限制最大最小值
-
点击-就是减1,点击+就是加1
-
需要完成v-model的双向数据绑定
-
存在无label的情况
<script setup>
// 组件间的v-model =》父组件绑定:modelValue,监听@update:modelValue
import { useVModel } from '@vueuse/core'
const emit = defineEmits(['update:modelValue', 'change'])
const props = defineProps({
modelValue: {
type: Number,
default: 1
},
min: {
type: Number,
default: 1
},
max: {
type: Number,
default: 100
},
label: {
type: String,
default: ''
}
})
// 使用useVModel做数据的双向绑定,这样修改值就会自动通知父组件
// 参数1为props,参数2为从父组件接收的参数,参数3是要发送的自定义事件
const count = useVModel(props, 'modelValue', emit)
// 修改值函数
const changeNum = (step) => {
const newVal = count.value + step
if (newVal < props.min || newVal > props.max) return
// 修改count值就会自动通知父组件count值修改
count.value = newVal
// 同时发出change通知
emit('change', count.value)
}
</script>
2.封装按钮组件
目的:封装一个通用按钮组件,有大、中、小、超小4种尺寸,有默认、主要、次要、灰色四种类型
<template>
<button class="xtx-button" :class="[size, type]">
<slot />
</button>
</template>
<script setup>
defineProps({
size: {
type: String,
default: 'middle'
},
type: {
type: String,
default: 'default'
}
})
</script>
.large {
width: 240px;
height: 50px;
font-size: 16px;
}
.middle {
width: 180px;
height: 50px;
font-size: 16px;
}
.small {
width: 100px;
height: 32px;
font-size: 14px;
}
.mini {
width: 60px;
height: 32px;
font-size: 14px;
}
.default {
border-color: #e4e4e4;
color: #666;
}
.primary {
border-color: @xtxColor;
background-color: @xtxColor;
color: #fff;
}
.plain {
border-color: @xtxColor;
color: @xtxColor;
background-color: lighten(@xtxColor, 50%);
}
.gray {
border-color: #ccc;
background-color: #ccc;
color: #fff;
}
3. 登录-表单校验
-
定义校验规则
utils/vee-validate.js // 定义校验规则给vee-validate组件使用 export default { // 校验account account(value) { // value是将来使用该规则的表单元素的值 // 1.必填 // 2.6~20个字符,以字母开头 // 返回true表示校验成功,其他情况均为失败,返回失败原因 if (!value) return '请输入用户名' if (!/^[a-zA-Z]\w(5,19)$/.test(value)) { return '字母开头且6~20个字符' } return true }, password(value) { if (!value) return '请输入密码' if (!/^\w(6,24)$/.test(value)) return '密码是6~24个字符' return true }, mobile(value) { if (!value) return '请输入手机号码' if (!/^1[3-9]\d(9)$/.test(value)) return '手机号格式错误' return true }, code(value) { if (!value) return '请输入验证码' if (!/^\d(6)$/.test(value)) return '验证码是6位数字' return true }, isAgree(value) { if (!value) return '请勾选同意用户协议' return true } }
- 使用vee-validate提供的Form组件,绑定validation-schema为上述自定义校验规则
<Form ref="formCom" class="form" :validation-schema="mySchema" autocomplete="off" v-slot="{errors}" > ....
- 使用vee-validate提供的Field组件代替input表单元素,指定name属性为自定义校验规则中的某项,比如,自定义校验中:account(){...},这里指定name就为account
<Field :class="{error: errors.account}" v-model="form.account" name="account" type="text" placeholder="请输入用户名或手机号" /> ....
- Form组件内部使用了默认插槽,这个插槽会返回errors错误对象,用于提示错误信息,比如errors.account就是显示自定义校验中account未通过校验返回的错误信息
<div class="error" v-if="errors.account"> <i class="iconfont icon-warning"></i> {{ errors.account }} </div> ...
- 切换组价时调用重置表单的方法清除校验结果
const formCom = ref(null) // Form表单的ref对象 // 表单数据 const form = reactive({ isAgree: true, account: null, password: null, mobile: null, code: null }) // 表单校验规则 const mySchema = { account: veeSchema.account, password: veeSchema.password, mobile: veeSchema.mobile, code: veeSchema.code, isAgree: veeSchema.isAgree } watch(isMsgLogin, () => { form.account = null form.code = null form.mobile = null form.isAgree = true form.password = null // formCom组件提供重置表单的方法resetForm() formCom.value.resetForm() })
- 当点击登录时,提交表单,调用Form组件的ref对象提供的统一校验方法validate()
// 统一校验,Form组件提供统一校验方法validate() const login = async () => { const valid = await formCom.value.validate() if (valid) { // 账号登录 if (!isMsgLogin.value) { try { const {result} = await userAccountLogin({account: form.account, password: form.password}) const {id, avatar, nickname, account, mobile, token} = result // 1.获取用户信息并存储到userStore中 userStore.setUser({ id, avatar, nickname, account, mobile, token }) // 2.消息提醒 Message({type: 'success', text: '登录成功'}) // 3.跳转 await router.push(route.query.redirectUrl || '/') } catch (e) { Message({type: 'error', text: '登录失败'}) } } else { // 手机号登录 try { if (codeSpan.value.disabled) { const {result} = await userMobileLogin({mobile: form.mobile, code: form.code}) const {id, avatar, nickname, account, mobile, token} = result // 1.获取用户信息并存储到userStore中 userStore.setUser({ id, avatar, nickname, account, mobile, token }) // 2.消息提醒 Message({type: 'success', text: '登录成功'}) // 3.跳转 await router.push(route.query.redirectUrl || '/') } else { throw Error('未发送验证码') } } catch (e) { Message({type: 'error', text: '登录失败'}) } } } }
标签:03,account,01,return,鲜儿,校验,value,组件,const 来源: https://www.cnblogs.com/jzhFlash/p/16663730.html