Files
tuniao-ui/componentsPage/form/form.vue
jaylen fa70ad608a 修改$t为$tn
修改部分函数api的名称
2022-11-27 16:58:51 +08:00

524 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="components-form">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Form表单</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" :fullWindowsScroll="true" @click="click">
<tn-form :model="model" ref="form" :errorType="errorType" :labelPosition="labelPosition" :labelWidth="labelWidth" :labelAlign="labelAlign">
<tn-form-item label="姓名" prop="name" leftIcon="identity" :required="true" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.name" type="text" placeholder="请输入姓名" :border="border"></tn-input>
</tn-form-item>
<tn-form-item label="性别" prop="sex" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.sex" type="select" placeholder="请选择性别" :border="border" :selectOpen="actionSheetShow" @click="actionSheetShow = true"></tn-input>
</tn-form-item>
<tn-form-item label="手机号码" prop="phone" rightIcon="phone" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.phone" type="number" placeholder="请输入手机号码" :border="border"></tn-input>
</tn-form-item>
<tn-form-item label="介绍" prop="desc" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.desc" type="textarea" placeholder="请输入介绍" :border="border" inputAlign="center"></tn-input>
</tn-form-item>
<tn-form-item label="密码" prop="password" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.password" type="password" placeholder="请输入密码" :border="border" :passwordIcon="true"></tn-input>
</tn-form-item>
<tn-form-item label="确认密码" prop="rePassword" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.rePassword" type="password" placeholder="请再次输入密码" :border="border"></tn-input>
</tn-form-item>
<tn-form-item label="水果" prop="fruit" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-checkbox-group v-model="model.fruit" :width="checkboxWidth" :wrap="checkboxWrap" @change="checkboxGroupChange">
<tn-checkbox v-for="(item, index) in checkboxList" :key="index" v-model="item.check" :name="item.name" :disabled="item.disabled">{{ item.name }}</tn-checkbox>
</tn-checkbox-group>
</tn-form-item>
<tn-form-item label="支付方式" prop="payType" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-radio-group v-model="model.payType" :width="radioWidth" :wrap="radioWrap" @change="radioGroupChange">
<tn-radio v-for="(item, index) in radioList" :key="index" :name="item.name" :disabled="item.disabled">{{ item.name }}</tn-radio>
</tn-radio-group>
</tn-form-item>
<tn-form-item label="所在地区" prop="region" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.region" type="select" placeholder="请选择所在地区" :border="border" :selectOpen="pickerShow" @click="pickerShow = true"></tn-input>
</tn-form-item>
<tn-form-item label="商品类型" prop="goodsType" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.goodsType" type="select" placeholder="请选择商品类型" :border="border" :selectOpen="selectShow" @click="selectShow = true"></tn-input>
</tn-form-item>
<tn-form-item label="验证码" prop="code" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.code" type="text" placeholder="请输入验证码" :border="border"></tn-input>
<tn-button slot="right" size="sm" backgroundColor="tn-bg-green" fontColor="tn-color-white" @click="getCode">{{ codeTips }}</tn-button>
</tn-form-item>
<tn-form-item label="记住密码" prop="remember" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-switch v-model="model.remember" slot="right"></tn-switch>
</tn-form-item>
<tn-form-item label="上传图片" prop="photo" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-image-upload :fileList="model.photo" @on-list-change="imageUploadChange"></tn-image-upload>
</tn-form-item>
</tn-form>
<view class="agreement">
<tn-checkbox v-model="model.agreement" @change="agreementCheckChange"></tn-checkbox>
<view class="agreement-text">勾选同意当前协议</view>
</view>
<tn-button backgroundColor="#01BEFF" fontColor="#FFFFFF" width="100%" @click="submit">提交</tn-button>
</dynamic-demo-template>
<!-- 性别选项 -->
<tn-action-sheet
v-model="actionSheetShow"
:list="actionSheetList"
@click="actionSheetClick"
></tn-action-sheet>
<!-- 地区picker -->
<tn-picker
v-model="pickerShow"
mode="region"
@confirm="regionPickerConfirm"
></tn-picker>
<!-- 商品类型select -->
<tn-select
v-model="selectShow"
mode="single"
:list="selectList"
@confirm="goodsTypeSelectConfirm"
></tn-select>
<!-- 验证码倒计时 -->
<tn-verification-code
ref="code"
:seconds="60"
@change="codeChange"
></tn-verification-code>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsForm',
components: {dynamicDemoTemplate},
data() {
return {
errorType: ['message','border-bottom','toast'],
labelPosition: 'left',
labelAlign: 'right',
border: false,
actionSheetShow: false,
labelWidth: 140,
checkboxWidth: 'auto',
checkboxWrap: false,
radioWidth: 'auto',
radioWrap: false,
pickerShow: false,
selectShow: false,
codeTips: '获取验证码',
checkboxList:[
{
name: '苹果',
disabled: false
},
{
name: '橘子',
disabled: false
},
{
name: '香蕉',
disabled: false
},
{
name: '榴莲',
disabled: true
}
],
radioList:[
{
name: '微信',
disabled: false
},
{
name: '支付宝',
disabled: true
},
{
name: '云闪付',
disabled: false
}
],
actionSheetList:[
{
text: '男'
},
{
text: '女'
},
{
text: '保密'
}
],
selectList: [
{
label: '手机',
value: 1101
},
{
label: '笔记本',
value: 1102
},
{
label: '手表',
value: 1103
}
],
model: {
name: '',
sex: '',
phone: '',
desc: '',
password: '',
rePassword: '',
fruit: ['橘子'],
payType: '微信',
region: '',
goodsType: '',
code: '',
remember: false,
photo: [],
agreement: false
},
rules: {
name: [
{
required: true,
message: '请输入用户名',
trigger: 'blur'
},
{
min: 3,
max: 5,
message: '姓名长度在3到5个字符',
trigger: ['change','blur'],
},
{
// 此为同步验证可以直接返回true或者false如果是异步验证稍微不同见下方说明
validator: (rule, value, callback) => {
return this.$tn.test.chinese(value);
},
message: '姓名必须为中文',
// 触发器可以同时用blur和change二者之间用英文逗号隔开
trigger: ['change','blur'],
},
{
// 异步验证需要通过调用callback()并且在里面抛出new Error()
// 抛出的内容为需要提示的信息和其他方式的message属性的提示一样
asyncValidator: (rule, value, callback) => {
if (value === '图鸟') {
callback(new Error('姓名重复'));
} else {
// 没有错误也要执行callback()回调
callback();
}
},
trigger: ['blur'],
}
],
sex: [
{
required: true,
message: '请选择性别',
trigger: 'change'
}
],
phone: [
{
required: true,
message: '请输入手机号码',
trigger: 'change'
}
],
desc: [
{
min: 5,
message: '简介不能少于5个字',
trigger: 'change'
},
{
// 正则表达式验证演示
pattern: /^[\u4e00-\u9fa5]+$/gi,
message: '简介只能包含中文',
trigger: 'change'
}
],
password: [
{
required: true,
message: '请输入密码',
trigger: ['change','blur']
},
{
pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]+\S{5,12}$/,
message: '需同时含有字母和数字长度在6-12之间',
trigger: ['change','blur']
}
],
rePassword: [
{
required: true,
message: '请再次输入密码',
trigger: ['change','blur']
},
{
validator: (rule, value, callback) => {
return value === this.model.password;
},
message: '两次输入的密码不相等',
trigger: ['change','blur'],
}
],
fruit: [
{
required: true,
message: '请选择水果',
trigger: 'change',
type: 'array'
}
],
payType: [
{
required: true,
message: '请选择支付方式',
trigger: 'change'
}
],
region: [
{
required: true,
message: '所在地区不能为空',
trigger: 'change'
}
],
goodsType: [
{
required: true,
message: '商品类型不能为空',
trigger: 'change'
}
],
code: [
{
required: true,
message: '验证码不能为空',
trigger: 'change'
}
],
remember: [
{
required: true,
message: '记住密码不能为空',
trigger: 'change'
}
],
photo: [
{
required: true,
message: '请选择图片',
trigger: 'change',
type: 'array'
}
],
},
tips: ['无需依赖额外的样式文件','使用tn-toast组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: 'label显示位置',
optional: ['左边','上边'],
methods: 'labelPositionChange'
},
{
title: 'label对齐方式',
optional: ['左对齐','右对齐','居中'],
methods: 'labelAlignChange',
current: 1
},
{
title: '边框显示',
optional: ['显示','隐藏'],
methods: 'borderChange',
current: 1
},
{
title: '可选项排列方式',
optional: ['默认','宽度的50%','换行'],
methods: 'checkRadioStyleChange'
},
{
title: '错误提示方式',
optional: ['message','toast','下划线','输入框'],
methods: 'errorTypeChange'
}
]
}
]
}
},
onReady() {
this.$refs.form.setRules(this.rules)
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换label显示位置
labelPositionChange(event) {
switch (event.index) {
case 0:
this.labelPosition = 'left'
break
case 1:
this.labelPosition = 'top'
break
}
},
// 切换label对其方式
labelAlignChange(event) {
switch (event.index) {
case 0:
this.labelAlign = 'left'
break
case 1:
this.labelAlign = 'right'
break
case 2:
this.labelAlign = 'center'
break
}
},
// 切换边框显示
borderChange(event) {
this.border = event.index === 0 ? true : false
},
// 切换可选项样式
checkRadioStyleChange(event) {
switch (event.index) {
case 0:
this.checkboxWidth = 'auto'
this.checkboxWrap = false
this.radioWidth = 'auto'
this.radioWrap = false
break
case 1:
this.checkboxWidth = '50%'
this.checkboxWrap = false
this.radioWidth = '50%'
this.radioWrap = false
break
case 2:
this.checkboxWidth = 'auto'
this.checkboxWrap = true
this.radioWidth = 'auto'
this.radioWrap = true
break
}
},
// 切换错误提示方式
errorTypeChange(event) {
switch (event.index) {
case 0:
this.errorType = ['message']
break
case 1:
this.errorType = ['toast']
break
case 2:
this.errorType = ['border-bottom']
break
case 3:
this.errorType = ['border']
break
}
},
// 表单提交
submit() {
this.$refs.form.validate(valid => {
if (valid) {
// 验证通过
if (!this.model.agreement) {
this.$tn.message.toast('请勾选协议')
return
}
} else {
// 验证失败
}
})
},
// 点击actionSheet选择性别
actionSheetClick(index) {
uni.hideKeyboard()
this.model.sex = this.actionSheetList[index].text
},
// 点击地区选择器
regionPickerConfirm(event) {
this.model.region = event.province.label + '-' + event.city.label + '-' + event.area.label
},
// 点击商品类型列选择器
goodsTypeSelectConfirm(event) {
this.model.goodsType = `${event[0]['label']}`
},
// 多选项值改变事件
checkboxGroupChange(event) {
this.model.fruit = event
},
// 单选项值改变事件
radioGroupChange(event) {
this.model.payType = event
},
// 获取验证码
getCode() {
if (this.$refs.code.canGetCode) {
this.$tn.message.loading('正在获取验证码')
setTimeout(() => {
this.$tn.message.closeLoading()
this.$tn.message.toast('验证码已经发送')
// 通知组件开始计时
this.$refs.code.start()
}, 2000)
} else {
this.$tn.message.toast(this.$refs.code.secNum + '秒后再重试')
}
},
// 验证码倒计时时间改变
codeChange(text) {
this.codeTips = text
},
// 图片有修改
imageUploadChange(lists) {
this.model.photo = lists
},
// 同意协议状态修改
agreementCheckChange(event) {
this.model.agreement = event.value
}
}
}
</script>
<style lang="scss" scoped>
.agreement {
display: flex;
align-items: center;
margin: 40rpx 0;
&-text {
padding-left: 8rpx;
color: $tn-font-sub-color;
}
}
</style>