[Nuxt.js]雑記。Createdとmounted、$elと$refなど

Nuxt.jsのCreatedとmounted、$elと$refについての備忘録。
Nuxtについて調べていると、Vue.jsのドキュメントの方が充実しているため、Nuxtでの適用方法が分からなかったりする。
基本的にはVue.jsと同じ仕組みだが、ここではNuxtでの書き方・特徴にフォーカスして書く。

免責
初学者です。間違っていたらご指摘ください。

Created \ mountedの違い

Vueでel: '#app',と書くと、それはVueインスタンスそのものを指す。

<script>
new Vue({
    el: '#app',
}) 
</script>

Nuxt
mountedやcreatedでの挙動を確かめようと思い、以下のようにしてみる。Nuxtでは、Vueをnewしたりel: '#app',を定義する必要はない。デフォルトでされる。

created() {
    console.log('created')
    console.log(this.$el)
},
mounted() {
    console.log('mounted')
    console.log(this.$el)
},

結果

created
undefined
mounted
▶︎<div></div>

ここで使用した$elは、DOMに直接アクセスして取得し(ようとし)た、Vueインスタンスcomponentsのルート(html要素の最上位)。

Nuxtライフサイクルでは、createdがDOM生成、mountedがDOM生成(直)後とされているため、createdで定義したthis.$elはundefinedになる。

余談

では、Vueにおけるel: '#app',をNuxtで取得したい場合はどういう風に書けばいいのかというと、thisを使えば良い。

export default {
    data() {
        return {
            el: this,
        }
    },
    created() {
        console.log('created')
        console.log(this.el)
    },
}

VueインスタンスそのものであるthisはDOMを参照しないのでcreatedでもmountedでも結果は同じ。

結果

created
▶︎ VueComponent&nbsp;{_uid: 34, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…},&nbsp;…}

なので、関数内などでもVue componentを使いたい、このthisの挙動を変えたくない場合などは、data内でself: thisとかなんとか定義しておいて、thisの代わりにself.hogeなどとする方法もある。って母方のばーちゃんが言ってた。

ちょっと脱線(computed vs methods)

computed

computedは、計算機能付きのプロパティである。
getterとsetterがあり、get()/set()を省略するとcomputedはgetterとなる。
変数への代入はsetterで行い、getterでは基本的にグローバルな変数への代入はできない。
どうしてもgetterで代入を行いたい時は関数を用意する。
計算結果をキャッシュするので、再計算が必要ない場合、一度行った計算結果を返す速度が速い。プロパティなので呼び出し時は()不要。
以下Nuxt componentに渡した値を変更する例。依存関係にある値が変わった時に自動計算したい時などにピッタリ!

<template>
  <div>
    <v-text-field
      :id="id"
      v-model="innerValue"
      :label="label"
      @input="input"
    ></v-text-field>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: [String, Number],
      default: '',
    },
    id: {
      type: String,
      default: '',
    },
    label: {
      type: String,
      default: '',
    },
    input: {
      type: Function,
      // eslint-disable-next-line
      default: () => {},
    },
  },
  computed: {
    innerValue: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit('input', val)
      },
    },
  },
}
</script>

関数にする場合

computed: {  // 関数として実装、参照時はプロパティとして機能
&nbsp;&nbsp;&nbsp;&nbsp;算出プロパティ名: function() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// return ...
}

methods

一方、メソッドはgetterのみ。setterは使えない。呼び出し時は <button @click="メソッド名()">送信</button>のように()が必要。
送信ボタンが押された時、など、アクションが起きた時の処理にピッタリ!

methods: {
&nbsp;&nbsp;&nbsp;&nbsp;メソッド名: function() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 処理
}

\$elと\$ref

\$elも\$refもVueインスタンスが持つプロパティ。他にも以下のようなものがある。

  • $data
  • $props
  • $el
  • $options
  • $parent
  • $root
  • $slots
  • $refs
  • $attrs

\$el

