编写目的

本文说明基于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;
		}
	}

展示效果

     

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