uniapp-商城-50-后台 商家信息
本文介绍了如何在后台管理系统中添加和展示商家信息,包括商家logo、名称、电话、地址和介绍等内容,并支持后期上传营业许可等文件。通过使用uni-app的uni-forms组件,可以方便地实现表单的创建、校验和管理操作。文章详细说明了组件的引入、页面结构的搭建、数据的绑定和验证规则的设置,并提供了具体的代码示例。通过这种方式,可以高效地管理和展示商家信息,同时确保数据的准确性和完整性。
如下图的,logo和名称都时后台商户的数据。
1、主要代码直观感受
1.1代码截图
2、实现准备
使用的组件时,可以使用的u-view的中的u-form的组件,其中有很多校验的功能,
可以参考:
Form 表单 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架uView UI,是 uni-app 生态最优秀的 UI 框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水https://uviewui.com/components/form.html
我们这里实现使用uniapp自己的扩展组件,uni-forms来进行实现的。它里面也有很多校验。比如邮箱,性别、电话号码等等一系列的数据校验。就不需要再自己写正则来校验。不用自己再重复造轮子了。
uni-app官网uni-app,uniCloud,serverless,介绍,基本用法,对齐方式,表单校验,如何使用,校验规则说明,rules 属性说明,validateFunction 自定义校验规则使用说明,validateFunction 异步校验,动态表单校验,表单校验时机说明,API,Forms Prophttps://uniapp.dcloud.net.cn/component/uniui/uni-forms.html
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、具体代码如下:
<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.htmlref 就是定义这个表单的标识 model:数据rules:校验规则label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpxlabel-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 数据定义
brandFormData: {thumb: [],name: "", //品牌名称mobile: "",address: "",about: ""},
3.3.3 验证规则
这里主要包含几个规则,一个必填项目,需要在页面上写 required 在验证规则也要写
3.3.3.1 页面required
<uni-forms-item label="商户电话" name="mobile" required><uni-easyinput type="text" v-model="brandFormData.mobile" placeholder="请输入商户电话" />
</uni-forms-item>
3.3.3.2 规则中需要 required
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 详细验证规则
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 正常,但是在微信小程序就是不正常。
<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.htmlref 就是定义这个表单的标识 model:数据rules:校验规则label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpxlabel-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就好了。
//这是日狗了,它大爷的onReady() {this.$nextTick(() => {this.$refs.brandRef.setRules(this.brandRules);});},
4.2.1 具体代码:
<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.htmlref 就是定义这个表单的标识 model:数据rules:校验规则label-width 加冒号绑定就数字,不加冒号就要写成100px,不能rpxlabel-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>