ここで使用した$elは、DOMに直接アクセスして取得し(ようとし)た、Vueインスタンスcomponentsのルート(html要素の最上位)。

先に述べたように、\$elは要素の最上位であるルート(html)のDOM要素。型はany

\$ref

一方\$refはref属性をつけたDOM要素とcomponentインスタンスのオブジェクト。
htmlにおけるidのようなもので、ref=""の形で要素にツバをつけておいて、\$refで要素を参照できる。型はobject。

<template>
    <button ref="hello">Hello</button>
</template>
<script>
  mounted() {
    console.log('$refs')
    console.log(this.$refs.hello)
  },
</script>

結果

$refs
▶︎ VueComponent&nbsp;{_uid: 83, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…},&nbsp;…}

参考

# 【Vue.js】createdとmountedの違い
# 【Vue.js】 DOMを直接操作 $el $ref
# 【Vue】getterとsetterの使い方。大元の変数を間接的に変更する方法
# Vueのcomputedとmethodsの「使い分け」を解説
# インスタンスプロパティ($data、$props、$el、$options、$parent、$root、$slots、$refs、$attrs) [Vue.js]

[Nuxt.js]FusionCharts導入覚書 – Vueフレームワーク編

前回書いた[Nuxt.js]FusionCharts導入覚書 – Plain javascript編のvueバージョンです。

以前はVueフレームワークバージョンのfusionChartsを使うと動かなかったのですが、大先輩の偉大な助けにより解決したので備忘録。
結論から言うと、FusionChartsのプラグイン化が必要でした。

Vueを使っている人は、シンプルにこちらを参照すれば実装できると思います。
https://cfusioncharts.com/dev/getting-started/vue/your-first-chart-using-vuejs

バージョン

  • MacOs 12.1
  • node v16.2.0
  • yarn 1.22.10
  • nuxt 2.15.7
  • fusioncharts 3.18.0

ライブラリを追加

fusionchartsは3系だとエラーが出るので2系に。該当のプロジェクト内で下記を実行。

$ yarn add fusioncharts
$ yarn add 'vue-fusioncharts@^2.0.4'

npm の人

$ npm install fusioncharts vue-fusioncharts --save
$ npm install vue-fusioncharts@^2.0.4' --save

plugins/fusioncharts.js

pluginsにDependencyを追加。
チャートの種類などはここに記載されている。
https://www.fusioncharts.com/dev/chart-guide/list-of-charts

import Vue from 'vue'
import VueFusionCharts from 'vue-fusioncharts'
import FusionCharts from 'fusioncharts'
import Charts from 'fusioncharts/fusioncharts.charts'
import FusionTheme from 'fusioncharts/themes/fusioncharts.theme.fusion'

Vue.use(
  VueFusionCharts,
  FusionCharts,
  Charts,
  FusionTheme
)

nuxt.config.js

plugins: [{ src: '~/plugins/fusioncharts.js', ssr: false }],

pages/chart.vue

ページ名はなんでもいいですが…

<template>
  <div>
    <Header></Header>
    <section class="container">
      <client-only>
        <div>
          <fusioncharts
            :type="type"
            :width="width"
            :height="height"
            :dataFormat="dataFormat"
            :dataSource="dataSource"
          ></fusioncharts>
        </div>
      </client-only>
    </section>
  </div>
</template>

<script>
export default {
  data() {
    return {
      width: '100%',
      height: '400',
      type: 'column2d',
      dataFormat: 'json',
      dataSource: {
        'chart': {
          'caption': 'Countries With Most Oil Reserves [2017-18]',
          'subCaption': 'In MMbbl = One Million barrels',
          'xAxisName': 'Country',
          'yAxisName': 'Reserves (MMbbl)',
          'numberSuffix': 'K',
          'theme': 'fusion',
        },
        'data': [
          {
            'label': 'Venezuela',
            'value': '290',
          },
          {
            'label': 'Saudi',
            'value': '260',
          },
          {
            'label': 'Canada',
            'value': '180',
          },
          {
            'label': 'Iran',
            'value': '140',
          },
          {
            'label': 'Russia',
            'value': '115',
          },
          {
            'label': 'UAE',
            'value': '100',
          },
          {
            'label': 'US',
            'value': '30',
          },
          {
            'label': 'China',
            'value': '30',
          },
        ],
      },
    }
  },
}
</script>

