vue3 ts uniapp基本组件封装、通用组件库myCompont、瀑布流组件、城市选择组件、自定义导航栏、自定义底部菜单组件等

gitee地址
uniapp插件地址

本人封装了一个vue3 ts的uniapp通用组件,欢迎大家使用有任何问题可以去Q交流也可以去gitee上提,共同学习,完全免费

myCompont 组件说明

组件目录

复制代码
m-button 按钮
m-checkbox 多选组件
m-city-selector 城市选择
m-code 验证码
m-countdown 定时获取验证码
m-downlist 搜索框
m-form 表单组件
m-form-item 表单项组件
m-icon icon组件
m-images 图片组件
m-list 数据列表
m-loading 加载中
m-login 快捷登录
m-navbar 自定义导航
m-number-box 数字输入框
m-picker 选择弹出
m-popup 弹出框
m-rating 评分
m-skeleton 骨架
m-swiper 轮播图 m-swiper-item
m-tabbar 自定义底部菜单
m-toast 消息提示
m-uploadimg 图片上传组件
m-video 视频显示组件
m-waterfall 瀑布流组件

组件使用

m-button

按钮组件

复制代码
showText: {
	type: Boolean, // 是否显示按钮文字 
	default: true
},
type:{
	type: String,
	default: "text"},
fontSize: {
	type: String,
	default: "24rpx"
},
openType: {
	type: String, //调用小程序原生使用
	default: ""
},
btnStyle: {
	type: Object, //按钮样式
	default: () => ({})
},
color: {
	type: String, //文字颜色
	default: "#fff"
},
text: {
	type: String, //文本内容
	default: '确定'
},
click: {
	type: Function, //点击事件
	default: null
}


<m-button openType="share" @click="share" type="botton" :title="``" :btnStyle="style1">
    <view class="flex flex-column align-center" style="margin-top: 6rpx;" @click="share">
        <view class="flex align-center justify-center">
            <text class="iconfont icon-share"></text>
        </view>
            <view class="foaim">
                分享
            </view>
    </view>
</m-button>

m-checkbox

复选按钮

复制代码
 * @param activeColor 选中的背景颜色
   * @param inactiveColor 未选中的背景颜色
   * @param iconColor 图标颜色
   * @param direction 选择框和文本的布局方向
   * @param size 选择框的大小
   * @param gap 选择框和文本的间距
   * @param activeValue 选中的值
   * @param inactiveValue 未选中的值
   
   
   modelValue: any
shape?: 'circle' | 'square' | 'round'
direction?: 'left' | 'right' | 'top' | 'bottom'
size?: number
/** 选中的背景颜色 */
activeColor?: string
/** 未选中的时候颜色 border颜色 */
inactiveColor?: string
/** 图标颜色*/
iconColor?: string
gap?: number
/**自定义选中值*/
activeValue?: any // ✅ 自定义选中值
/** 自定义未选中值*/
inactiveValue?: any // ✅ 自定义未选中值

<m-checkbox
  :size="20"
  shape="circle"
  direction="left"
  :activeColor="'#4199FF'"
  :inactiveColor="'#666666'"
  :iconColor="'#fff'"
  @onchange="onchange($event, index)"
  v-model="item.checked"
>
</m-checkbox>

m-city-selector

城市选择 城市选择插件,城市数据在city.ts中,可以自行更新,选择城市后给父组件返回选中城市数据。支持城市搜索

复制代码
详情 https://ext.dcloud.net.cn/plugin?id=24847

m-code

输入验证码

复制代码
 /**
 * 双向绑定的值
 */
modelValue?: string | number
/**
 * 验证码长度
 * @default 4
 */
length?: number
/**
 * 输入框边框颜色(选中时)
 * @default '#9666FF'
 */
borderColor?: string
/**
 * 文字颜色
 * @default '#333'
 */
textColor?: string
/**
 * 文字大小,单位 rpx
 * @default 36
 */
textSize?: number | string
/**
 * 每个格子的宽高,单位 rpx
 * @default 90
 */
size?: number | string

m-countdown

获取手机验证码倒计时

复制代码
duration


<m-countdown ref="countdownRef" 
  :duration="60"
  @click="getCode"
  @start="onStart"
  @end="onEnd"></m-countdown>
  
  onStart 开始
  getCode 点击 获取验证码
  onEnd 结束

m-downlist

复制代码
items: Record<string, any>[] 数据类型
selectedId?: string | number | null 选择中的
valueKey?: string  数据的KEY
labelKey?: string lbae key字段
multiple?: boolean 是否多选

