在typescript中import第三方類庫clipboard報錯
一、問題
在實際開發專案中就遇到了這樣的問題,需要在Vue+Typescript專案中新增複製文字的功能,就找了clipboard外掛,先是新建了一個新的專案用來實驗看看是否好用,都寫好了以後發給別人讓在專案裡新增,結果採用常規的方法匯入第一句話就提示錯誤。然後又用了vue-clipboard2外掛匯入 import VueClipboard form'vue-clipboard2'同樣報一樣問題,剛開始一直沒意識到是typescript的原因。報錯如下:
TS7016: Could not find a declaration file for module 'vue-clipboard2'. 'D:/Work/wechat/node_modules/vue-clipboard2/vue-clipboard.js' implicitly has an 'any' type. Try `npm install @types/vue-clipboard2` if it exists or add a new declaration (.d.ts) file containing `declare module 'vue-clipboard2';
二、錯誤原因
因為第三方類庫並沒有ts的.d.ts 型別的宣告檔案,所以無法在目前的專案中正常使用。舉個栗子,我們使用vant,首先是在專案裡安裝,然後再專案裡引入。
npm i vant -S //在專案裡安裝 import { Toast } from 'vant'; //引入專案
會發現這裡並沒有報錯,我們檢視node_modules,找到vant檔案,發現裡面有types資料夾,types資料夾裡面有index.d.ts等檔案,這個資料夾的用處就在於將弱型別轉換為強型別,對外掛裡面的變數方法什麼的進行了宣告和定義。所以可以在typescript專案里正常使用。
而我不管是安裝vue-clipboard2還是clipboard,在檔案裡都未發現types資料夾及index.d.ts等檔案,所以專案不支援使用。
查閱網上資料,可以自定定義(.d.ts)來描述庫的型別和@types兩種宣告方式,第一次我模仿官網上jquery來寫.d.ts(如下圖:)不過沒成功,就想著那就試試@types。
三、解決方法
查閱相關資料後在,做了下面的嘗試。
npm install @types/vue-clipboard2
即vue-clipboard2安裝的前提下再增加安裝@types的npm modules即可,然後就嘗試了一下,依舊報錯(如下):
D:\Work\wechat>npm install @types/vue-clipboard2npm ERR! code E404
npm ERR! 404 Not Found: @types/vue-clipboard2@latest npm ERR! A complete log of this run can be found in:
這個原因是並沒有vue-clipboard2的types宣告檔案,所以在使用之前還是需要在typesearch裡面檢視一下相關的類庫是否有宣告檔案,https://microsoft.github.io/TypeSearch/ 查詢結果如下:
所以就採用了clipboard
通過npm執行安裝@types/clipboard外掛,安裝完成後就可以在專案中正常的使用clipboard了。
在專案裡安裝
npm install --save @types/clipboard
在專案中引入
import clipboard from 'clipboard'; //註冊到vue原型上(這裡不是很明白,還沒搞清楚) Vue.prototype.clipboard = clipboard;
<h1 class="coupon-code" id="bar">{{couponCode}}</h1> <button class="btn" data-clipboard-action="copy" data-clipboard-target="#bar" @click="copyLink">點選複製</button>
我們需要定義data-clipboard-action
屬性,來選擇是複製還是剪下,如果忽略這個,預設是copy
public copyLink() { const This = this; const clipboard = new Vue.prototype.clipboard('.btn'); clipboard.on('success', () => { // Toast('複製成功'); This.$toast('複製成功'); }); clipboard.on('error', () => { Toast('複製失敗,請手動選擇複製!'); }); }
&n