vue3.0中封装组件,单选或多选

1,使用组件
<template>
	<div class="home-container layout-pd">
		<div id="headers">
			<el-button size="default" type="primary" class="ml10" @click="onOpenAddMenu('add')">
				<el-icon>
					<ele-FolderAdd />
				</el-icon>
				选择
			</el-button>
		</div>
		<el-table 
			:data="state.tableData.data" 
			v-loading="state.tableData.loading" 
			style="width: 100%;margin-top: 10px;"
			border>
			<el-table-column label="序号" type="index" width="70" align="center" show-overflow-tooltip></el-table-column>
			<el-table-column prop="name" label="天气" align="center" show-overflow-tooltip></el-table-column>
			<el-table-column label="温度" align="center" show-overflow-tooltip>
				<template #default="scope">
					<span>{{ scope.row.num }}</span>
				</template>
			</el-table-column>
		</el-table>
		<!-- 2,使用 -->
		<List ref="listRef"  :isCheckBox='true' @handleData="handleDataRes"></List>
	</div>
</template>

<script setup lang="ts" name="index">
import { defineAsyncComponent, ref, onMounted, reactive } from 'vue';
	//1,引入组件
	const List = defineAsyncComponent(() => import('./list.vue'));

	//子组件ref
	const listRef = ref();

	//声明变量
	const state = reactive({
		tableData: {
			data: [
				{name:'晴天',num:'34°C'},
				{name:'晴天',num:'30°C'},
				{name:'多云',num:'28°C'}
			],
			loading: false,
		},
	});

	//自定义方法,得到子组件传来的数据
	const handleDataRes = (list:[]) => {
		state.tableData.data = (state.tableData.data).concat(list)
	};
	const onOpenAddMenu = (type: string) => {
		listRef.value.openDialog(type);    //调用子组件的方法
	};
	// 页面加载时
	onMounted(() => {});
</script>
<style scoped lang="scss"></style>

2,封装组件
<!-- 列表组件 -->
<template>
	<div class="system-menu-dialog-container">
		<el-dialog :title="state.dialog.title" :close-on-click-modal="false" v-model="state.dialog.isShowDialog" width="769px">
			<div id="headers">
				<el-button 
					size="default" 
					type="primary" 
					class="ml10" 
					@click="handleSelectedClick"
					:disabled="state.tableData.selections.length == 0" 
					v-if='isCheckBox'>
						确认选中
				</el-button>
			</div>
			<el-table 
				ref="tableRef"
				:data="state.tableData.data" 
				v-loading="state.tableData.loading" 
				style="width: 100%;margin-top: 10px;"
				border
				@selection-change="handleSelectionChange"
				@row-dblclick='dbRowClick'>
					<el-table-column type="selection" width="55" align="center" v-if="isCheckBox"/>
					<el-table-column label="序号" type="index" width="70" align="center" show-overflow-tooltip></el-table-column>
					<el-table-column prop="name" label="天气" align="center" show-overflow-tooltip></el-table-column>
					<el-table-column label="温度" align="center" show-overflow-tooltip>
						<template #default="scope">
							<span>{{ scope.row.num }}</span>
						</template>
					</el-table-column>
			</el-table>
		</el-dialog>	
	</div>
</template>

<script setup lang="ts" name="list">
import {reactive,ref, onMounted} from 'vue';

	// 定义父组件传过来的值
	const props = defineProps({

		//是否多选,默认单选
		isCheckBox: { 
			type: Boolean,
			default: () => false,
		}
	});

	//声明表格ref
	const tableRef = ref();

	const state = reactive({
		tableData: {
			data: [
				{name:'晴天(组件)',num:'31°C'},
				{name:'晴天(组件)',num:'29°C'},
				{name:'多云(组件)',num:'27°C'}
			],
			loading: false,
			selections:[]
		},
		dialog: {
			isShowDialog: false,
			type: '',
			title: '',
		},
		
	});

	// 定义子组件向父组件传值/事件
	const emit = defineEmits(['handleData']);

	// 打开弹窗
	const openDialog = (type: string) => {
		state.dialog.title = '列表组件';
		state.dialog.type = type;
		state.dialog.isShowDialog = true;
	};

	const closeDialog = () => {
		state.dialog.isShowDialog = false;
	};

	const handleSelectionChange = (selection:[])=>{
		state.tableData.selections = selection;
	}

	const dbRowClick =(row:Object) =>{
		let list = [];
		list.push(row);
		if (props.isCheckBox) {   //1,注意:props.isCheckBox
			row.selected = !row.selected;
			if (row.selected) {
				if (!state.tableData.selections.includes(row)) state.tableData.selections.push(row);
			} else {
				state.tableData.selections.map((item, index) => {
					if (item == row) state.tableData.selections.splice(index, 1);
				})
			}
			//是否回显  2,注意:先声明ref,再使用tableRef.value
			tableRef.value.toggleRowSelection(row, row.selected);
		} else{
			closeDialog();
			emit('handleData',list);
		} 
	}

	const handleSelectedClick =()=>{
		closeDialog(); 
		emit('handleData',state.tableData.selections);
	}

	// 页面加载时
	onMounted(() => {
		state.tableData.data.map(item => item.selected = false)
	});

	// 暴露变量
	defineExpose({
		openDialog,
	});
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值