fix: 表格单元格内无法输入空格和换行

This commit is contained in:
pipipi-pikachu 2021-06-06 11:16:40 +08:00
parent 85ce023845
commit 87c9a2996e
4 changed files with 24 additions and 15 deletions

View File

@ -16,7 +16,7 @@ import { defineComponent, onUnmounted, ref, watch } from 'vue'
export default defineComponent({ export default defineComponent({
name: 'custom-textarea', name: 'custom-textarea',
props: { props: {
modelValue: { value: {
type: String, type: String,
default: '', default: '',
}, },
@ -32,16 +32,16 @@ export default defineComponent({
// v-modal // v-modal
// //
watch(() => props.modelValue, () => { watch(() => props.value, () => {
if (isFocus.value) return if (isFocus.value) return
text.value = props.modelValue text.value = props.value
if (textareaRef.value) textareaRef.value.innerHTML = props.modelValue if (textareaRef.value) textareaRef.value.innerHTML = props.value
}, { immediate: true }) }, { immediate: true })
const handleInput = () => { const handleInput = () => {
if (!textareaRef.value) return if (!textareaRef.value) return
const text = textareaRef.value.innerHTML const text = textareaRef.value.innerHTML
emit('update:modelValue', text) emit('updateValue', text)
} }
// //
@ -56,7 +56,7 @@ export default defineComponent({
const clipboardDataFirstItem = e.clipboardData.items[0] const clipboardDataFirstItem = e.clipboardData.items[0]
if (clipboardDataFirstItem && clipboardDataFirstItem.kind === 'string' && clipboardDataFirstItem.type === 'text/plain') { if (clipboardDataFirstItem && clipboardDataFirstItem.kind === 'string' && clipboardDataFirstItem.type === 'text/plain') {
clipboardDataFirstItem.getAsString(text => emit('update:modelValue', text)) clipboardDataFirstItem.getAsString(text => emit('updateValue', text))
} }
} }
} }

View File

@ -55,12 +55,14 @@
v-contextmenu="el => contextmenus(el)" v-contextmenu="el => contextmenus(el)"
> >
<CustomTextarea <CustomTextarea
v-if="activedCell === `${rowIndex}_${colIndex}`"
class="cell-text" class="cell-text"
:class="{ 'active': activedCell === `${rowIndex}_${colIndex}` }" :class="{ 'active': activedCell === `${rowIndex}_${colIndex}` }"
:contenteditable="activedCell === `${rowIndex}_${colIndex}` ? 'plaintext-only' : false" contenteditable="plaintext-only"
v-model="cell.text" :value="cell.text"
@update:modelValue="handleInput()" @updateValue="value => handleInput(value, rowIndex, colIndex)"
/> />
<div v-else class="cell-text" v-html="formatText(cell.text)" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -76,7 +78,7 @@ import { PPTElementOutline, TableCell, TableTheme } from '@/types/slides'
import { ContextmenuItem } from '@/components/Contextmenu/types' import { ContextmenuItem } from '@/components/Contextmenu/types'
import { KEYS } from '@/configs/hotkey' import { KEYS } from '@/configs/hotkey'
import { createRandomCode } from '@/utils/common' import { createRandomCode } from '@/utils/common'
import { getTextStyle } from './utils' import { getTextStyle, formatText } from './utils'
import useHideCells from './useHideCells' import useHideCells from './useHideCells'
import useSubThemeColor from './useSubThemeColor' import useSubThemeColor from './useSubThemeColor'
@ -428,8 +430,8 @@ export default defineComponent({
// //
// //
// //
// //
const tabActiveCell = () => { const tabActiveCell = () => {
const getNextCell = (i: number, j: number): [number, number] | null => { const getNextCell = (i: number, j: number): [number, number] | null => {
if (!tableCells.value[i]) return null if (!tableCells.value[i]) return null
@ -501,7 +503,8 @@ export default defineComponent({
}) })
// //
const handleInput = debounce(function() { const handleInput = debounce(function(value, rowIndex, colIndex) {
tableCells.value = tableCells.value[rowIndex][colIndex].text = value
emit('change', tableCells.value) emit('change', tableCells.value)
}, 300, { trailing: true }) }, 300, { trailing: true })
@ -626,6 +629,7 @@ export default defineComponent({
contextmenus, contextmenus,
handleInput, handleInput,
subThemeColor, subThemeColor,
formatText,
} }
}, },
}) })

View File

@ -35,7 +35,7 @@
:colspan="cell.colspan" :colspan="cell.colspan"
v-show="!hideCells.includes(`${rowIndex}_${colIndex}`)" v-show="!hideCells.includes(`${rowIndex}_${colIndex}`)"
> >
<div class="cell-text" v-html="cell.text" /> <div class="cell-text" v-html="formatText(cell.text)" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -46,7 +46,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType, ref, watch } from 'vue' import { computed, defineComponent, PropType, ref, watch } from 'vue'
import { PPTElementOutline, TableCell, TableTheme } from '@/types/slides' import { PPTElementOutline, TableCell, TableTheme } from '@/types/slides'
import { getTextStyle } from './utils' import { getTextStyle, formatText } from './utils'
import useHideCells from './useHideCells' import useHideCells from './useHideCells'
import useSubThemeColor from './useSubThemeColor' import useSubThemeColor from './useSubThemeColor'
@ -99,6 +99,7 @@ export default defineComponent({
totalWidth, totalWidth,
hideCells, hideCells,
getTextStyle, getTextStyle,
formatText,
subThemeColor, subThemeColor,
} }
}, },

View File

@ -31,4 +31,8 @@ export const getTextStyle = (style?: TableCellStyle) => {
fontFamily: fontname || '微软雅黑', fontFamily: fontname || '微软雅黑',
textAlign: align || 'left', textAlign: align || 'left',
} }
}
export const formatText = (text: string) => {
return text.replace(/\n/g, '</br>').replace(/ /g, '&nbsp;')
} }