mirror of
https://gitee.com/TSpecific/tuniao-ui.git
synced 2026-03-07 08:14:01 +08:00
524 lines
17 KiB
Vue
524 lines
17 KiB
Vue
<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>
|