Nuxt.js Tips
nuxt.jsのtipsです
componentに値を渡す場合
送る側
<template> <MyComponent /> </template> <script> import MyComponent from "~/components/MyComponent.vue" export default { components: { MyComponent } } </scipt>
受け取る側(MyComponet.vue)
<script> export default { props: { aaa, bbb, ccc } } </script>
型チェックをしたい場合
<script> export default { props: { aaa: String, bbb: Boolean, ccc: Array } } </script>
propsに直接文字列を入れる場合
<MyComponent :myprop="StringDayo" />
とすると
Raw expression: :myprop="StringDayo"
となる
解決策
<MyComponent myprop="StringDayo" /> or <MyComponent :myprop="'StringDayo'" />
props等の変数をhtmlの要素にいれたい
<template> <nuxt-link to="this.link"> Link Dayo </nuxt-link> </template> <script> export default { props: { link: String } } </script>
これだとpropsのlinkが呼ばれずに/this.linkというリンクが参照されてしまう
解決策としては変数を使いたいときには要素の前に:をつける
<nuxt-link :to="this.link">
画像をpropsとして読み込む
<template> <div> <img :src="image_src" /> </div> </template> <script> export default { props: { filename: String, }, data() { return { image_src: require(`~/assets/img/${this.filename}`) } } } </script>
methodsを追加する場合
<template> <div class="foobar" @mouseover="mouseOn()" @mouseout="mouseOut()"> hogefuga </div> </template> <script> export default { methods: { mouseOn() { document.getElementById(foobar).style.color = "red"; }, mouseOut() { var img = document.getElementById(foobar); img.style.color = "gray"; } } } </scrip>
ページ読み込み時に処理を行いたいとき
<script> export default { mounted() { alert('foobar'); } } </script>
jsonファイルを読み込んで表示する
{ "aaa": true "bbb": false "ccc": "hogehoge" }
/pages/test.vue
<script> export default { data() { return { json: require(`static/json/test.json`) } } } </script>
▼v-for
要素を繰り返えしたいときに使う
上のjsonファイルを使う
<template> <div> <ol> <li v-for"(value, index) in json" property1="index" property2="value"></li> </ol> </div> </template> <script> export default { data() { return { json: require(`static/json/test.json`) } } } </script>
v-bind:class
クラス属性を条件分岐で設定するしないを分ける
<template> <div> <ol> <li v-for"(value, index) in json" v-bindclass="{ active: aaa }"></li> // 描画される(aaa === true) <li v-for"(value, index) in json" v-bindclass="{ active: bbb }"></li> // 描画されない(bbb === false) </ol> </div> </template> <script> export default { data() { return { json: require(`static/json/test.json`) } } } </script>
nuxt generateで動的ルーティングもbuild対象にする
nuxtは_foobar.vueといったアンダースコアで始まるvueファイルを作ることで動的にルーティングすることができる。
しかしこの動的ルーティングはデフォルトでnuxt generateの静的ファイルビルドの対象外となっている
以下のようにnuxt.config.jsで明示的に指定してやることで静的なルーティングがビルドされる
module.exports = { generate: { routes:[ '/hogehoge', '/fuga/fuga' ] } }
また、ファイル数が多くなって直接編集が面倒になったときは、以下のようにもできる
staticファイル以下のjsonファイルを読み込んでroutingに設定している
const fs =require('fs') const filename = fs.readdirSync("./static/").map(x => x.match(/(.*)(?:\.([^.]+$))/)[1]) module.exports = { generate: { routes: filenames } }
ホットリロードで開発サーバをたてる
npm run dev
listen portを開ける
上記のnpm run devでデバッグサーバをたてることが可能になるが、デフォルトではlocalhostからしかアクセスできない。
なのでnuxt.config.jsで以下のように指定する
module.exports = { server: { host: '0.0.0.0' } }
rss.xmlを設定する
nuxt generate時にrss.xmlを更新する方法
まずstatic/rss.xmlを作る
<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0"> <channel> <title>My Home Page</title> <link>https://my-home-page.com/</link> <description>このページはぼくのホームページぃぃぃ!!!</description> <lastBuildDate>${generate by modules}</lastBuildDate> <language>ja</language> <item> <title>日記</title> <link>https://my-home-page/blog/</link> <description>はじめての日記</description> <pubDate>Fri, 01 Mar 2019 18:00:00 +0900</pubDate> </item> </channel>
このstaticファイルの内容はコンパイルされずにそのままdist以下に配置されるので、
nuxt generateが終わった時点で${generate by modules}のところを書き換えてやればよい
modules/hook/generate.js
require('date-utils') const fs = require ('fs') const now = new Date() const rss = fs.readFileSync("static/rss.xml", "utf-8").replace("<lastBuildDate>${generate by modules}</lastBuildDate>", `<lastBuildDate>${now.toFormat('DDD, DD MMM YYYY HH24:MI:SS +0900')}</lastBuildDate>`) module.exports = function () { this.nuxt.hook('generate:done', async generator => { fs.writeFileSync("dist/rss.xml", rss); }) }
moduleを書いたら、nuxt.config.jsで指定する
module.exports = { modules: [ '@/modules/hook/generate' ] }
bootstrapを読み込む際に二重で読み込まれるのを防ぐ
nuxt.config.js modules.exports = { modules: [ ['bootstrap-vue/nuxt', { css: false }] ] }
v-if/v-else-if/v-else
コンポーネント等の表示切替をv-if等を使って切り替えることができる
<template> <div> <img v-if="this.type==='image'" :src="src"></img> <video v-else-if="this.tyep==='movie'" :src="src" autoplay loop muted></video> <p v-else>missing media</p> </div> </template> <script> export default { props: { type: String, link: String }, data() { return { src: require(`~/assets/img/${this.link}`) } } } </script>
v-for内でv-ifを使う
v-forとv-ifを同じ要素内で使うことは推奨されていない
<template> <div> <div v-for="(value, index) in objects"> <div v-if="value">aaa</div> <div v-if="index===0">bbb</div> </div> </div> </template>
外部リソースを読み込む(bootstrapとかjqueryとか)
<script> export default { head () { return { script: [ { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' }, { src: 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js' } ], link: [ { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' } ] } } } </script>
custom layoutを読み込む
<script> export default { layout: 'custom' } } </script>
▼404ページの作成
pages/404/index.vueに作成する
▼動的ルーティングで値を受け取る
pages/_id.vue
<template> <div> {{parameter}} </div> </template> <script> export default { asyncData({ params }) { return { parameter: params.id } } } </script>