开发uniapp前端通用价格组件提交到DCloud插件市场

需求描述

如果你开发商城类项目,必定会显示价格,如果想让价格显示的具有突出并且有美感,如下图所示,很显然是需要花费一些工夫的,我在开发商城的时候客户端、后台管理都需要展示价格,每天都要花费一些时间调整,所以我就开发了一个价格组件,将价格显示的样式放到插件市场,如果需要显示价格的时候,导入进来修改一下属性就能使用了。

上面显示的价格样式,在这篇文章"自定义价格尾数"讲过,如果使用css完整价格尾数的显示。

下面我们就通过上面的需求,开发一款可以给uniapp项目是使用的价格组件,介绍一下如何开发DCloud插件市场的插件。

📺综合商城实战项目: unipay支付微信小程序商城开发Vue3完整版

一、新建uni_modules插件

1.在根目录下"uni_modules"单击右键,"新建uni_modules插件"

2.为插件创建一个名称,前面最好加一个你的专属前缀,我的昵称是"咸虾米",所以我的所有插件都用了xxm作为了前缀,就好比element-plus用的所有组件前缀都是el-类似,前缀后面的单词最好能准确表达创建的意思,方便别人检索你的插件。

然后,选择你开发的插件分类,我开发的这个插件是通用组件,所以选择第一个。

3.插件目录结构如下:

  • components内的xxm-price.vue是你要写的组件
  • changelog.md 是更新日志,这个不需要编写,提交时候会自动更新
  • package.json 是插件的配置项,如插件说明及相关依赖等
  • readme.md 是插件的使用说明,会在插件市场详情页展示的文档

二、开发插件

如上目录所示,我们要想实现一个功能,核心代码是需要编写在xxm-price.vue文件中的。

这个就是一个普通的vue文件,如果你会写vue这个页面没什么要给介绍的,重点是需要接收一下父组件传递过来的属性,在当前组件中进行处理。

下面这个代码是完整的实现逻辑,可以作为参考,当然你开发自己的组件的话就编写自己的代码就可以了。

这个实现代码中,很多地方让AI给实现的,所以用AI辅助开发还是很方便的,甚至一行代码都不需要写,直接用自然语言描述,就可以生成一个你所需要的功能组件了。

javascript 复制代码
<script setup>
import { ref, computed } from 'vue';

const props = defineProps({
	price: {
		type: Number,
		default: 999
	},
	symbol: {
		type: String,
		default: '¥'
	},
	size: {
		type: Number,
		default: 20
	},
	smallSize: {
		type: Number,
		default: undefined
	},
	color: {
		type: String,
		default: '#FF0F23'
	},
	origPrice: {
		type: Number,
		default: 0
	},
	origColor: {
		type: String,
		default: '#999'
	},
	origAlign: {
		type: String,
		default: 'right',
		validator: (val) => ['left', 'right', 'top', 'bottom'].includes(val) // 限制可选值
	}
});

const comFontSize = computed(() => {
	// 如果传递了smallSize则使用,否则用size*0.618
	return props.smallSize ?? props.size * 0.618;
});

// 计算flex-direction方向
const flexDirection = computed(() => {
	// left/right → row;top/bottom → column
	return ['left', 'right'].includes(props.origAlign) ? 'row' : 'column';
});

// 计算align-items值
const alignItems = computed(() => {
	// top/bottom → flex-start;left/right → flex-end
	return ['top', 'bottom'].includes(props.origAlign) ? 'flex-start' : 'flex-end';
});

// 计算原价是否需要调整order
const isOrigPriceFirst = computed(() => {
	// top/left → order:-1
	return ['top', 'left'].includes(props.origAlign);
});

function formatPrice(num, option = 0) {
	// 第一步:校验num是否为有效数字
	if (typeof num !== 'number' || isNaN(num)) {
		return '无效的数字,第一个参数必须是有效数字';
	}

	// 提取公共计算逻辑:num/100(处理精度误差)
	const baseValue = (num + Number.EPSILON) / 100;

	// 根据option分支处理
	if (option === 0) {
		// 取百位及以上整数(向下取整)
		return Math.floor(baseValue);
	} else if (option === 1) {
		// 取小数点后两位(格式化为.xx形式的字符串)
		// 先保留两位小数,再截取小数部分
		const fixedValue = Math.round(baseValue * 100) / 100; // 精准保留两位小数
		const [, decimalPart = '00'] = fixedValue.toString().split('.');
		return `.${decimalPart.padEnd(2, '0').slice(0, 2)}`;
	} else {
		// 非0/1选项:返回num/100并保留两位小数(数字类型)
		return Math.round(baseValue * 100) / 100;
	}
}
</script>

<template>
	<view
		class="price-wrap"
		:style="{
			'--flex-direction': flexDirection,
			'--align-items': alignItems
		}">
		<view
			class="price"
			:style="{ '--symbol': `'${symbol}'`, '--size': `${size}px`, '--color': `${color}`, '--com-size': `${comFontSize}px` }"
			:data-suffix="formatPrice(price, 1)">
			{{ formatPrice(price, 0) }}
		</view>
		<view class="origPrice" v-if="origPrice > 0" :style="{ '--orig-color': origColor, '--com-size': `${comFontSize}px`, '--order': isOrigPriceFirst ? '-1' : 'initial' }">
			{{ formatPrice(origPrice, -1) }}
		</view>
	</view>
