iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
Software Development

譯者會消失嗎?Maybe, but not today —— 你,才是更好的翻譯師系列 第 20

難道... 今天... 又是開天窗的好日子嗎?

  • 分享至 

  • xImage
  •  

昨天我們用 Vue3 實現了句子面板的原文句顯示,
做完之後,我的心裡其實有些不平靜。

原文句的顯示,並不是很難的事。
硬要用 Vue3 來實現,
實在有點殺雞用牛刀的感覺。

這就像手裡如果拿著鐵錘,
很多東西看起來都像是釘子一樣。

夜神月拿到了死亡筆記簿,
他的眼中就會老是看到很多該死的人。

普丁手握核武,
就會覺得很多事用核武便可解決。

這肯定是有問題的。

而且,template 可說是 Vue 很好用的一種做法 ,
但現在因為種種因素而無法使用,
我們迫不得已只好改用 render 來解決問題。

少了 template,Vue 的吸引力頓時少了一大半。
但我心想,至少它還有其他好用的特性呀,
例如簡潔的元件系統、資料與顯示分離,
還有即時更新頁面資訊的能力,
這些都會在之後的功能中展現出它的優勢,
所以我還是想藉由這次機會,
把一些會遇到的問題順帶解決。

但今天在實現詞語面板的功能時,
我又再次遇到問題了。

而且,現在距離晚上十二點截稿,時間已經所剩無多,
眼看著又要開天窗了呀啊啊啊啊啊!!

這次的問題,主要出在 component 元件系統上。
其實應該說,若想用 render 的做法搭配元件系統,
似乎就會有種種的問題。

我嘗試了半天,至少到現在都還沒找出解決辦法。
在網路上搜尋,也暫時找不到相應的解答。

從另一個角度來看,這可能也表示,
採用 render 搭配 component 的做法,
或許並不是主流的用法。

有機會的話,
我可能還要再檢討一下所採用的架構,
如果各位有什麼建議,也歡迎指教囉。

不過,現在我們頭已經洗了一半,
也不能說停手就停手。

因此我回頭嘗試了一下 Vue2 做法,
發現 Vue2 可能是因為被使用的時間比較長,
相關的說明文件也比較充足,
因此總算找到了可行的做法。

以下我會先用 Vue2 來實現相關的做法,
同時也算是留下了一個坑,
之後若在 Vue3 找到了可行的做法,
我再回來補上好了。

首先,為了使用 Vue2,
請把 vue.min.js 下載到 js 子目錄中。
然後在 manifest.json 裡,把登記的 vue 檔案換成這個新檔案。

  ...
  "js": [
    // "js/vue.global.prod.js", //Vue3
    "js/vue.min.js", // Vue2
    ...
  ],
  ...

接著要先做點調整,讓昨天的程式碼能夠正常運作,
主要有以下幾個地方需要修改:

  • Vue.createApp({...}) 要換成 new Vue({...})
  • .mount(...) 要換成 .$mount(...)
  • render() {...} 要換成 render(h) {...}

因為我們還沒用到很多 Vue 的功能,
所以目前基本上也就只有這三處需要修改。
其他像是 data 的設定方式,
在 Vue3 採用的是函式的形式,
之前在 Vue2 則是採用物件屬性的形式,
不過在 Vue2 也可以使用函式的形式,
所以沒改回去也沒問題。

關於 Vue2 與 Vue3 寫法上的差異,
可參考這個網頁的說明。

接著我們終於可以來討論如何運用詞語面板了。

在進行 NLP 自然語言處理時,
一旦完成分句的工作,
下一步通常就要進行分詞(tookenize)。

英文的分詞非常簡單,
因為句中的每個單詞都會用空格隔開,
所以只要用下面這個最簡單的方式,
就可以從句子轉換出單詞列表了。

tokens = sent.split(' ')

有了單詞列表之後,
我們就可以把每個單詞當做單一元素,
重新顯示整個句子:

  render(h) { 
    return h('div', {
      id: "orig_sent",
      style: { 'margin': '20px', }, 
    },  
    //[this.sent_text]) 
    this.tokens.map(token => h('span', {
        style: { 'margin': '2px' }  // 隔開每個 span 元素
        ...
      }, token)
    )
  )}

這裡是利用 .map() 函式,製作出 span 元素的列表,
如果對照 template 的做法,就相當於 v-for 的效果。

template 與 render 兩種做法的對照說明,
可參考官方的文件

我們之所以把每個單詞變成單一元素,
主要是為了帶出相應的的詞語面板。
因此,我們應該在每個 span 元素中,
針對滑鼠游標移入移出與 click 點擊事件,
設定相應的處理方法。

  ...
  h('span', {
    style: { 'margin': '2px' },
    on: { 
      mouseover: this.activate, 
      mouseout: this.deactivate, 
      click: this.tokenClicked, 
    },
  }, token)
  ...

其中 tokenClicked() 就是詞語點擊事件的處理方法。
我們會把這些方法寫在 methods 的設定中:

  methods: { 
    activate: function (e) { 
      e.target.classList.add('active'); 
    }, 
    deactivate: function (e) { 
      e.target.classList.remove('active'); 
    }, 
    tokenClicked: function (e) {  
      slideInPanel('bt_token_panel') 
      token_panel = document.querySelector('#bt_token_panel') 
      token_panel.innerHTML = `<h2>${e.target.innerText}</h2>` 
    },                 
  },

如此一來,只要點擊任一個單詞,
詞語面板就會從右邊滑出來,顯示相應的詞語。
跳到下一句時,則可自動關閉詞語面板。

slideOutPanel('bt_token_panel')

(相應程式碼應放在 nextSent() 函式中)

我們也可以在詞語面板中,
呈現詞語相關的資訊,或進行詞語相關的操作。

舉例來說,
我們可以請 JS 幫我們念出這個單詞,
或是幫我們查字典(連續點擊兩次),找出這個詞語的意思。

https://ithelp.ithome.com.tw/upload/images/20221006/201152416LyjQZGyuS.png

相應的程式碼這裡就不再多做說明了,
有興趣請參見我們放在 Github 的程式碼囉!

將來我們也可以在這裡定義詞語的替換方式,
讓它在滿足特定條件的情況下,
(例如參考詞語的原文、詞性等等)
幫我們進行更聰明的翻譯修正。

至此,我們的句子面板與詞語面板全都順利導入了。
雖然 Vue3 沒能順利導入,
但目前的功能應該也算是有了不錯的進展,
有興趣歡迎查看我們的程式碼,
或是下載外掛直接拿來使用囉。


上一篇
運用 Vue3 製作方便的句子面板
下一篇
Vue 呀 Vue 你讓我吃那麼多苦,也該給點甜頭了吧!
系列文
譯者會消失嗎?Maybe, but not today —— 你,才是更好的翻譯師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言