<m-downlist style="width: 100%" v-model:selectedId="formData.merchant_category_id" @search="searchStore"
			:items="adminStoreClassData" valueKey="merchant_category_id"
labelKey="category_name"></m-downlist>

m-form

表单组件

复制代码
<m-form ref="formRef" :rules="rules" :labelStyle="labelStyle" :model="formData">
	<view class="detail">
		<view class="itms">
			<m-form-item label="收货人" prop="real_name">
				<input v-model="formData.real_name" placeholder="收货人"></input>
			</m-form-item>
		</view>
		<view class="itms">
			<m-form-item label="联系手机" prop="phone">
				<input v-model="formData.phone" placeholder="联系手机"></input>
			</m-form-item>
		</view>
		<view class="itms">
			<m-form-item label="所在地区" prop="province">
				<view class="flex justify-space w" @click="selectAddress">
					<!-- <input disabled v-model="formData.real_name" placeholder-style="color:#C8C8C8;" placeholder="请输入店铺名称" /> -->
					<view style="width:400rpx;">
						<view v-if="!formData.province">
							请选择地区
						</view>
						<view v-else>
							<text>
								{{formData.province}}
							</text>
							<text>
								{{formData.city}}
							</text>
							<text>
								{{formData.district}}
							</text>
						</view>
					</view>
					<m-images :url='mapicon' width="28rpx" height="34rpx"></m-images>
				</view>
				<view>

				</view>
			</m-form-item>
		</view>
		<view class="itms">
			<m-form-item label="详细地址" prop="address_name">
				<input v-model="formData.address_name" placeholder="请输入详细地址"></input>
			</m-form-item>
		</view>


	</view>
	<!-- 设为默认地址 -->
	<view class="flex align-center"
		style="margin-top:20rpx;gap:6rpx;background:#fff;height: 122rpx;padding-left:68rpx">
		<m-checkbox :size="14" direction="left" :activeColor="'#4199FF'" :inactiveColor="'#666666'"
			:iconColor="'#fff'" :gap="0" :activeValue="1" :inactiveValue="0" shape="circle"
			v-model="formData.is_default" />
		<text style="color:#4199FF;">设为默认地址</text>
	</view>
</m-form>

表单验证
// 表单验证
const rules = ref({
	real_name: [
		{ required: true, message: '请输入收货人', trigger: 'blur' },
	],
	phone: [
		{ required: true, message: '请输入手机号码', trigger: 'blur' },
		{
			pattern: /^1[3-9]\d{9}$/,
			message: '手机号格式不正确',
			trigger: 'blur'
		}
	],
	province: [
		{ required: true, message: '请选择地区', trigger: 'blur' },
	],
	address_name: [
		{ required: true, message: '请输入详细地址', trigger: 'blur' },
	]


})
获取验证结果
const valid = await formRef.value.validate()

if (!valid.valid) {
  return toastRef.value.show('请将数据填写完整')
}

m-icon

icon组件

复制代码
<m-icon
  :size="midButton && item.midButton ? midButtonSize : iconSize"
  :name="elIconPath(index)"
  img-mode="scaleToFill"
  :color="elColor(index)"
  :custom-prefix="item.customIcon ? 'custom-icon' : 'uicon'"
/>

m-images

图片显示组件

复制代码
// 图片链接
url: {
  type: String,
  required: true
},
// 图片裁剪、缩放模式
mode: {
  type: String as PropType<ModeType>,
  default: 'scaleToFill'
},
// 宽度
width: {
  type: [String, Number],
  default: '100%'
},
// 高度
height: {
  type: [String, Number],
  default: '100%'
},
// loading图片大小
loadingSize: {
  type: [String, Number],
  default: '60rpx'
},
// 圆角 角度
rounded:{
	  type: [Number,String],
	  default: 0
},
// 是否开启点击后查看大图
showLarge:{
	  type:Boolean,
	  default:false
},
// 查看大图的数组
currImage:{
	  type: Array,
	  default: ()=>[]
}

     <m-images :url="serachUrl" width="40rpx" height="40rpx" />

m-list

m-loading

加载状态

复制代码
  status?: LoadStatus    /**'loading' | 'nodata' | 'getall' | 'loaded' 加载中 暂无数据 加载更多 加载完成 */
 <m-loading v-if="loading!='loaded'"  :status="loading"></m-loading>

m-login

其他登录方式

复制代码
<view>
	<m-login></m-login>

