Vueまとめ3(上級編)
こちらの記事は、Adnan Babakan 氏によりDev.to上で公開された『 Vue cheat sheet 3 』の邦訳版です(原著者から許可を得た上での公開です)
原著をベースに説明の足りない部分は適宜、追記しています。
(追記・改変の許可は得ています。)
DEV.toコミュニティの皆さん、こんにちは!
Vueまとめシリーズは多くの注目を集めたので、シリーズの公開を続けることにしました。これは、ほとんどすべての主要な初心者向けの事柄が以前のものでカバーされているので、これは少し高度になっています。
いくつかのコードサンプルは公式ウェブサイトから引用しています。Vue.jsで確認できます。1
mixins
- ミックスイン
簡単に言うと、ミックスインは別々のファイルに保存されるコンポーネントの一部であり、他のコンポーネントで再使用可能なもの。
ミックスインは次のよう書くことができる。
// define a mixin object
export const myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('Hello from mixin!')
}
}
}
ご覧のとおり、これにはcreated
フックとhello
というメソッドがあるので、このmixinを次のようにコンポーネントで使うことができる。
<script>
import { myMixin } from './myMixin.js'
export default {
mixins: [myMixin]
}
</script>
したがって、このコンポーネントでこれらのフックとメソッドを記述した場合と同様に機能する。
ミックスインが競合した場合
コンポーネント自身のプロパティまたはメソッドとミックスインの間に競合がある場合は、ミックスインではなくコンポーネントの方が優先される。
let mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// ミックスインではなくコンポーネントのdataになっている
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
Vueによる上書きの処理方法は変更できるが、それについては別の記事で説明する。
Vue.mixin()
- グローバルミックスイン
グローバルミックスインは、作成されたすべてのVueインスタンスをスコープに含むという以外は通常のミックスインと同様の機能を提供する。
import Vue from 'vue'
Vue.mixin({
methods: {
sayHi() {
alert('Salam!')
}
}
});
const app = new Vue({
el: '#app'
})
このメソッドsayHi
は、上記のコードのすべてのコンポーネントとVueインスタンスで使用できる。
directives
- カスタムディレクティブ
ご存じのとおり、ディレクティブはVueがDOMを処理する方法だ。たとえば、v-model
やv-show
はディレクティブだ。
ディレクティブを定義するには、次のようにする。
<script>
export default {
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
}
</script>
focusディレクティブは、v-focus
として次のように使うことができるようになる。
// コンポーネントがレンダリングされるとすぐにinput要素がフォーカスされる
<input v-focus />
Vue.directives()
- カスタムグローバルディレクティブ
カスタムディレクティブをVueインスタンス全体でグローバルに使用できるようにするには、次のように定義する。
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
})
filters
- フィルター
フィルターは、単に値を変更してそれを返すために使用される。
それらは、ムスタッシュ構文とv-bind
ディレクティブの両方で使うことができる。
コンポーネントでフィルターを定義するには、次のように定義する。
<script>
export default {
filters: {
capitalize: function(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
}
</script>
定義したcapitalizeフィルターは次のように使うことができる。
<span>{{ msg | capitalize }}</span>
または、以下のようにv-bind
でも使うことができる。
<a v-bind:href="url | capitalize">My capitalized link!</a>
Vue.filter()
- グローバルフィルター
グローバルフィルターは通常のフィルターと同じだが、一度定義すると、すべてのVueインスタンスまたはコンポーネントで使用可能。
import Vue from 'vue'
Vue.filter('focus', {
capitalize: function(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
})
Vue Router
Vue Routerは、Vueを使用してクライアント側でルーティングシステムを設計するために使われる。
Vue Routerを使い始める
ルーターの使用を開始するには、ルーターをインストールする必要がある。
手順を紹介する。
Vue Routerのインストール
npmを使用してインストールする(推奨)。
npm i vue-router --save
次のファイルを含めることでもインストールできる。
<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>
インストール後、VueにVueRouterを使用するよう指示する。
次の通り。
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
ルートにバインドされているコンポーネントは、ページのどこかにレンダリングする必要があります。これは次のようにrouter-view
タグを使って宣言される。
<div id="app">
<div>
Hello World!
</div>
<router-view></router-view>
</div>
ルートの定義
各ルートには、独自の固有のコンポーネントがバインドされる。以下のようにルートを定義できる。
const routes = [
{ path: '/foo', component: require('./path/to/foo/component') },
{ path: '/bar', component: require('./path/to/bar/component') }
]
const router = new VueRouter({
routes // `routes: routes`の省略記法
})
ユーザーのブラウザの履歴へルートを残したい場合は、以下のように履歴モードをアクティブにする必要がある。
const router = new VueRouter({
mode: 'history',
routes // `routes: routes`の省略記法
})
次に、ルートをVueインスタンスにアタッチする。
const app = new Vue({
router
}).$mount('#app')
履歴モードを使用している場合、すべてのリクエストをindex.html
ファイルにリダイレクトしてVueが残りの処理を行えるようにするには、Webサーバーの設定をする必要がある。そうしないと、ページ上でブラウザを更新することにより、そのページが実際にはサーバー上に存在しないため、404が返されてしまうことに注意。
<router-link></router-link>
- ルーターリンク
ルーターリンクは、ページを更新せず、必要なコンポーネントのみを取得するため(そして履歴モードで履歴にURLをプッシュするため)特別なもので、新しいページに切り替わったように見える。
ハイパーリンク(a
タグ)の代わりに、router-link
を次のように使用する必要がある。
<router-link to="/foo">Go to foo</router-link>
高度なルーティング
Vue Routerはには単純なルーティング機能以外に、ルーティングを処理する優れた方法を他にも用意している。
動的ルーティング
動的ルートは、取得するいくつかのパラメータを持つ一連のルートを照合するために使用される。
動的ルートは、通常のルートと同様に定義されるが、動的セグメントの先頭にコロンが付いている。
const routes = [
{ path: '/user/:username', component: require('./path/to/user/component') },
]
これで、/user/adnanbabakan
、/user/dev/
または/user/vue
などのルートは全て有効になる。
以下のようにルート内のusername
対応するコンポーネントには次のようにしてアクセスすることができる。
<div>This is {{ $route.params.username }}'s profile!</a>
動的ルートのパラメーター変更への対応
上記の例を考えてみよう。ユーザが/user/adnanbabakan
から/user/dev
に移動する場合、同じコンポーネントをレンダリングしようとするので、Vueは以前のインスタンスを破棄しない。$route
オブジェクトで見ることのできるどんなparamsの変化にも対応するためにライフサイクルフックが呼び出されることはない。
<script>
export default {
watch: {
$route(to, from) {
}
}
}
</script>
404ルーティング
すべてのWebサイトには、優れた404ルートが必要だ。Vue Routerでは、最後にアスタリスクルート*
を定義して、定義されていないすべてのものをキャッチすることができる。
アスタリスクルートは、他のルートの最後とその後に定義する必要がある。そうしないと、このアスタリスクルートは他のすべてと一致し、ルーティングシステムを破壊してしまうことに注意だ。
そのためには、以下のコードをご覧ください。
const routes = [
// 他のルートを書いた後に404となるルートを書く
{
path: '*',
component: require('./path/to/404/component'
}
]
アスタリスクルート
アスタリスクを使用すると、別の種類の動的ルートを照合可能だ。動的ルートは2つのスラッシュ間の動的セグメントだけを照合可能だが、アスタリスクはそれとは別のことができる。
次のルートを見てみよう。
const routes = [
{
path: '/user-*',
component: require('./path/to/user/component')
}
]
このように書くことで、/user-adnan
、および/user-dev
のようなルートでページはレンダリング可能だ。
$route.params
を使うことによってと呼ばれるプロパティがpathMatch
と呼ばれるプロパティをもつことができる。
このプロパティはアスタリスクと一致した部分が含んでいる。
たとえば/user-adnan
ページの$route.params.pathMatch
ははが返されadnan
を返す。
名前付きルート
名前付きルートは、短い名前で長いルートパターンにアクセスするために使用される。
次のようなパターンがあるとする。
const routes = [
{
path: '/user/profile/setting/',
component: require('./path/to/user/component')
}
]
次のように名前を定義できる。
const routes = [
{
path: '/user/profile/setting/',
component: require('./path/to/user/component'),
name: 'settings'
}
]
これで、リンクは次のように書ける。
<router-link :to='{name: "settings"}'>
Profile settings
</router-link>
代わりにこう書くこともできる。
<router-link to="/user/profile/setting/">
Profile settings
</router-link>
オブジェクトをto
属性に渡すときは、バインドする必要があることに注意だ。
パラメータ付きの名前付きルート
先述の例のように、一部のルートにはパラメータがある場合があるがそれらの名前も定義できる。
const routes = [
{
// usernameというパラメータを持っているが名前を付けることが可能
path: '/posts/from/:username',
component: require('./path/to/posts/component'),
name: 'posts'
}
]
そして、これのリンクを作成する時は、次のように書くことができる。
<router-link :to='{ name: "posts", params: {username: "adnanbabakan"} }'>Profile settings</router-link>
プログラムによるナビゲーション
先に書いたように、<router-link></router-link>
を使用してルーターリンクを作成することができるが、プログラムでユーザーをリダイレクトする必要がある場合はどうだろうか。さて、このコードでそれを行うことができる
router.push('/foo');
このコードはユーザーを/foo
にリダイレクトする。これは特に、ログイン後のリダイレクトなどの状況で使用される。
プログラムによる名前付きナビゲーション
このような名前付きルートにもrouter.push()
を使うことができる。
router.push({name: 'myRoute'});
パラメータのある場合のプログラムによるナビゲーション
同様にrouter.push()
は次のようにparamsと一緒にリダイレクトするために使用できる。
router.push({name: 'myRoute', params: {paramOne: 'Hello', paramTwo: 'Salam'}})
ルートリダイレクト
ルートは、次のように相互にリダイレクトされるように定義できる。
const routes = [
{
path: '/foo',
redirect: '/bar'
}
]
名前付きリダイレクトのルート
次のように、ルートを名前付きルートにリダイレクトすることもできる。
const routes = [
{
path: '/foo',
redirect: { name: 'myRoute' }
}
]
動的ルートリダイレクト
次のように、宛先を評価する関数を使用してルートをリダイレクトできます。
const routes = [
{
path: '/foo',
redirect: to => {
// the function receives the target route as the argument
// return redirect path/location here.
}
}
];
パラメータを使用したルートリダイレクト
ターゲットルートにパラメータがある場合は、リダイレクト先にも渡すことができる。
const routes = [
{
path: '/profile/:username',
redirect: '/user/:username'
}
]
ルートエイリアス
ルートエイリアスとは、1つのルートがアクセスされるための複数のアドレスをもつことができるとい機能だ。
次が例。
const routes = [
{
path: '/foo',
alias: '/bar'
}
];
これで/foo
というルートは/bar/
でもアクセスすることができる。
1つのルートは複数のエイリアスを持つこともできる。
const routes = [
{
path: '/foo',
// 配列に複数のエイリアスを指定できる
alias: ['/bar', '/baz']
}
];