前言#
以前、尤大さんが「
最近、関連するプロジェクトをネットで見つけ、また興味が湧いてきました。何もすることがなかったので、この夏休みにビデオに従って試してみました。<script setup>
のシンタックスシュガーと ts を使用すると、多くの問題に直面しましたが、このプロジェクトを進める過程で<script setup> +ts
の爽快感を感じました。本当に快適でした(笑)
それでは、開発プロジェクトで感じた利点と、開発過程で遭遇したいくつかの問題について直接話していきます。
利点:#
よりシンプルなコード#
Vue3.2 では、公式に<script setup>
のシンタックスシュガーがサポートされ、大量の重複したテンプレートコードが削減され、コンポーネントのインポートは登録する必要がなくなりました。インポートしたコンポーネントは、SFC 内で使用するだけで使用できます。コードで直接表示すると、効果がより良くわかります:
<template>
<Header />
</template>
<script setup>
// インポートしたコンポーネントは登録する必要がなくなりました
import Header from './header.vue'
</script>
コンポーネントのインポートだけでなく、関数や変数の宣言もコード量が大幅に減少しました。<script setup>
を使用すると、変数の値をreturn
する必要がなくなります。関数の場合も、methods
オプションを使用して公開する必要がなくなり、setup 内で直接関数を記述できます。公式ドキュメントのコード例は以下の通りです:
<script setup>
// 変数
const msg = 'Hello!'
// 関数
function log() {
console.log(msg)
}
</script>
<template>
<button @click="log">{{ msg }}</button>
</template>
プロジェクトのインターフェースがより詳細になりました#
このプロジェクトでは、インターフェースの作成に mock.js を使用し、import '@/mock/index'
でインターフェースを実行します。実際のプロジェクトでは、インターフェースを呼び出す際に typescript を使用してインターフェースを定義
する必要があります。コード量は多少増えますが、中〜大規模なプロジェクトではメンテナンスが容易になりますし、インターフェースの呼び出し時にもコードのヒントが表示されるため、これは ts の利点です。
コードの例は以下の通りです:
<script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'
// インターフェースの定義
interface Iswiper {
imgSrc: string
link: string
}
const list = ref<Iswiper[]>([])
axios({
url: '/swiperList',
method: 'get'
}).then((res) => {
console.log(res.data.result)
list.value = res.data.result
})
</script>
マウスをホバーすると、以下のようなヒントが表示されます:。これにより、インターフェースの呼び出しと後続のメンテナンスが非常に容易になります。詳細な ts のチュートリアルについては、この記事を参照して、interface
についてより深く理解することができます。
開発プロセスで遭遇した問題#
ルーティングが機能しない#
ここで犯したミスは、実は<script setup>
の理解が不十分だったことです。検索ボタンをクリックして遷移しようとしたとき、クリックしても何の反応もありませんでした。<script setup>
でthis.$router.push
を直接使用して遷移しようとしましたが、この時点では setup が実行されておらず、まだ vue インスタンスがないため、this
もありません。
vue-router
の公式ドキュメントを見ると、次のように明確に説明されていることがわかります:
setup の実行タイミングは beforeCreate よりも前なので、setup 内では data と methods を使用することはできません(まだ初期化されていないため)。data と methods を setup 関数内で使用できないため、Vue は誤った使用を防ぐために、setup 関数内の this を undefined に変更します。
ただし、このプロジェクトの「検索アイコン」はタグであるため、useRouter
関数を使用する必要はありません。直接タグに追加するだけです:
注意:デフォルトのルーティングはhash
ですので、ここに直接/search
を追加することはできません。そうするとページが遷移せず、前に#
を追加する必要があります。
コンポーネントのスタイルを変更できない#
コンポーネントのスタイルを変更できない問題は、以前のプロジェクトでも遭遇したことがあります。element plus
のコンポーネントのデフォルトスタイルは変更できず、vant3
でも同じ問題に遭遇しました。自分で書いたスタイルが上書きされてしまいます。この場合、スタイルのパススルー
を直接行えば問題ありません。使用方法:::deep クラス名 { スタイルを変更 }
:
CSS モジュール#
ログイン画面のスタイルを変更しようとしたときに問題が発生しました。ページ全体の背景色を灰色に変更できませんでした。<style scoped>
の中のscopedを削除すると、スタイルが適用されますが、その場合、スタイルがプライベートにならず、グローバルに汚染されるという副作用があります。
この場合、2 つの解決策があります:
別のスタイルを作成する#
別の<style>
を作成し、body に対してスタイルを適用します。
グローバルスコープを使用する#
CSS Modules では、:global(.className)
の構文を使用して、グローバルルールを宣言することができます。
CSS Modules の詳細については、阮一峰先生のCSS Modules 用法教程を参考にしてください。
defineExpose#
vant3
コンポーネントを使用する際に、element plus
のように公式の例が<script setup>
を直接使用していなかったため、次のように書いてしまいました:
結果として、ログイン画面の入力フィールドがすべて表示されなくなりました... 考えればわかりますが、おそらくsetupシンタックスシュガー
をうまく使えていないため、すぐに Vue の公式ドキュメントを見て、問題の原因を見つけました:実際、<script setup>
では、ref
を使用してコンポーネントの公開インスタンスに直接アクセスすることはできません。defineExpose
を使用する必要があります。
<script setup>
を使用するコンポーネントは、デフォルトで非公開です。つまり、テンプレートの ref や$parent
チェーンで取得されるコンポーネントの公開インスタンスには、<script setup>
で宣言されたバインディングは公開されません。
<script setup>
コンポーネント内で公開するプロパティを明示的に指定するために、defineExpose
コンパイラマクロを使用します。
注意:definExpose
は手動でインポートする必要があります。
まとめ#
<script setup> + TS + Volar
は本当に素晴らしいです。まだ<script setup>
のシンタックスシュガーを十分に理解していないため、開発プロセスで一連の問題が発生しましたが、シンタックスシュガーの魅力を感じることができました。最後に、プロジェクトとソースコードのリンクを軽く添付します。
ソースコードのリンク:https://github.com/isolcat/vue3-ts-bilibili
プロジェクトのプレビュー:https://vue3-ts-bilibili.vercel.app