使用 v-linkified 無法即時更新(real time)

Juju 的自學筆記
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"
/>

👍🏻👍🏻👍🏻

--

--

No responses yet