[Nuxt2]初期設定備忘録

nuxt.jsのプロジェクトを作成するたびに前回の作成から時間が空いてしまい、「あれ初期設定どうしてたっけ」となりがちなので自分用に備忘録。

  • OS MacOS Monterey 12.1
  • Node v16.2.0
  • npm 7.20.0
  • Nuxt.js 2.15.7

まずはプロジェクト作成

$ npm init nuxt-app test-project

設定項目

画像でドン!

参考

https://ma-vericks.com/blog/nuxt-init/

axios追加

インストール

npm install --save @nuxtjs/axios

nuxt.config.jsに追記

  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    "@nuxtjs/axios",
  ],

参考

https://public-constructor.com/nuxtjs-with-axios/

vuetifyのdarkモードをfalseに

フレームワークでvuetifyを選択した場合、dark modeがtrueになっているので設定を削除しtrueをfalseに書き換え。

  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    theme: {
      dark: false,
    },
  },

いらないものを削除

デフォルトの要素たちにセイ・グッバイ

layouts/default.vueの中身にさよなら

<v-app></v-app>の中をざっくり消して、<Nuxt />だけ残す。今回はVuetifyのサイジングを使用するので<v-main><v-container>も残しました。footerはコンポーネント実装にするなら消す。今回はlayouts実装でいいや。ということで残した。

// layouts/default.vue
<template>
  <v-app>
    <v-main>
      <v-container>
        <Nuxt />
      </v-container>
    </v-main>
    <v-footer :absolute="!fixed" app>
      <span>&copy; {{ new Date().getFullYear() }}</span>
    </v-footer>
  </v-app>
</template>

index.vueの中身にさよなら

まっさらな状態に。

<template>
  <div></div>
</template>

components配下のディレクトリパスを設定

atomic designを採用しているが、初期のままだとコンポーネント名の頭にディレクトリ名をつけなければならないため(例<MoleculesHeader />)、パスを通す。nuxt.config.jsに以下を記載。

  components: {
    dirs: [
      '~/components',
      '~/components/atoms',
      '~/components/molecules',
      '~/components/organisms',
    ],
  },

こちらにも書いた

eslintrcのルール変更

console.logなど、よく使用する機能に関してはエラーが出ないよう、.eslintrc.jsにルールを追加しておく。

  rules: {
    'no-console': 'off', // console.log();OK
    'no-unused-vars': 'off', // 使っていない変数あってもOK
    // ↓空白行に対してwarnのみ出るようにする。
    'no-multiple-empty-lines': ['warn', { max: 1 }],
    'no-empty-function': 'off', // 空のfunctionあっても大丈夫
    'spaced-comment': 'off', // //の後にスペースかtabなくてもOK
  },

一旦ここまで。また思い出したら追記。

その他参考

vuetifyについてわかりやすかった記事

https://dev83.com/vue-vuetify-basic/

[Google Tag Manager]GTM操作画面に[プレビュー][公開]ボタンが出てこない

GTMの操作画面にプレビューボタンや公開ボタンが出てこない時、それは[管理]権限が問題です。

結論から言うと、以下2つのどちらかです。

  1. 今操作しているアカウントが管理者権限を持っていない
  2. 管理者権限を持っているが、コンテナ権限が制限されている

本記事は、以下の記事を参考にしています。

Google Tag Manager in View Only Mode? Here’s the fix

1. 今操作しているアカウントが管理者権限を持っていない場合

管理 > ユーザー管理 へ移動し、自分の役割が「ユーザー」になっていないか、確認しましょう。設定したGTMのタグ反映には管理者権限が必要です。もし自分の権限が「ユーザー」だった場合は、管理者権限を持つ人に、設定変更を依頼します。

