使用 v-linkified 無法即時更新(real time)
4 min readJun 4, 2023
前言
一開始是為了想在 vue 讓有網址的字串能自動轉成可點擊的超連結,所以使用了 vue-linkify。
使用方式
很簡單!
第一步:安裝
npm install vue-linkify
第二步:載入
import linkify from 'vue-linkify';
Vue.directive('linkified', linkify);
最後一步:在需要轉成超連結的節點加 v-linkified
例如:
<div
class="message message-text text-body-3"
v-linkified
>
{{ message }}
</div>
就可以看到文字中有 url 的都轉成超連結啦!
遇到問題~不能即時更新(real time)
但是在我的使用情境會遇到一個問題~
我的畫面中有一個使用者的輸入框,還有一個是可以預覽使用者輸入字串的區域,就是這個預覽區需要用到 vue-linkify。
但發現用了 vue-linkify 畫面只要渲染過就再也不會動了!
即使變數 message 有變化畫面也不會跟著變。
後來發現應該是因為 vue-linkify 抓到字串轉成超連結 <a> tag 後就不會再改動了。
不能即時更新(real time)的解法
關鍵:能讓畫面改變的方式就是要重新渲染!
查了一些能讓 vue2 重新渲染的方法,最後選擇用 v-if 比較簡單。
步驟1:宣告一個 Boolean 變數 isPreviewCard
data() {
return {
textContent: '', // 使用者輸入的字串
message: '', // 預覽畫面的字串
isPreviewCard: true, // 是否要炫染 PrevewCard 元件,預設要
};
}
步驟2:把這個變數放到要 rerender 的元件控制 v-if
<previewCard
v-if="isPreviewCard"
:message="message"
/>
步驟3:監控輸入的字串,有改變時就先停止 render
watch: {
textContent() {
this.isPreviewCard = false; // 先停止 render
this.debounceArrangeText(); // 需要 debounce,否則太快也是不會更新
}
},
import debounce from 'lodash/debounce';
methods: {
debounceArrangeText: debounce(async function () {
this.arrangeText();
}, 500),
arrangeText() {
if (this.textContent) {
this.message = this.textContent;
this.isMessagePreviewCard = true; // 開始渲染畫面
}
}
}
這樣就可以讓預覽畫面跟使用者輸入的文字連動啦!
而且字串有 url 的都會自動變成可點擊的超連節唷👍
更方便的解法 v-html
後來發現這篇文章問到同樣的問題,使用 vue-linkify plugin 後 reactivity 失效。
有人回答說使用 v-html 就可以維持 reactive,超方便!
像這樣:
<p
class="message message-text text--body-3"
v-linkified
v-html="message"
/>
👍🏻👍🏻👍🏻