当前位置: 首页 > news >正文

自定义uniapp组件,以picker组件为例

编写目的

本文说明基于vue3定义uniapp组件的关键点:

1、一般定义在components文件夹创建组件,组件与页面已经没有明确的语法格式区别,所以可以与页面的语法保持一致 ;

2、组件定义后使用该组件的页面不需要引用组件即可使用;

3、1级选项利用modelValue属性实现双向绑定,2级选项使用回调函数实现数据回传;

组件源码

在components文件夹下新建vol-picker文件夹,文件夹下新建vol-picker.vue,代码如下: 

<template>
	<up-picker :show="show" :defaultIndex="defaultIndex" ref="uPickerRef" :loading="pickerLoading"
		:closeOnClickOverlay="true" :columns="datas" keyName="label" @confirm="confirm"
		@change="changeHandler"></up-picker>

	<up-input v-model="content.label" border="bottom" :readonly="true" :placement="placement">
		<template #suffix>
			<up-button @click="show = true" type="default" size="mini">
				<up-icon name="arrow-right"></up-icon>
			</up-button>
		</template>
	</up-input>

</template>

<script setup>
	import {ref,reactive,onMounted,defineEmits} from 'vue';

	const uPickerRef = ref(null);

	//选择框是否显示
	const show = ref(false);
	const pickerLoading = ref(false);

	//默认值
	const defaultIndex = ref([0]);

	//选择到的值
	const content = ref({
		label: "",
		name: ""
	});

	onMounted(() => {
		//设置默认值
		if (props.modelValue) {
			//2级
			if (props.datas.length == 2) {

				//查找1级数组索引
				let level1Index = props.datas[0].findIndex(f => f.list.some(s => s.id == props.modelValue));
				if (level1Index > -1) {
					//查找2级数组索引
					let level2Index = props.datas[0][level1Index].list.findIndex(f => f.id == props.modelValue);
					defaultIndex.value = [level1Index, level2Index];
				}
				content.value = props.datas[0][level1Index];
				//设置二级数组
				uPickerRef.value.setColumnValues(1, content.value.list);
			}
			//1级
			else {
				let oldVal = props.datas[0].find(f => f.id == props.modelValue);
				if (oldVal) {

					content.value = oldVal;
					let levle1 = props.datas[0].findIndex(f => f.id == props.modelValue);
					defaultIndex.value = [levle1]
				}
			}
		}

	});

	const props = defineProps({
		modelValue: {
			type: String,
			default: '' //
		},
		
		datas: {
			type: Array,
			default: () => {
				return [
					[] 
				]
			}
		},
		placement: {
			type: String,
			default: ''
		},
		readonly: { //默认是否只读
			type: Boolean,
			default: false
		}

	})
	const emit = defineEmits(['update', 'updateValue']);

	function changeHandler(e) {

		const {
			columnIndex, //列的索引
			value, //是一个数组[]
			values, // values为当前变化列的数组内容
			index // 选值元素的索引
		} = e
		//console.log(e, index)
		// 当第一列值发生变化时,变化第二列(后一列)对应的选项
		if (props.datas.length == 2) {
			//  变更第2列对应的选项
			uPickerRef.value.setColumnValues(1, value[0].list)
		}
	};
	// 回调参数包含columnIndex、value、values
	function confirm(e) {
		// console.log(e)
		//两级选值
		if (props.datas.length == 2) {
			content.value = e.value[1];
			emit("updateValue", e.value);
		}
		 //只有一级选择
		 else {
			content.value = e.value[0];
			 emit("update:modelValue", e.value[0].id);
            //当只有一级选项时,请根据需要 执行回调函数
            //emit("updateValue", e.value);
		}

		// console.log(content.value)
		show.value = false
	}

</script>

使用演示

<vol-picker>是组件文件名称。

<template>

	<vol-picker v-model="formData.Gender" 
:datas="countrys" 
@updateValue="fun_updateValue"
placement="选择">

</template>

<script setup>
	import {ref,reactive,watch,defineProps,defineEmits,defineExpose,getCurrentInstance} from 'vue';

	//示例1:1级选项
	const countrys = reactive([
		[
			{label: '业主',id: "1"},
			{label: '租客',id: "2"},
		]
	])

	//示例2:2级选项
	const countrys = reactive([
		[
			{label: '业主',id: "1",list: [{label: '业主3',id: "3"}, {label: '业主4',id: "4"}]},
			{label: '租客',id: "2",list: [{label: '租客5',id: "5"}, {label: '租客6',id: "6"}]},
		]
		,[]
	])

	const emit = defineEmits(['input,updateValue']);
  

	let formData = reactive({
       Gender: "2"
    });

	//picker回调
	const fun_updateValue = (values) => {
		//2级选项的回调,二级选项时可能展示的数据格式需要不同,因此不使用modelValue 通过回调函数返回选择的值
		if(countrys.length==2){
		    formData.Gender=values[1].id;
		}else{
           //1级选项 时  根据需要回调 ,组件暂时不回调,已通过modelValue实现双向绑定
			//formData.Gender=values[0].id;
		}
	}

展示效果

     

相关文章:

  • SpringBoot第三站:配置嵌入式服务器使用外置的Servlet容器
  • SQL注入第7关
  • DNS主从服务器
  • 【第K小数——可持久化权值线段树】
  • IIS 服务器日志和性能监控
  • 蓝桥杯嵌入式赛道复习笔记2(按键控制LED灯,双击按键,单击按键,长按按键)
  • element-plus中Popconfirm气泡确认框组件的使用
  • 基于 Docker 和 Flask 构建高并发微服务架构
  • UnitTest框架管理测试用例——python自动化测试
  • Golang学习笔记_49——解释器模式
  • mysql-查看binlog日志
  • 基于SpringBoot+Vue的幼儿园管理系统+LW示例参考
  • GPU视频编解码:Jetson VPI+multimedia_api视频编解码入门(一)
  • Effective C++ 剖析(条款1~9)
  • 【软件工程】03_软件需求分析
  • 速通大厂测开
  • 介绍如何使用Python构建引文网络,并计算结构洞指标
  • 深入解析 `SQL_SMALL_RESULT`:MySQL 的“小优化”大作用
  • 【unity实战】用unity封装一个复杂全面且带不同射击模式的飞机大战射击系统
  • Navicat 17.2 正式发布 | AI 助手、支持 Snowflake...超多新功能等你解锁
  • 中国海油总裁:低油价短期影响利润,但也催生资产并购机会
  • 4月人文社科联合书单|天文学家的椅子
  • 海尔·2025青岛马拉松两选手被终身禁赛:违规转让号码、穿戴他人号码
  • 专访丨青年作家杜梨:以动物的视角去观察这个世界
  • 老凤祥一季度净利减少两成,去年珠宝首饰营收下滑19%
  • 四川省社科联期刊:不建议在读硕士、博士将导师挂名为第一作者