自定义导航栏

复制代码
backColor: { type: String, default: '#000019' }, // 返回图标颜色
background: { type: String, default: '' }, // 导航栏背景色
isFixed: { type: Boolean, default: true }, // 是否固定顶部
borderBottom: { type: Boolean, default: true }, // 是否显示底部边框
isBack: { type: [Boolean, String], default: true }, // 是否显示返回按钮
height: { type: [String, Number], default: '' }, // 导航栏高度(非小程序平台)
backText: { type: String, default: '' }, // 返回按钮文字
backTextStyle: { type: Object, default: () => ({ color: '#606266' }) }, // 返回文字样式
title: { type: String, default: '' }, // 标题文本
titleWidth: { type: [String, Number], default: '250' }, // 标题宽度
titleColor: { type: String, default: '#606266' }, // 标题颜色
immersive: { type: Boolean, default: false }, // 是否沉浸式
titleBold: { type: Boolean, default: false }, // 标题是否加粗
titleSize: { type: [String, Number], default: 32 }, // 标题字号
customBack: { type: Function, default: null } // 自定义返回事件



  <m-navbar :title="title" :isBack="true" :background="backgroundNav">
  <view class="ssetflex justify-space" style="width: 94%">
    <JointSearch
      ref="joinREf"
      v-model="searchKeyword"
      @clear="clear"
      labelKey="keyword"
      :showType="false"
      :background="`#F9F9F9`"
      @confirm="confirmInput"
    />
  </view>
</m-navbar>

m-number-box

数字输入框

复制代码
 modelValue: { type: [Number, String], default: 1 },
min: { type: [Number, String], default: 1 },
max: { type: [Number, String], default: 100 },
step: { type: [Number, String], default: 1 },
disabled: { type: Boolean, default: false },
showMinus: { type: Boolean, default: true },
showPlus: { type: Boolean, default: true },


 <m-number-box style="height: 100%;" :showMinus="false" :showPlus="false" :max="spectData?spectData.stock:`1`" v-model="inputValue"></m-number-box>

m-picker

下拉选择数据

复制代码
 modelValue: boolean
columns: PickerItem[]
defaultValue?: (string | number)[]
labelKey?: string 
valueKey?: string

 <m-picker v-model="qyShowSelect" :columns="configPay.bankAccountType" 
 @change="qyPickerChange" labelKey="name" 
  valueKey="type"></m-picker>

m-popup

弹出层

复制代码
	// 显示隐藏
	/** 显示隐藏*/
modelValue: { type: Boolean, default: false },
showmark: { type: Boolean, default: true },
bacground: { type: String, default: '#fff' },
title: { type: String, default: '' },
fontSize: { type: Number, default: 26 },
fontWeight: { type: Boolean, default: true },
showClose: { type: Boolean, default: false },
lineHeight: { type: Number, default: 30 },
zIndex: { type: Number, default: 11 },
closeIndex: { type: Number, default: 0 },
showTitle:{ type: Boolean, default: true },
 /** 圆角: 可以传字符串统一四个角,也可以传对象分别控制 */
  borderRadius: {
    type: [String, Object] as PropType<RadiusType>,
    default: '20rpx'
  },
type: {
  type: String as PropType<Direction>,
  default: 'bottom',
},


 <m-popup :zIndex="22" v-model="showSelectSpec" :showClose="true">
   <SelectSpec :productDetail="productData" @changeSku="changeSku"></SelectSpec>
</m-popup>

m-rating

评分

复制代码
modelValue: { type: Number, default: 0 }, // 当前评分(可小数)
max: { type: Number, default: 5 },        // 总星数
color: { type: String, default: "#FF7300" }, // 实心颜色
emptyColor: { type: String, default: "#e1e1e1" }, // 空心颜色

<m-rating v-model="item.service_score" color="#FFF05D" :max="5" />

m-skeleton

复制代码
 <m-skeleton v-if="loading" :rows="5" width="300rpx" height="400rpx"></m-skeleton>

m-swiper

轮播图

复制代码
* 轮播图组件
 * 支持视频和图片轮播
 * 轮播切换时视频暂停,视频播放时轮播暂停,视频结束后轮播恢复


<m-swiper :url="swiperData" width="750rpx" height="600rpx" ></m-swiper>

m-tabbar

自定义底部导航

