[[vue-mention]]を使って実装してみる。 ## インストール ```console $ bun add vue-mention@next floating-vue warn: incorrect peer dependency "[email protected]" installed [email protected] installed [email protected] ``` 若干依存関係のズレが気になるが一旦続ける。 `main.ts`などに追加。 ```ts import 'floating-vue/dist/style.css' ``` import文を書くがエラーになる。 ```ts import { Mentionable } from "vue-mention"; ``` ## floating-vueのバージョンを変更 [[vue-mention]]の[[peer dependencies]]を確認すると、[[floating-vue]]のバージョンは2系になっている。 ```json "peerDependencies": { "floating-vue": "^2.0.0-beta.1", "vue": "^3.2" }, ``` 実際のバージョンは遥か先の5.2.2。それは動かない。 > installed [email protected] バージョン指定して入れなおしてみる。 ```console bun add floating-vue@2 ``` 変わらず... ```error Could not find a declaration file for module 'vue-mention'. '/home/tadashi-aikawa/git/github.com/tadashi-aikawa/fenice/node_modules/vue-mention/dist/vue-mention.es.js' implicitly has an 'any' type. There are types at '/home/tadashi-aikawa/git/github.com/tadashi-aikawa/fenice/node_modules/vue-mention/dist/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'vue-mention' library may need to update its package.json or typings. ``` ## @ts-expect-errorで無理やり回避する [[vue-mention]]の`package.json`で`types`を追加すればエラーは回避できる。 ```diff "exports": { ".": { "import": "./dist/vue-mention.es.js", "require": "./dist/vue-mention.umd.js", + "types": "./dist/index.d.ts" } }, ``` ...が、これは微妙な方法なので[[@ts-expect-errorコメント]]で回避する。 ```ts // @ts-expect-error import { Mentionable } from "vue-mention"; ``` ## 補完が表示されない undefined? ```ts const members = ["ichiro", "jiro"] ``` 以下のようにしてもうまく補完が表示されない。 ```html <Mentionable :keys="['@']" :items="members" offset="6"> <v-textarea v-model="text" style="width: 640px" :rows="12" @paste="handlePaste" @keyup.ctrl.enter.exact="postMessage" @keyup.meta.enter.exact="postMessage" /> </Mentionable> ``` 同じ事象のIssueを発見したが、反応されてなさそう。。 <div class="link-card"> <div class="link-card-header"> <img src="https://github.githubassets.com/favicons/favicon.svg" class="link-card-site-icon"/> <span class="link-card-site-name">GitHub</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">Got @undefined in Vue3 · Issue #96 · Akryum/vue-mention</p> <p class="link-card-description">Hi, I tried to add this on our project using Nuxt3. "vue-mention": "^2.0.0-alpha.3" and "floating-vue": "^2.0.0-beta.24", When I select ... </p> </div> <img src="https://opengraph.githubassets.com/1710c555d5afb2881d0902b17fc2b392b6606c20a28050a961d92f69e6e73ddc/Akryum/vue-mention/issues/96" class="link-card-image" /> </div> <a href="https://github.com/Akryum/vue-mention/issues/96"></a> </div> よくよく確認したら `items` の値が間違ってた。`string[]`ではなく`{label: string, name: string}[]`だった。 ## styleが適応されない 別途styleを設定する必要がありそう。[[Scoped CSS]]は使えなそうなので`main.css`に。 ```css /* v-mention */ .v-popper__popper .mention-item { padding: 4px 10px; border-radius: 4px; } .v-popper__popper .mention-selected { color: white; background: rgb(var(--v-theme-primary)); } ``` ## 候補の見た目を変更する テキストだけではなく画像も入れたい。`v-slot:item`を追加すればOK。 ```html <Mentionable :keys="['@']" :items="userSuggestions" offset="6"> <v-textarea v-model="text" style="width: 640px" :rows="12" @paste="handlePaste" @keyup.ctrl.enter.exact="postMessage" @keyup.meta.enter.exact="postMessage" /> <template v-slot:item="{ item }"> <div class="d-flex align-center ga-2" style="font-size: 16px"> <img :src="item.user.profile.image_24" /> <span style="font-weight: bold"> {{ item.user.real_name }} </span> <span class="username"> {{ item.user.name }} </span> </div> </template> <template v-slot:no-result> <div style="display: none" /></template> </Mentionable> ``` `main.css` ```css /* v-mention */ .v-popper__popper .mention-item { padding: 4px 10px; border-radius: 4px; } .v-popper__popper .mention-selected { color: white; background: rgb(var(--v-theme-primary)); } .v-popper__popper .username { color: gray; } .v-popper__popper .mention-selected .username { color: white; } ```