Nuxt.js調査_8/27
■Nuxtをチェック
■
■
⑧$slots.defaultについて
■
- Nuxt.jsのディレクトリ構成
- vue-no-ssr.js
- export default
- props
- data
- mounted()
- canrenderによる遅延評価
- $slots
- nuxt-child
- import { compile } from '../utils'
- compileメソッド
- nuxt-childのkeepAlive
- defineReactive
- routeViewKey
- computed
- route-link
- HTML_ATTR/BODY_ATTR
- webpackchunkname
- transitionのout-in
- template lang="pug"
- v-tooltip
- v-btn
- slot = "activator"
■
■
①Nuxt.jsのディレクトリ構成について
■.nuxt
■
②vue-no-ssr.jsについて
■
[実装]
Home.vue(親)
ディレクトリ構成一覧
構成要素 | 説明 |
---|---|
.nuxt | コマンドでのビルド結果はここに配置されます。 |
└router.js | pagesディレクトリ配下のファイルに対して、ルーティングの設定を行います。 |
store | Vuexのストアファイルを配置します。Nuxt.jsではデフォルトでVuexを読み込んでいます。 |
static | コンパイルしない静的なファイルを配置します。例:robots.txt等。「/(ルート)」でアクセスすることができます。 |
plugins | アプリケーションをインスタンス化する前に実行したいJavaScriptプラグインを配置します。 |
pages | Nuxt.jsにおいて一番重要なディレクトリになります。「ビュー」と「ルーティング」に関する役割を担います。「index.vue」に最初に表示させるページのHTMLを記述する。 |
package.json | Nuxt.jsで使用するコマンド等を定義します。 |
nuxt.config.js | 「コンテキストオブジェクト」への各種設定を行います。 |
middleware | ページをレンダリングする前に実行される関数を定義して配置することができます。 |
layouts | アプリケーションのレイアウトファイルを入れます。 |
└default.vue | デフォルトのレイアウトファイルになります。 |
└error.vue | エラーページのレイアウトファイルになります。 |
components | ビューで使用するためのコンポーネントを指定します。Nuxt.jsの影響下のファイルではなく、Nuxt.jsからは自動で読み込まれないので、ピュアなvueファイルになります。使用しないのであれば削除することが可能です。 |
assets | LESSやSCSS等のコンパイルされていないファイルを配置します。 |
README.md | |
yarn.lock | |
node_modules |
■.nuxt
■
②vue-no-ssr.jsについて
- <no-ssr>タグ
- サーバーサイドレンダリングの対象からコンポーネントを除外する
- Nuxt.js 2.9.0以上は、<no-ssr>の代わりに<client-only>を使う
[定義]
<template><div id="app"><h1>My Website</h1><no-ssr><!-- this component will only be rendered on client-side --><comments /></no-ssr></div></template><script>import NoSSR from 'vue-no-ssr'export default {components: {'no-ssr': NoSSR}}</script>
■
③export defaultついて
■
③export defaultついて
- Vueファイルは「単一コンポーネント」ファイルである。
export default
でメンバーを囲むことで、外部からも参照できる- つまり、他のコンポーネントでも利用できる状態にする
- 基本的にscriptの部分は
export default
で囲むことが前提となる
■
Home.vue(親)
<template>
<div>
<!-- nameとpriceに静的な値をセットして
子コンポーネント(Item)にデータを渡しています。 -->
<Item name="りんご" price="100"></Item>
<!-- こっちのnameとpriceには動的な値をセットしています。
動的な値なので、nameとprice属性には:(v-bind:の省略形)を付けています。 -->
<Item :name="items[0].name" :price="items[0].price"></Item>
</div>
</template>
<script>
// Itemコンポーネントをインポートしています。
import Item from '@/components/Item.vue';
export default {
name: 'home',
components: {
// componentsプロパティにItemコンポーネントをセットして
// template内でItemコンポーネントが利用できるようにしています。
Item,
},
data: () => {
return {
// templateブロック内の2つ目のItemコンポーネントで使用しているデータです。
items: [
{ name: 'ぶどう', price: 500 },
],
};
},
};
</script>
Item.vue(子)
<template>
<div>
<!-- nameとpriceの値を表示するためのテンプレートです。 -->
{{ name }}: {{ price }}円
</div>
</template>
<script>
export default {
name: 'Item',
// 親コンポーネントから受け取るpropsを定義しています。
// 定義方法はいろいろありますが、ここでは一番シンプルに
// 配列でプロパティ名を書いています。
props: ['name', 'price'],
};
</script>
結果
- 親コンポーネントでnameとpriceの値をセットした子コンポーネント(Item)を呼び出す。
- 子コンポーネントで設定しているpropsプロパティでnameとpriceを受け取る。
- 子コンポーネントのtemplateブロック内でnameとpriceの値を表示する。
[使い方]
- コンポーネントでpropsオプションを定義する際、バリデーションや初期値を指定することができます。
- バリデーションを指定することで、親コンポーネントの属性値がバリデーションの条件を満たさない場合にコンソール上に警告を表示します。
2
3
4
5
6
7
8
9
10
11
|
props: {
itemName: {
type: String, // 型の検査
default: 'itemName', // 初期値
required: true, // 必須かどうか
},
itemPrice: {
type: Number,
required: false,
},
},
|
■
■
⑤dataについて
- データを保持(保存)しておき他から引っ張ってデータを使う
- data () メソッド内でオブジェクトを定義して、
- returnすることでデータの保持をして、
- vueのcomponentで必要なときにデータを引っ張ってきて使う
■
■
⑥mountedについて
■
■
⑦canRenderによる描画タイミングの調整(レンダリングの遅延)について
- Vue.mounted()の挙動は、内部的にrendererをDOMに追加していたが、SSR(Server-Side-Rendering)の場合document,windowオブジェクトが使用できない
- すなわち、Vue.mountedピュアではSSRには対応しておらず、なにがしかの別途調整が必要である
- レンダリング時に行えるような調整である
- Vue.renderで描画を行うように変更する
- これだけだと、SSRでもレンダリングが発生してしまうので、Vue.mounted内にcanRenderのスイッチを行うようにした。
- vue.mountedの仕様によりSSR時にはVue.mountedは動作しないため、レンダリングの遅延を発生させることができるようになった。
- これで、renderer.domElementをDOMに追加できた。
[実装上]
data() { return { canRender: false } }, mounted() { this.canRender: true }, render(h) { if(this.canRender) { ..... } }
■
■
⑧$slots.defaultについて
- slotとは親となるコンポーネント側から、子のコンポーネントのテンプレートの一部を差し込む機能 です。
- スロットというと「スロットマシン」が思い浮かびますが、もともとslotの「差し込み口」という意味から派生して、コインの投入口があるスロットマシンの意味をもつようになったそうです。
[実装での確認]
- $slot.default
- 名前付きslot
- スコープスロット
myCom.Vue
1 2 3 4 5 6 7 | <template> <div class="mycom"> <p>name:<slot>Mirai Taro</slot></p> </div> </template> <style> </style> |
about.Vue
1 2 3 4 5 6 7 8 9 10 11 12 13 | <template> <div class="home"> <MyCom>未来太郎</MyCom> </div> </template> <script> import MyCom from '../components/MyCom.vue' export default { components: { MyCom } } </script> |
表示結果
→タグの効果で、templateが上書きされている状態
→ちなみに name のない slot は暗黙的に「default」という名前になっています。
■
■
⑨nuxt-childについて
- ネストされたルート内で、子コンポーネントを表示するために使う
- つまり、layoutファイルよりも共通化できるための実装である
■
■
⑩import { compile } from '../utils'について
- import NuxtChildはクラスを呼び出す
- import { compile } はメソッドを呼び出す
■
■
11)compileメソッドについて
export function compile(str, options) { return tokensToFunction(parse(str,options)) }
コンパイルの実装
■
■
12)nuxt-childのkeepAliveについて
- nuxt-childのオプション値
- コンポーネントのキャッシュ
- コンポーネントを切り替ええてもデータが保持されるようになり、都度APIを叩いていた挙動を最初の1回だけに収めることができる。
■
■
13)defineReactiveについて
- オプジェクトの動的な属性を定義付けます
[実装]
/** * Define a reactive property on an Object. */ export function defineReactive ( obj: Object, key: string, val: any, customSetter?: ?Function, shallow?: boolean ) { const dep = new Dep() const property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) { return } // cater for pre-defined getter/setters const getter = property && property.get const setter = property && property.set let childOb = !shallow && observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { const value = getter ? getter.call(obj) : val if (Dep.target) { dep.depend() if (childOb) { childOb.dep.depend() } if (Array.isArray(value)) { dependArray(value) } } return value }, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val /* eslint-disable no-self-compare */ if (newVal === value || (newVal !== newVal && value !== value)) { return } /* eslint-enable no-self-compare */ if (process.env.NODE_ENV !== 'production' && customSetter) { customSetter() } if (setter) { setter.call(obj, newVal) } else { val = newVal } childOb = !shallow && observe(newVal) dep.notify() } }) }
■
■
14)routeViewKey- nuxtChildKey か ルートが子を持っていれば払い出すメソッド
■
■
15)computedについて
- プロパティと処理内容を記述する
- 他に依存した値を宣言する場合、計算して返す
[実装例]
var demo = new Vue({ data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } })
■
■
16)route-linkについて■
- 動的に生成しているh_ref
■views/app.template.html
■
17)html_attrについて■
- タグ内部の属性を取得する
■App.js
■
18)WebpackChunknameについて■
- Vue の 非同期コンポーネント機能 と webpack の コード分割機能 を組み合わせることでとても簡単に遅延ロードするルートコンポーネントができます。
- Webpackによる動的なimport文である
■
■
19)transitionのout-inについて
- out-in
- 最初に現在の要素がトランジションアウトして、それが完了したら、新しい要素がトランジションインする。
■
■
20)template lang="pug"について
- HTMLを簡単に書けるためのテンプレートエンジン
[比較]
HTML
<html lang="en"> <head> <meta charset="utf-8"> <title>sample</title> </head> <body> <div id="app"></div> </body> </html>
Pug
html(lang='en') head meta(charset='utf-8') title sample body #app
■
■
21)v-tooltipについて
[実例]
- v-tooltipコンポーネントは、ユーザーが要素にカーソルを合わせたときに情報を伝えるのに役立ちます.v-tooltip bottom.
[実例]
■
■
22)v-btnについて
- v-btn コンポーネントは基本的な HTMLにおけるボタンをマテリアルデザインで置き換え、多数のオプションを提供します。
■
■
23)slot = "activator"について
- イベントハンドラーである