往写好的html插入标签,写一个可插入自定义标签的 Textarea 组件
- “插入自定義標簽是什么鬼?”
- “比如你要插入一個的標簽...”
- “什么情況下會有這種需求?”
- “得罪了產(chǎn)品的情況下...”
一、需求背景
某天,產(chǎn)品找到我,發(fā)生了如下對話
PM:“哇,研發(fā)小哥哥你今天好帥啊~”
我:“說人話。”
PM:“我有一個需求。”
我:“我不聽。”
PM:“我們要給用戶發(fā)送模版消息。”
我:“找后端小姐姐啊。”
PM:“后端小姐姐讓你在編輯這個字段的時候,標記對應(yīng)的模版詞組。”
我:“怎么標記?”
PM:“然后我希望在刪除這個模版詞組的時候,可以整個刪除。”
我:“怎么刪除?!”
PM:“整個刪除。”
我:(打開抽屜,亮出我的四十米長刀)
PM:(楚楚可憐的看著我)
我:“做不了。”
PM:(伸出一根手指)
我:“這需求我接了。”
十年后...
二、輸入功能實現(xiàn)
為了實現(xiàn)這個功能,我最先想的是改造一個
然后我想到了(鏈接指向 mozilla.org)這一屬性
這是一個 html5 的屬性,可以讓元素內(nèi)容可編輯
這是一個可編輯的段落。
但這樣改造之后的輸入框,在粘貼的時候會帶上文本格式,即富文本
所以最后我放棄了該屬性,采用 CSS 的解決方案:
這個屬性有四個可選值:
read-only:默認值,元素只讀,不可編輯;
read-write:可以編輯,支持富文本;
read-write-plaintext-only:可以編輯,不支持富文本;
write-only:使元素僅用于編輯(幾乎沒有瀏覽器支持)
所以最后我給輸入框添加了這樣一行 CSS 屬性:
-webkit-user-modify: read-write-plaintext-only !important;
三、實現(xiàn)單向綁定
一個常規(guī)的輸入框組件,父組件可以通過 v-model 指令雙向綁定數(shù)據(jù)
v-model 其實是一個語法糖,它向子組件傳遞一個 value 屬性,并接收一個 input 事件
所以對于父組件來說:
等價于:
而子組件為了支持 v-model,需要在 props 里定一個 value 屬性
并且在合適的時候觸發(fā)?this.$emit('input', value)
在這個 tag-textarea 組件中,我在輸入框上監(jiān)聽 input 事件,獲取元素內(nèi)的 innerHTML,并暴露給父組件
到這里,還僅僅實現(xiàn)了單項綁定——子組件的值改變時,父組件的值隨之改變
要實現(xiàn)真正意義上的雙向綁定,還有一段路要走
四、完成雙向綁定
首先需要在 data 定義一個?currentText
如果是普通的輸入框,直接在輸入框元素上使用 v-text="currentText"
然后在 watch 中監(jiān)聽 value 的變化,實時更新 currentText,就能實現(xiàn)雙向綁定
但這個 textarea 返回的是 html,v-text 是不能用了
如果用 v-html 的話,在輸入的時候,光標會一直跳到最前方,最后我采用了以下方案:
在 data 添加一個 isLocked 用于記錄鎖定狀態(tài)
在 mounted() 的時候,通過 dom 操作初始化數(shù)據(jù)
在聚焦和失焦的時候修改鎖定狀態(tài)
看,很簡單吧,沒有人會受傷的世界一個基本的 textarea,完成了
五、插入標簽
創(chuàng)建標簽并不難,可如何讓這個標簽插入到光標所在的位置?
于是 Selection 對象閃亮登場,它記錄了拖藍的文本范圍,或插入符號的當前位置
通過 Selection 對象可以獲取到 Range 對象,然后使用?Range.insertNode()方法,在目標位置插入標簽
在 mounted() 中監(jiān)聽 selectionchange 事件,添加對應(yīng)的處理函數(shù),并在 beforeDestroy() 的時候卸載
在處理函數(shù)中,記錄當前的 range
添加標簽的時候,首先通過?document.createElement() 創(chuàng)建標簽,然后插入節(jié)點
六、刪除標簽
刪除分為光標位于標簽外和標簽內(nèi)兩種情況
首先是當光標在標簽外的時候,有一個取巧的辦法
給模版標簽添加樣式,將?-webkit-user-modify 設(shè)置為 read-only
這樣在刪除的時候,因為無法編輯,就會直接刪除整個 dom 節(jié)點
當光標位于標簽內(nèi)的時候,會稍微復(fù)雜一點
首先需要監(jiān)聽 click 事件,當點擊模版標簽的時候,記錄其 id
然后監(jiān)聽?keydown.delete 事件,如果選中了標簽,就使用 removeChild() 刪除標簽
以上,就已經(jīng)滿足了產(chǎn)品的基本需求
不過既然是開發(fā)組件,就需要做一些適合組件開發(fā)的優(yōu)化
比如 props 、slot 、 css樣式等,這里就不多贅述了
最后,元旦快樂~
總結(jié)
以上是生活随笔為你收集整理的往写好的html插入标签,写一个可插入自定义标签的 Textarea 组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 东大18春计算机基础在线作业,东大18春
- 下一篇: 台式计算机配置清单及价格,电脑配置清单及