|
<template> |
|
<div class="table-generator"> |
|
<div class="title"> |
|
<div class="lef">表格 {{endCell.length ? `${endCell[0]} x ${endCell[1]}` : ''}}</div> |
|
<div class="right" @click="isCustom = !isCustom">{{ isCustom ? '返回' : '自定义'}}</div> |
|
</div> |
|
<table |
|
@mouseleave="endCell = []" |
|
@click="handleClickTable()" |
|
v-if="!isCustom" |
|
> |
|
<tbody> |
|
<tr v-for="row in 10" :key="row"> |
|
<td |
|
@mouseenter="endCell = [row, col]" |
|
v-for="col in 10" :key="col" |
|
> |
|
<div |
|
class="cell" |
|
:class="{ 'active': endCell.length && row <= endCell[0] && col <= endCell[1] }" |
|
></div> |
|
</td> |
|
</tr> |
|
</tbody> |
|
</table> |
|
|
|
<div class="custom" v-else> |
|
<div class="row"> |
|
<div class="label" style="width: 25%;">行数:</div> |
|
<NumberInput |
|
:min="1" |
|
:max="20" |
|
v-model:value="customRow" |
|
style="width: 75%;" |
|
/> |
|
</div> |
|
<div class="row"> |
|
<div class="label" style="width: 25%;">列数:</div> |
|
<NumberInput |
|
:min="1" |
|
:max="20" |
|
v-model:value="customCol" |
|
style="width: 75%;" |
|
/> |
|
</div> |
|
<div class="btns"> |
|
<Button class="btn" @click="close()">取消</Button> |
|
<Button class="btn" type="primary" @click="insertCustomTable()">确认</Button> |
|
</div> |
|
</div> |
|
</div> |
|
</template> |
|
|
|
<script lang="ts" setup> |
|
import { ref } from 'vue' |
|
import message from '@/utils/message' |
|
import Button from '@/components/Button.vue' |
|
import NumberInput from '@/components/NumberInput.vue' |
|
|
|
interface InsertData { |
|
row: number |
|
col: number |
|
} |
|
|
|
const emit = defineEmits<{ |
|
(event: 'insert', payload: InsertData): void |
|
(event: 'close'): void |
|
}>() |
|
|
|
const endCell = ref<number[]>([]) |
|
const customRow = ref(3) |
|
const customCol = ref(3) |
|
const isCustom = ref(false) |
|
|
|
const handleClickTable = () => { |
|
if (!endCell.value.length) return |
|
const [row, col] = endCell.value |
|
emit('insert', { row, col }) |
|
} |
|
|
|
const insertCustomTable = () => { |
|
if (customRow.value < 1 || customRow.value > 20) return message.warning('行数/列数必须在0~20之间!') |
|
if (customCol.value < 1 || customCol.value > 20) return message.warning('行数/列数必须在0~20之间!') |
|
emit('insert', { row: customRow.value, col: customCol.value }) |
|
isCustom.value = false |
|
} |
|
|
|
const close = () => { |
|
emit('close') |
|
isCustom.value = false |
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.table-generator { |
|
width: 100%; |
|
margin-top: -10px; |
|
} |
|
.title { |
|
height: 28px; |
|
line-height: 28px; |
|
background-color: $lightGray; |
|
margin: 0 -10px 10px -10px; |
|
padding: 0 14px; |
|
font-size: 12px; |
|
display: flex; |
|
justify-content: space-between; |
|
border-top-left-radius: $borderRadius; |
|
border-top-right-radius: $borderRadius; |
|
user-select: none; |
|
|
|
.right { |
|
cursor: pointer; |
|
|
|
&:hover { |
|
color: $themeColor; |
|
} |
|
} |
|
} |
|
table { |
|
border-collapse: separate; |
|
} |
|
td { |
|
width: 23px; |
|
height: 23px; |
|
line-height: 23px; |
|
border: 2px solid #fff; |
|
background-color: #f7f7f7; |
|
} |
|
.cell { |
|
width: 100%; |
|
height: 100%; |
|
border: 1px solid #dcdcdc; |
|
|
|
&.active { |
|
background-color: rgba($color: $themeColor, $alpha: .1); |
|
border-color: $themeColor; |
|
} |
|
} |
|
|
|
.custom { |
|
width: 230px; |
|
|
|
.row { |
|
display: flex; |
|
align-items: center; |
|
|
|
& + .row { |
|
margin-top: 10px; |
|
} |
|
} |
|
} |
|
|
|
.btns { |
|
margin-top: 10px; |
|
text-align: right; |
|
|
|
.btn { |
|
margin-left: 10px; |
|
} |
|
} |
|
</style> |