复制代码
// 非凸起按钮未激活的图标,可以是uView内置图标名或自定义扩展图标库的图标
    // 或者png图标的【绝对路径】,建议尺寸为80px * 80px
    // 如果是中间凸起的按钮,只能使用图片,且建议为120px * 120px的png图片
    iconPath: "home",
    // 激活(选中)的图标,同上
    selectedIconPath: "home-fill",
    // 显示的提示文字
    text: "首页",
    // 红色角标显示的数字,如果需要移除角标,配置此参数为0即可
    count: 2,
    // 如果配置此值为true,那么角标将会以红点的形式显示
    isDot: true,
    // 如果使用自定义扩展的图标库字体,需配置此值为true
    // 自定义字体图标库教程:https://www.uviewui.com/guide/customIcon.html
    customIcon: false,
    // 如果是凸起按钮项,需配置此值为true
    midButton: false,
    // 点击某一个item时,跳转的路径,此路径必须是pagees.json中tabBar字段中定义的路径
    pagePath: "", // 1.5.6新增,路径需要以"/"开头
	
	定义 tabbar 场景,我们不建议在一个页面内通过几个组件,用v-if切换去模拟各个页面,而应该使用 uni-app 自带的 tabbar 系统,同时隐藏原生的 tabbar, 再引入自定导航栏,这样可以保证原有性能,同时又能自定义 tabbar,思路如下:
	
	在 pages.json 中正常定义 tabbar 逻辑和字段,只需配置tabBar字段list中的pagePath(需以"/"开头)属性即可
	在各个 tabbar 页面引入u-tabbar组件,组件会默认自动通过uni.hideTabBar()隐藏系统 tabbar
	通过vuex引用同一份 tabbar 组件的list参数,这样可以做到修改某一个页面的u-tabbar数据,其他页面的u-tabbar也能同步更新
	组件内部会自动处理各种跳转的逻辑,同时需要注意以下两点:
	要在list参数中配置pagePath路径,此路径为pages.json中定义的 tabbar 字段的路径
	此种方式,无需通过v-model绑定活动项,内部会自动进行判断和跳转
	
	代码
	let list = [
	  {
	    // 非凸起按钮未激活的图标,可以是uView内置图标名或自定义扩展图标库的图标
	    // 或者png图标的【绝对路径】,建议尺寸为80px * 80px
	    // 如果是中间凸起的按钮,只能使用图片,且建议为120px * 120px的png图片
	    iconPath: "home",
	    // 激活(选中)的图标,同上
	    selectedIconPath: "home-fill",
	    // 显示的提示文字
	    text: "首页",
	    // 红色角标显示的数字,如果需要移除角标,配置此参数为0即可
	    count: 2,
	    // 如果配置此值为true,那么角标将会以红点的形式显示
	    isDot: true,
	    // 如果使用自定义扩展的图标库字体,需配置此值为true
	    // 自定义字体图标库教程:https://www.uviewui.com/guide/customIcon.html
	    customIcon: false,
	    // 如果是凸起按钮项,需配置此值为true
	    midButton: false,
	    // 点击某一个item时,跳转的路径,此路径必须是pagees.json中tabBar字段中定义的路径
	    pagePath: "", // 1.5.6新增,路径需要以"/"开头
	  },
	];
	
	# 代码
	
	 <view>
	    <view class="u-page">
	      <!-- 所有内容的容器 -->
	    </view>
	    <!-- 与包裹页面所有内容的元素u-page同级,且在它的下方 -->
	    <u-tabbar v-model="current" :list="list" :mid-button="true"></u-tabbar>
	  </view>
	</template>
	
	<script>
	  export default {
	    data() {
	      return {
	        list: [
	          {
	            iconPath: "home",
	            selectedIconPath: "home-fill",
	            text: "首页",
	            count: 2,
	            isDot: true,
	            customIcon: false,
	          },
	          {
	            iconPath: "photo",
	            selectedIconPath: "photo-fill",
	            text: "放映厅",
	            customIcon: false,
	          },
	          {
	            iconPath: "https://cdn.uviewui.com/uview/common/min_button.png",
	            selectedIconPath: "https://cdn.uviewui.com/uview/common/min_button_select.png",
	            text: "发布",
	            midButton: true,
	            customIcon: false,
	          },
	          {
	            iconPath: "play-right",
	            selectedIconPath: "play-right-fill",
	            text: "直播",
	            customIcon: false,
	          },
	          {
	            iconPath: "account",
	            selectedIconPath: "account-fill",
	            text: "我的",
	            count: 23,
	            isDot: false,
	            customIcon: false,
	          },
	        ],
	        current: 0,
	      };
	    },
	  };