</template>

<style lang="scss" scoped>
.price-wrap {
	display: flex;
	align-items: flex-start;
	align-items: var(--align-items);
	flex-direction: var(--flex-direction); // 动态控制布局方向
	line-height: 1em;
	gap: 5px;
	.price {
		color: var(--color);
		font-size: var(--size);
		font-weight: bold;
		&::before {
			font-size: var(--com-size);
			content: var(--symbol);
		}
		&::after {
			font-size: var(--com-size);
			content: attr(data-suffix);
		}
	}
	.origPrice {
		text-decoration: line-through;
		color: var(--orig-color);
		font-size: var(--com-size);
		order: var(--order); // 动态控制排序
	}
}
</style>

三、提交插件

如果你的功能组件已经开发完毕了,那么就需要将该组件提交到插件市场了,那么给大家介绍一下如何操作。

发布到插件市场

在插件文件夹上单击右键,选择"发布到插件市场",会出现插件描述的弹窗,可以在弹窗内填写插件的相关信息,也可以在"package.json"文件中填写,在package.json填写过的话,选择发布的时候再弹窗中也会展示你填写的内容,弹窗编写的内容只有提交后才会写入到package.json文件中。

不知道上面这些怎么填写?我以官方的uni-icons组件为例,告诉大家对应关系。

  • 一定要注意将开发的组件选择适合的分类
  • 插件显示名称、描述、标签一定要清晰明了,让别人看标题就知道是干什么的插件
  • 插件ID是唯一的,所以最后前面加上你的个性标识,如el-、uni-、uv-等

其他配置大家就按照要求填写就可以了,如果没有问题就可以点击提交,就会发布到DCloud的插件市场了。

先发布的插件,会展示在插件市场的首页,插件市场是按照插件更新时间排序的,如果想要给插件增加多一些曝光度,经常更新插件是一个好的办法。

这样插件就发布成功了,插件地址:https://ext.dcloud.net.cn/plugin?name=xxm-price

在本插件的详情页可以看到对插件使用说明的介绍,这是因为我们在插件文件夹下的"readme.md"进行了编写,你可以将详细的使用文档进行编写,有利于让别人更好的入手你的插件。

四、应用插件

提交发布插件后,在DCloud插件市场就可以找到我们发布的插件了,和使用官方扩展组件一样,选择右上角的"下载插件并导入HBuilderX",这样就会将该插件下载到你项目的"uni_modules"目录中,和使用自定义的组件一样使用即可。

在项目中使用

在任意的vue文件中,可以使用该插件,无需import导入价格插件,直接在页面中使用插件名称,便可展示价格样式了,在插件说明文档中有组件属性的说明,也可以参考下面代码来使用。

javascript 复制代码
<template>
	<view class="layout">
		<view class="row">
			<view class="title">基础样式:</view>
			<xxm-price></xxm-price>
		</view>
		<view class="row">
			<view class="title">设置组件大小:</view>
			<xxm-price :size="26"></xxm-price>
		</view>

		<view class="row">
			<view class="title">前缀货币符号:</view>
			<xxm-price :size="26" symbol="$"></xxm-price>
		</view>

		<view class="row">
			<view class="title">显示原价和现价:</view>
			<xxm-price :size="26" :price="36987" :origPrice="400355"></xxm-price>
		</view>

		<view class="row">
			<view class="title">设置小字尺寸:</view>
			<xxm-price :size="26" :price="36987" :origPrice="400355" :smallSize="12"></xxm-price>
		</view>

		<view class="row">
			<view class="title">设置原价和现价颜色:</view>
			<xxm-price :size="26" :price="36987" :origPrice="400355" color="#E6A23C" origColor="green"></xxm-price>
		</view>

		<view class="row">
			<view class="title">设置原价显示位置:</view>
			<xxm-price :size="26" :price="36987" :origPrice="400355" origAlign="bottom"></xxm-price>
		</view>
	</view>
</template>
相关推荐
郑州光合科技余经理2 小时前
实战分享:如何构建东南亚高并发跑腿配送系统
java·开发语言·javascript·spring cloud·uni-app·c#·php
2501_916007472 小时前
iOS与Android符号还原服务统一重构实践总结
android·ios·小程序·重构·uni-app·iphone·webview
嘿siri3 小时前
uniapp enter回车键不触发消息发送,已解决
前端·前端框架·uni-app·vue
00后程序员张4 小时前
fastlane 结合 appuploader 命令行实现跨平台上传发布 iOS App
android·ios·小程序·https·uni-app·iphone·webview
2501_915106325 小时前
iOS 性能优化这件事,结合多工具分析运行期性能问题
android·ios·性能优化·小程序·uni-app·cocoa·iphone
嘿siri5 小时前
自定义app端、小程序端和H5等多端自定义键盘输入框,跟随系统键盘弹出和隐藏
javascript·小程序·uni-app·uniapp
游戏开发爱好者85 小时前
App Store 上架流程,结合多工具协作
android·ios·小程序·https·uni-app·iphone·webview
cesske5 小时前
如何在yii2的uniapp项目中处理提交重复问题?
uni-app·状态模式
茶憶6 小时前
UniApp 安卓端实现文件的生成,写入,获取文件大小以及压缩功能
android·javascript·vue.js·uni-app