管理者権限を持っているにも関わらずGTMの操作画面にプレビューボタンや公開ボタンが出てこない場合は次の手順を参照してください。

2. 管理者権限を持っているが、コンテナ権限が制限されている場合

GTMは複数人数で編集することを前提とするため、コンテナごとに権限が設けられています。今回このコンテナに関しては割愛しますが、このコンテナ権限には以下の4つの段階があり、全ての権限を持っていないと、GTMで設定したタグを公開できません。

  • 公開
  • 承認
  • 編集
  • 読み取り

管理者権限を持っているにも関わらず、GTMの公開ボタンが表示されない場合、このコンテナ権限の「公開」権限まで持っていない可能性が高いです。というわけで以下設定方法

管理 > ユーザー管理 へ移動し、任意のアカウントをクリック。

ポップアップに出てきた管理者権限ページから、「コンテナの権限」以下にある設定を反映したいコンテナをクリック。

全てのチェックボックスにチェックを入れて、ページ右上のボタンから「保存」。

 

これで、ワークスペースにプレビューないしは公開公開ボタンが追加されたはずです。

 

 

[Nuxt.js]Take Over Modeって何?って話

https://v3.nuxtjs.org/getting-started/quick-start/

Nuxt.js 3のget startedを読んでいたところ、VSCodeの設定でわからない箇所が。

Prerequisitesに

とあったのでTake Over Modeを入れようと下記URLの内容を参考に取り掛かるも、

https://github.com/johnsoncodehk/volar/discussions/471

How to enable Take Over Mode?に書いてある2のやり方(Run Extensions: Show Built-in Extensions command)がわからなかったのです。

  1. Update Volar to 0.27.17.
  2. Disable built-in TypeScript extension:
    2.1. Run Extensions: Show Built-in Extensions command
    2.2. Find TypeScript and JavaScript Language Features, right click and select Disable (Workspace)
  3. Reload VSCode, and then open any vue file to trigger Volar activation (no longer need in 0.28.4).

Extensions: Show Built-in Extensionsってどうやるんじゃ!!

VSCode

答えはこちらにありました。

https://code.visualstudio.com/docs/editor/extension-marketplace

Extensionsの検索窓から@builtinでフィルターをかけられるよ、というもの。検索結果からTypeScript and JavaScript Language Featuresを探し、右クリックからdisable(Workspace)を選択します。

Run Extensions: Show Built-in Extensions commandなので文字通りコマンドからやる方法があるんでしょうけど、わからなかったので手動です。

誰か賢い方、教えてください。

nodenv,anydenvを使ったNode.jsのアップデート

Nuxt.js 3が出ましたね。

https://v3.nuxtjs.org/getting-started/quick-start

でもnodeバージョンは14.16 か 16.11. 以上でないとダメらしいです。

* If you already have Node.js installed, check with node --version that you are using version 14.16 or above 16.11.

nodenv install --list

で、今入っているバージョンを確認。しかし、nodenvはインストール時に登録されているバージョンしか表示されないそう。

というわけでnodeをバージョンアップします。

以前、node.jsのバージョン切り替え方法を書いたのですが、

[node.js]バージョン切り替え方法

nodenv,anydenvが入っている方は

anyenv update

これでOK!

あとはもう一度インストール済のバージョンを確認いただいて、インストール。

nodenv install --list
nodenv install 18.4.0

バージョンを上げたいプロジェクトディレクトリで切り替えます。

nodenv local 18.4.0 node -v

 

おしまい。

おまけ

18.4.0でnuxt 3動きましたよ!!

npx nuxi init nuxt-app

VSCodeでnuxt-appフォルダをOpenし、dependenciesをインストール。

npm install

devサーバでスタート。

npm run dev -- -o

めちゃめちゃエラー出るやないかい!!

でも起動はする。

めでたしめでた…し?