m-toast

消息提示

复制代码
      <m-toast ref="toastREf"></m-toast>
	  
	  const toastREf = ref<InstanceType<typeof MToast> | null>(null);
	    toastREf.value?.show("删除成功");

m-uploadimg

图片上传组件

复制代码
<m-uploadimg v-model="formData.licenceUrl" :defaultImage="businessUrl" :imgWidth="552"
  @defaultClick="defaultClickbase(1)" :imgHeight="396">
  <template #default="{ index, src }">
    <view @click.stop="upYbFile(1)" v-if="!formData.licenceUrl" class="addImgUp">
      点击上传
    </view>
  </template>
</m-uploadimg>

// 默认显示的营业执照
const businessUrl = ref(
  staticUrl + "/tx_user_sever_img/createStore/zhizhoa.png"
);
const defaultClickbase = (num:number) => {
 upYbFile(num)
};

m-watrfall

瀑布流组件

复制代码
 * @param value  瀑布流数据
 * @param addTime 插入数据的时间间隔
 * @param keyIdData / id值,用于清除某一条数据时,根据此idKey名称找到并移除

<m-waterfall :value="product" ref="commproduct">
	<!-- 左边数据 -->
	<template v-slot:left="{leftList}">
		<view @click="goodsDetail(item)" class="prodecutitem" v-for="(item,index) in leftList" :key="item.goodsId" >
			<view style="width: 100%;">
				<m-imgage  mode="widthFix" :url="statusUrl+item.showImage"></m-imgage>
			</view>
			<view class="textDertail">
				<view class="title">{{item.name}}</view>
				<!-- <view class="desc">{{item.title}}</view> -->
				<view class="descList">
					<text class="tej" v-for="(citem,cindex) in item.labelName.split(',')" :key="citem">{{citem}}</text>
					<!-- <text class="tej">特价</text>
					<text class="te24">24H发货</text> -->
				</view>
				<view class="numb1">
					<text class="fh">¥</text><text class="pay">{{item[leveKey]}}</text>/元
				</view>
				<view class="numb2">
					原价¥{{item.originalPrice}}/元
				</view>
			</view>
		</view>
	</template>
	<!-- 右边数据 -->
	<template v-slot:right="{rightList}">
		<view class="prodecutitem" v-for="(item,index) in rightList" :key="item.goodsId" @click="goodsDetail(item)">
			<view>
				<m-imgage  :url="statusUrl+item.showImage" mode="widthFix"></m-imgage>
			</view>
			<view class="textDertail">
				<view class="title">{{item.name}}</view>
				<!-- <view class="desc">{{item.title}}</view> -->
				<view class="descList" v-if="item.labelName">
					<text class="tej" v-for="(citem,cindex) in item.labelName.split(',')" :key="citem">{{citem}}</text>
					<!-- <text class="te24">24H发货</text> -->
				</view>
				<view class="numb1">
					<text class="fh">¥</text><text class="pay">{{item[leveKey]}}</text>/元
				</view>
				<view class="numb2">
					原价¥{{item.originalPrice}}/元
				</view>
			</view>
		</view>
	</template>
</m-waterfall>
相关推荐
阿提说说1 小时前
uniapp demo调试支付宝沙箱模式
uni-app·支付宝沙箱
Amy_yang1 小时前
UniApp Vue3 词云组件开发实战:从原理到应用
javascript·vue.js·uni-app
灵犀坠1 小时前
前端知识体系全景:从跨域到性能优化的核心要点解析
前端·javascript·vue.js·性能优化·uni-app·vue
yqcoder1 小时前
uni-app 之 uni.showToast
运维·服务器·uni-app
q_19132846951 小时前
基于SpringBoot+uniapp+vue.js的货物配送系统
java·vue.js·spring boot·后端·mysql·uni-app·毕业设计
渣波1 小时前
# TypeScript:给 JavaScript 穿上“防弹衣”的超能力语言
javascript·typescript
我叫张小白。1 小时前
Vue3 标签的 ref 属性:直接访问 DOM 和组件实例
前端·javascript·vue.js·typescript·vue3
2501_916008891 小时前
Python抓包HTTPS详解:Wireshark、Fiddler、Charles等工具使用教程
python·ios·小程序·https·uni-app·wireshark·iphone
刻刻帝的海角1 小时前
uniapp引入qqmap-wx-jssdk实现微信小程序端获取用户当前位置
微信小程序·小程序·uni-app