本文介绍了如何在后台管理系统中添加和展示商家信息,包括商家logo、名称、电话、地址和介绍等内容,并支持后期上传营业许可等文件。通过使用uni-app的uni-forms组件,可以方便地实现表单的创建、校验和管理操作。文章详细说明了组件的引入、页面结构的搭建、数据的绑定和验证规则的设置,并提供了具体的代码示例。通过这种方式,可以高效地管理和展示商家信息,同时确保数据的准确性和完整性。
如下图的,logo和名称都时后台商户的数据。

1、主要代码直观感受
1.1代码截图

2、实现准备
使用的组件时,可以使用的u-view的中的u-form的组件,其中有很多校验的功能,
可以参考:
我们这里实现使用uniapp自己的扩展组件,uni-forms来进行实现的。它里面也有很多校验。比如邮箱,性别、电话号码等等一系列的数据校验。就不需要再自己写正则来校验。不用自己再重复造轮子了。
3、具体实现
3.1 引入该组件
tip1:但是在uni-id的时,它全部给我们安装和引入了,我们就不用再安装和引入了。
tip2:我们开始写我们需要的代码,一般的加一些属性值,都会提示一些参考值,如果没有提示,一般都是自己代码哪里写错了。
3.2 页面基本格式
3.2.1、使用一个盒子包起来 view
3.2.2、写一个 uni-forms 注意 包含 ref 这是一个tag。他是代表这份表单
https://uniapp.dcloud.net.cn/component/uniui/uni-forms.html
ref 就是定义这个表单的标识
model:数据
rules:校验规则
label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpx
label-align 对齐方式
3.2.3、uni-forms-item 是表单中的一个标签 在标签中可添加 uni-file-picker ,uni-easyinput
uni-file-picker 可以上传文件
<uni-file-picker v-model="brandFormData.thumb" fileMediatype="image" mode="grid" :limit="1" />
格式我们这里写的是图片
v-model是一个双向绑定,一个是用于读取数据库显示,一个用来上传数据立即展示
3.2.4、button 可以放在uni-forms组件。
<button type="primary" @click="onSubmit">提交信息</button>
type是样式,click是一个动作
3.2.5、具体代码如下:
html
<template>
<view class="brand">
<!-- <uni-forms ref="brandRef" :model="brandFormData" :rules="brandRules" :label-width="100" label-align="right"> -->
<uni-forms ref="brandRef" :model="brandFormData" :label-width="100" label-align="right">
<!--
https://uniapp.dcloud.net.cn/component/uniui/uni-forms.html
ref 就是定义这个表单的标识
model:数据
rules:校验规则
label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpx
label-align 对齐方式
-->
<uni-forms-item label="品牌招牌" required name="thumb">
<uni-file-picker v-model="brandFormData.thumb" fileMediatype="image" mode="grid" :limit="1" />
</uni-forms-item>
<uni-forms-item label="品牌名称" name="name" required>
<!-- name 是标签名字 后面借来标识是哪一个被验证 required 是强制输入项目 必填-->
<uni-easyinput type="text" v-model="brandFormData.name" placeholder="请输入品牌名称" />
</uni-forms-item>
<uni-forms-item label="商户电话" name="mobile" required>
<uni-easyinput type="text" v-model="brandFormData.mobile" placeholder="请输入商户电话" />
</uni-forms-item>
<uni-forms-item label="商户地址" name="address" required>
<uni-easyinput v-model="brandFormData.address" placeholder="请输入商户地址" />
</uni-forms-item>
<uni-forms-item label="商家介绍" name="about">
<uni-easyinput v-model="brandFormData.about" placeholder="请输入商家介绍" type="textarea" />
</uni-forms-item>
<button type="primary" @click="onSubmit">提交信息</button>
<!-- type 按钮样式选择 -->
</uni-forms>
</view>
</template>
3.3 数据和验证
<uni-forms ref="brandRef" :model="brandFormData" :rules="brandRules" :label-width="100" label-align="right">
这一行是我们注释的代码,但是最开始就是这样,为什么要注释?接下来在说。
3.3.1 注意:
brandFormData是数据。
brandRules是验证规则。
label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpx
label-align 对齐方式
3.3.2 数据定义
html
brandFormData: {
thumb: [],
name: "", //品牌名称
mobile: "",
address: "",
about: ""
},
3.3.3 验证规则
这里主要包含几个规则,一个必填项目,需要在页面上写 required 在验证规则也要写
3.3.3.1 页面required
html
<uni-forms-item label="商户电话" name="mobile" required>
<uni-easyinput type="text" v-model="brandFormData.mobile" placeholder="请输入商户电话" />
</uni-forms-item>
3.3.3.2 规则中需要 required
javascript
mobile: {
rules: [{
required: true,
errorMessage: "请输入正确的手机号码"
}, {
validateFunction: function(rule, value, data, callback) {
let res = /^1[3-9]\d{9}$/.test(value);
if (!res) {
callback("手机格式不正确")
}
return;
}
}]
},
3.3.3.3 电话规则
电话的规则,没有只有自己写正则。按理说这个是应该有的。
具体代码见上面2.
其中需要的函数是:
validateFunction: function(rule, value, data, callback) {
let res = /^1[3-9]\d{9}$/.test(value);
if (!res) {
callback("手机格式不正确")
}
return;
}
3.3.3.4 详细验证规则
javascript
brandRules: {
thumb: {
rules: [{
required: true,
errorMessage: "品牌招聘需要上传"
}]
},
name: {
rules: [{
required: true,
errorMessage: "请输入正确的品牌名称"
}, {
minLength: 3,
maxLength: 20,
errorMessage: '长度在{minLength}到{maxLength}的字符'
}]
},
mobile: {
rules: [{
required: true,
errorMessage: "请输入正确的手机号码"
}, {
validateFunction: function(rule, value, data, callback) {
let res = /^1[3-9]\d{9}$/.test(value);
if (!res) {
callback("手机格式不正确")
}
return;
}
}]
},
address: {
rules: [{
required: true,
errorMessage: "请输入正确的商户地址"
}, {
minLength: 6,
maxLength: 100,
errorMessage: '长度在{minLength}到{maxLength}的字符'
}]
}
}
};
},
4、重点一般在最后 validateFunction使用
注意
- 需要注意,如果需要使用
validateFunction
自定义校验规则,则不能采用uni-forms
的rules
属性来配置校验规则,这时候需要通过ref
,在onReady
生命周期调用组件的setRules
方法绑定验证规则 - 无法通过props传递变量,是因为微信小程序会过滤掉对象中的方法,导致自定义验证规则无效。
- 如果使用了
validateFunction
且required
为false
的情况,表现为不填写内容不校验,有内容才校验,所以内容为空时validateFunction
不会执行
其实:该函数在h5 和web上可以正常运行
就是直接 按照普通写法,不用管注意事项。
4.1 普通写法
在forms 中就写上rules就好。如下普通写法,在web 和 H5 正常,但是在微信小程序就是不正常。
html
<template>
<view class="brand">
<uni-forms ref="brandRef" :model="brandFormData" :rules="brandRules" :label-width="100" label-align="right">
<!--
https://uniapp.dcloud.net.cn/component/uniui/uni-forms.html
ref 就是定义这个表单的标识
model:数据
rules:校验规则
label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpx
label-align 对齐方式
-->
<uni-forms-item label="品牌招牌" required name="thumb">
<uni-file-picker v-model="brandFormData.thumb" fileMediatype="image" mode="grid" :limit="1" />
</uni-forms-item>
<uni-forms-item label="品牌名称" name="name" required>
<!-- name 是标签名字 后面借来标识是哪一个被验证 required 是强制输入项目 必填-->
<uni-easyinput type="text" v-model="brandFormData.name" placeholder="请输入品牌名称" />
</uni-forms-item>
<uni-forms-item label="商户电话" name="mobile" required>
<uni-easyinput type="text" v-model="brandFormData.mobile" placeholder="请输入商户电话" />
</uni-forms-item>
<uni-forms-item label="商户地址" name="address">
<uni-easyinput v-model="brandFormData.address" placeholder="请输入商户地址" />
</uni-forms-item>
<uni-forms-item label="商家介绍" name="about">
<uni-easyinput v-model="brandFormData.about" placeholder="请输入商家介绍" type="textarea" />
</uni-forms-item>
<button type="primary" @click="onSubmit">提交信息</button>
<!-- type 按钮样式选择 -->
</uni-forms>
</view>
</template>
<script>
import {
mapMutations
} from "vuex"
const brandCloudObj = uniCloud.importObject("kt-mall-brand")
export default {
data() {
return {
brandFormData: {
thumb: [],
name: "", //品牌名称
mobile: "",
address: "",
about: ""
},
brandRules: {
thumb: {
rules: [{
required: true,
errorMessage: "品牌招聘需要上传"
}]
},
name: {
rules: [{
required: true,
errorMessage: "请输入正确的品牌名称"
}, {
minLength: 3,
maxLength: 20,
errorMessage: '长度在{minLength}到{maxLength}的字符'
}]
},
mobile: {
rules: [{
required: true,
errorMessage: "请输入正确的品牌电话"
}, {
validateFunction: function(rule, value, data, callback) {
let res = /^1[3-9]\d{9}$/.test(value);
if (!res) {
callback("手机格式不正确")
}
return;
}
}]
}
}
};
},
onLoad() {
this.isManage();
this.getBrand();
},
methods: {
...mapMutations(["SET_BRAND"]),
//获取数据库中的品牌信息
getBrand() {
brandCloudObj.get().then(res => {
if (!res.data.length) return;
this.brandFormData = res.data[0]
})
},
//点击提交按钮
onSubmit() {
this.$refs.brandRef.validate().then(res => {
let arr = this.brandFormData.thumb.map(item => {
return {
extname: item.extname,
url: item.url,
name: item.name,
size: item.size
}
})
this.brandFormData.thumb = arr;
this.addAndUpdate();
}).catch(err => {
console.log(err);
})
},
//新增或者修改品牌啊信息
async addAndUpdate() {
let title;
if (this.brandFormData._id) {
let res = await brandCloudObj.update(this.brandFormData)
title = "修改成功"
} else {
//新增
await brandCloudObj.add(this.brandFormData)
title = "新增成功"
}
uni.showToast({
title,
mask: true
})
setTimeout(() => {
uni.navigateBack();
}, 1500)
this.SET_BRAND(this.brandFormData);
}
}
}
</script>
<style lang="scss" scoped>
.brand {
padding: 30rpx;
//间距是30rpx, 每一个标签之 标签内部 需要label-width 来调整
}
</style>
4.2 修改后兼容写法
这给写好了,应该有人点赞,我简直不能太详细了。看到这里一般都是人才。
这也是前面3.3 我说的为什么要屏蔽掉普通写法的代码.
tmd普通写法就是不能兼容wx,需要删除rules,在onready中设置绑定rules就好了。
javascript
//这是日狗了,它大爷的
onReady() {
this.$nextTick(() => {
this.$refs.brandRef.setRules(this.brandRules);
});
},
4.2.1 具体代码:
html
<template>
<view class="brand">
<!-- <uni-forms ref="brandRef" :model="brandFormData" :rules="brandRules" :label-width="100" label-align="right"> -->
<uni-forms ref="brandRef" :model="brandFormData" :label-width="100" label-align="right">
<!--
https://uniapp.dcloud.net.cn/component/uniui/uni-forms.html
ref 就是定义这个表单的标识
model:数据
rules:校验规则
label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpx
label-align 对齐方式
-->
<uni-forms-item label="品牌招牌" required name="thumb">
<uni-file-picker v-model="brandFormData.thumb" fileMediatype="image" mode="grid" :limit="1" />
</uni-forms-item>
<uni-forms-item label="品牌名称" name="name" required>
<!-- name 是标签名字 后面借来标识是哪一个被验证 required 是强制输入项目 必填-->
<uni-easyinput type="text" v-model="brandFormData.name" placeholder="请输入品牌名称" />
</uni-forms-item>
<uni-forms-item label="商户电话" name="mobile" required>
<uni-easyinput type="text" v-model="brandFormData.mobile" placeholder="请输入商户电话" />
</uni-forms-item>
<uni-forms-item label="商户地址" name="address" required>
<uni-easyinput v-model="brandFormData.address" placeholder="请输入商户地址" />
</uni-forms-item>
<uni-forms-item label="商家介绍" name="about">
<uni-easyinput v-model="brandFormData.about" placeholder="请输入商家介绍" type="textarea" />
</uni-forms-item>
<button type="primary" @click="onSubmit">提交信息</button>
<!-- type 按钮样式选择 -->
</uni-forms>
</view>
</template>
<script>
import {
mapMutations
} from "vuex"
const brandCloudObj = uniCloud.importObject("kt-mall-brand")
export default {
data() {
return {
brandFormData: {
thumb: [],
name: "", //品牌名称
mobile: "",
address: "",
about: ""
},
brandRules: {
thumb: {
rules: [{
required: true,
errorMessage: "品牌招聘需要上传"
}]
},
name: {
rules: [{
required: true,
errorMessage: "请输入正确的品牌名称"
}, {
minLength: 3,
maxLength: 20,
errorMessage: '长度在{minLength}到{maxLength}的字符'
}]
},
mobile: {
rules: [{
required: true,
errorMessage: "请输入正确的手机号码"
}, {
validateFunction: function(rule, value, data, callback) {
let res = /^1[3-9]\d{9}$/.test(value);
if (!res) {
callback("手机格式不正确")
}
return;
}
}]
},
address: {
rules: [{
required: true,
errorMessage: "请输入正确的商户地址"
}, {
minLength: 6,
maxLength: 100,
errorMessage: '长度在{minLength}到{maxLength}的字符'
}]
}
}
};
},
onLoad() {
this.isManage();
this.getBrand();
},
//这是日狗了,它大爷的
onReady() {
this.$nextTick(() => {
this.$refs.brandRef.setRules(this.brandRules);
});
},
methods: {
...mapMutations(["SET_BRAND"]),
//获取数据库中的品牌信息
getBrand() {
brandCloudObj.get().then(res => {
if (!res.data.length) return;
this.brandFormData = res.data[0]
})
},
//点击提交按钮
onSubmit() {
this.$refs.brandRef.validate().then(res => {
let arr = this.brandFormData.thumb.map(item => {
return {
extname: item.extname,
url: item.url,
name: item.name,
size: item.size
}
})
this.brandFormData.thumb = arr;
this.addAndUpdate();
}).catch(err => {
// console.log(err);
})
},
//新增或者修改品牌啊信息
async addAndUpdate() {
let title;
if (this.brandFormData._id) {
let res = await brandCloudObj.update(this.brandFormData)
title = "修改成功"
} else {
//新增
await brandCloudObj.add(this.brandFormData)
title = "新增成功"
}
uni.showToast({
title,
mask: true
})
setTimeout(() => {
uni.navigateBack();
}, 1500)
this.SET_BRAND(this.brandFormData);
}
}
}
</script>
<style lang="scss" scoped>
.brand {
padding: 30rpx;
//间距是30rpx, 每一个标签之 标签内部 需要label-width 来调整
}
</style>