20210112のvue.jsに関する記事は7件です。

laravel8 + vue.js2.6の.nativeの使い方

この本を書いたきっかけは?何についての記事?

「これから始める、Vue.js実践入門」(山田祥寛/著、SBクリエイティブ株式会社/発行)のリスト4-15~16あたりをlaravel8のプロジェクト内でやりたかったので、コードを少し改変してみた。

参考にしたリンク

https://qiita.com/b1san/items/6bc0be17cd6ed687520c

MyComponent3.vue
<template>
  <div>
    <mycomponent4 v-on:focus.native="onfocus"></mycomponent4>
  </div>
</template>

<script>
import mycomponent4 from './MyComponent4.vue';
export default {
components: {mycomponent4},
 data: function () {
    return {
        current: 0,
    }
 },
  methods: {
    onfocus: function (e) {
      console.log(e);
    }
  },
};
</script>
MyComponent4.vue
<template>
<input type="text" />
</template>
<script>
export default {
 data: function () {
    return {
        // current: 0,
    }
 },

    // props: ['step'],
    methods: {
    }
};
</script>
app.js
require('./bootstrap');
import Vue from 'vue'
import App3 from './components/MyComponent3.vue'
const app3 = new Vue({
    el: '#app3',
    components: {
         App3
    },
});
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue 3.x [Vue warn]: inject() can only be used inside setup() or functional components.の解消法

発生する問題

async setup関数(正確にはPromiseを返すsetup関数)内でinjectを使用すると下記のエラーに遭遇することがあります。

import { defineComponent, inject } from 'vue'
import axios from 'axios'
import { key } from '@/store/user'

export default defineComponent({
  async setup () {
    const { data } = await axios.get('http://example.com')
    const userStore = inject(key)

    if (!userStore) {
      throw new Error(`${key} is not provided`)
    }

    return {
      userStore
    }
  }
})
[Vue warn]: inject() can only be used inside setup() or functional components.

解決策

injectを呼び出す箇所を、awaitより前にするとエラーが発生しなくなります。

import { defineComponent, inject } from 'vue'
import axios from 'axios'
import { key } from '@/store/user'

export default defineComponent({
  async setup () {
    const userStore = inject(key)

    if (!userStore) {
      throw new Error(`${key} is not provided`)
    }

    const { data } = await axios.get('http://example.com')

    return {
      userStore
    }
  }
})

Vue Router・Vuexを呼び出す際にも注意

useRoute()useRouter()またはuseStore()は内部でinjectを使用しているので、同じ問題に遭遇します。

import { defineComponent } from 'vue'
import axios from 'axios'
import { useRouter } from 'vue-router'

export default defineComponent({
  async setup () {
    const { data } = await axios.get('http://example.com')
    const router = useRouter
  }
})

こちらも同様に呼び出し順を変更すればOKです。

import { defineComponent } from 'vue'
import axios from 'axios'
import { useRouter } from 'vue-router'

export default defineComponent({
  async setup () {
    const router = useRouter
    const { data } = await axios.get('http://example.com')
  }
})
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laraval8 + vue.js2.6で、親子(parent-child)component間の通信について(propsや$emitを使わない場合=>.nativeの使い方)

この本を書いたきっかけは?何についての記事?

「これから始める、Vue.js実践入門」(山田祥寛/著、SBクリエイティブ株式会社/発行)のリスト4-16あたりをlaravel8のプロジェクト内でやりたかったので、コードを少し改変してみた。

参考にしたサイトなど

前に挙げた本以外、忘れてしまいました。思い出したら追記するかもです。

前置きはこれくらいにして

MyComponent3.vue
<template>
  <div>
    <div>
      <p>現在値{{ current }}</p>
    </div>
    <mycomponent4 step="1" v-on:click.native="onclick"></mycomponent4>
    <mycomponent4 step="2" v-on:click.native="onclick"></mycomponent4>
    <mycomponent4 step="-1" v-on:click.native="onclick"></mycomponent4>
  </div>
</template>

<script>
import mycomponent4 from './MyComponent4.vue';
export default {
components: {mycomponent4},
 data: function () {
    return {
        current: 0,
    }
 },
  methods: {
    onclick: function (e) {
      this.current += Number(e.target.childNodes[0].nodeValue);
      //console.log(e);
      console.log(Number(e.target.childNodes[0].nodeValue));
    },
  },
};
</script>

.nativeってのがミソで、これがないと動きません。
e.target.childNodes[0].nodeValueってのがボタンに表示されてる値を指すわけですが、
これが正確にどう指定すればよいかはconsole.log(e);してからchromeのdevtoolでeの中身をポチポチ開いていった後に、右クリックで「Copy property path」すると間違いがなくて安心です。

MyComponent4.vue
<template>
<button type="button" v-on:click="onclick">{{ step }}</button>
</template>
<script>
export default {
 data: function () {
    return {
        current: 0,
    }
 },

    props: ['step'],
    methods: {
        onclick:function() {
            this.$emit('plus', Number(this.step));
        }
    }
};
</script>
app.js
require('./bootstrap');
import Vue from 'vue'
import App3 from './components/MyComponent3.vue'
const app3 = new Vue({
    el: '#app3',
    components: {
         App3
    },
});

Controllerとか、実際の画面の動きとかはhttps://qiita.com/tarako2/items/942b1c5d9af9bb4bf946
と一緒なので参考にされてください。
ここまで見ていただいてありがとうございました。何かお役に立てれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laraval8 + vue.js2.6で、親子(parent-child)component間の通信について(propsや$emitを使わない場合)

この本を書いたきっかけは?何についての記事?

「これから始める、Vue.js実践入門」(山田祥寛/著、SBクリエイティブ株式会社/発行)のリスト4-16あたりをlaravel8のプロジェクト内でやりたかったので、コードを少し改変してみた。

参考にしたサイトなど

前に挙げた本以外、忘れてしまいました。思い出したら追記するかもです。

前置きはこれくらいにして

MyComponent3.vue
<template>
  <div>
    <div>
      <p>現在値{{ current }}</p>
    </div>
    <mycomponent4 step="1" v-on:click.native="onclick"></mycomponent4>
    <mycomponent4 step="2" v-on:click.native="onclick"></mycomponent4>
    <mycomponent4 step="-1" v-on:click.native="onclick"></mycomponent4>
  </div>
</template>

<script>
import mycomponent4 from './MyComponent4.vue';
export default {
components: {mycomponent4},
 data: function () {
    return {
        current: 0,
    }
 },
  methods: {
    onclick: function (e) {
      this.current += Number(e.target.childNodes[0].nodeValue);
      //console.log(e);
      console.log(Number(e.target.childNodes[0].nodeValue));
    },
  },
};
</script>

.nativeってのがミソで、これがないと動きません。
e.target.childNodes[0].nodeValueってのがボタンに表示されてる値を指すわけですが、
これが正確にどう指定すればよいかはconsole.log(e);してからchromeのdevtoolでeの中身をポチポチ開いていった後に、右クリックで「Copy property path」すると間違いがなくて安心です。

MyComponent4.vue
<template>
<button type="button" v-on:click="onclick">{{ step }}</button>
</template>
<script>
export default {
 data: function () {
    return {
        current: 0,
    }
 },

    props: ['step'],
    methods: {
        onclick:function() {
            this.$emit('plus', Number(this.step));
        }
    }
};
</script>
app.js
require('./bootstrap');
import Vue from 'vue'
import App3 from './components/MyComponent3.vue'
const app3 = new Vue({
    el: '#app3',
    components: {
         App3
    },
});

Controllerとか、実際の画面の動きとかはhttps://qiita.com/tarako2/items/942b1c5d9af9bb4bf946
と一緒なので参考にされてください。
ここまで見ていただいてありがとうございました。何かお役に立てれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsのv-ifで画面に表示される内容を切り替える

初めに

前回に引き続きVue.jsで学んだことのアウトプットとして投稿します。

v-if

js ファイルにある mode の値を変えることで画面に表示する内容を切り替えることができる。
key="night-comment"key="mornig-comment" により、ボタンを押した後、テキスト欄にそのまま文字が残らないようにする。これは以下のように公式ドキュメントにある方法を利用した。

一意の値を持つ key 属性を追加する

v-on ディレクティブにより js ファイルにあるメソッドを呼び出し mode の値を変える。

  <div id="app" v-bind:style="styles">
    <template v-if="mode === 'night'">
      <input placeholder="夜の一言" key="night-comment">
    </template>
    <template v-else>
      <input placeholder="朝の一言" key="mornig-comment">
    </template>
    <button >コメントする</button>
    <br>
    <button 
      v-on:click="toggle"
      v-if="mode === 'night'"
      v-bind:style="buttonStyles">朝へ</button>
    <button
      v-on:click="toggle" 
      v-else
      v-bind:style="buttonStyles">夜へ</button>
  </div>

v-bind ディレクティブによりスタイルも切り替える。data の中に stylesbuttonStyles を入れ、html ファイルの v-bind と連携させる。

var app = new Vue({
  el: '#app',
  data: {
    mode: '',
    styles: {
      backgroundColor: 'rgb(240, 210, 220)',
      padding: '50px'
    },
    buttonStyles: {
      margin: '30px 0px'
    }
  },
  methods: {
    toggle: function() {
      if (this.mode === 'night') {
        this.mode = 'mornig';
        this.styles.backgroundColor = 'rgb(240, 210, 220)'
      } else {
        this.mode = 'night';
        this.styles.backgroundColor = 'rgb(10, 10, 30)'
      }
    }
  }
})

動作結果

  • 画面更新後

image.png

  • 夜へボタン押下後

image.png

  • 朝へボタン押下後

image.png

参考記事

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Snowpack で React・Vuejs・Svelte を動かしてみる

Snowpack とは

webpack や rollup などの代替として利用できるフロントエンドの依存解決を行うビルドツール、モジュールバンドラではなく、コードを ESM 形式に変換してモジュールとして利用できるようにする。

参照:Snowpack公式サイト


ES Modules までの歴史

  1. NodeJS が誕生、CommonJS を基にしたモジュール機能を実装
  2. RequireJS が誕生、AMD をブラウザ用に変換する
  3. Browserify が誕生、CommonJS をブラウザ用に変換する
  4. CommonJS でも AMD でも使える UMD が誕生
  5. Webpack が誕生、やたらと多機能で実質的にデファクト環境となる
  6. ES Modules の策定

つまり現状では CommonJS(CJS)、AMD、UMD、ES Modules(ESM) の4種類のモジュール形式が存在することになります。


ES Modules の誕生

フロントエンドの複雑化・肥大化にともなって ES Modules(ESM) という仕様が策定された、これは 2021年現在では既に Microsoft Edge を含む IE 以外のブラウザでは対応されており、Nodejs でも v12 以降は標準対応している。

参照:MDN - JavaScript モジュール


普及しない ES Modules

じゃあ依存ファイルを ESM でガンガン import すれば良いよね!としたいところだったが、 いくつかの問題が存在していた。

  1. webpack 等のバンドラが開発環境として普及してしまっている
  2. npm で提供されているライブラリの多くが ESM に対応していない
  3. import に対応していないブラウザに対する互換性がまるでない

そして Snowpack の登場

ここで前述の問題を解決するための新たな手段として注目されているのが Snowpack というビルドツールで、これは単純にいうと npm ライブラリを ESM 形式に変換して出力するというビルドツールである。

※これはつまり ESM をサポートしている Deno でも npm の資産が使えるようになることも意味しています。

なお現状ではファイルのバンドルだけではなく、JSX や Vue テンプレートファイルの変換とかもしてると思うので、それらの対応についても解説しておきます。


フレームワークへの対応

Snowpack には create-snowpack-app というボイラープレートが存在しており、簡単にいうと React や VueJS などのフレームワークを Snowpack で変換する際の開発環境があらかじめ用意されています。

これにより JSX や Vueファイル、Svelteファイルの変換などが行えます。

create-snowpack-app のテンプレート一覧はこちら


React

Reactの例
npx create-snowpack-app yourappname --template @snowpack/app-template-react
React+TypeScriptの例
npx create-snowpack-app yourappname --template @snowpack/app-template-react-typescript

Vue

Vueの例
npx create-snowpack-app yourappname --template @snowpack/app-template-vue
Vue+TypeScriptの例
npx create-snowpack-app yourappname --template @snowpack/app-template-vue-typescript

Svelte

Svelteの例
npx create-snowpack-app yourappname --template @snowpack/app-template-svelte
Svelte+TypeScriptの例
npx create-snowpack-app yourappname --template @snowpack/app-template-svelte-typescript

WebWorker 対応

2021年1月現在では WebWorker 内での ES Modules は全てのブラウザで対応しているわけではありません、これに関しては、Snowpack v 3.0.0Snowpack Webpack v5 plugin の両方で自動的にバンドルファイルを出力するようになりました。

Web Workers - Snowpack


IE対応

npm snowpachk --nomodule

でレガシーブラウザ用に旧来のようにバンドルしたJSファイルを出力できるが、ドキュメントに書いてない気がする。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フロントエンドのコンポーネントの分け方の勉強

Vue.jsのコンポーネント設計について勉強

単一コンポーネントの原則は理解したけどじゃあ具体的にどうコンポーネントを作ったらいいの?という問いにぶち当たった。

https://qiita.com/seya/items/8814e905693f00cdade2

こちらの記事がわかりやすかったのでこれを自分なりに要約していこうと思う。

コンポーネントとは?

アプリの見た目を作る構成部品。

コンポーネントを作る目的

アプリの見た目を作る上では同じような部品がくり返し使われることが多々ある(フォームの送信ボタンなど) 。このような要素を一つの部品の単位として分けて作成することで再利用性やデザインのしやすさを高めるためにコンポーネントを利用する。

コンポーネントの構成要素

以下の4つ。今回は①について見る。

  1. 情報構造
  2. スタイル
  3. 状態
  4. インタラクション・機能

①情報構造

HTMLのこと。どのような単位で部品を分けるのか?ということですね。

Atomic Design

見た目を作るHTMLをどのような単位で分けるのか?についての最もメジャーな考え方の一つ。

1_j1P0pjQtl36QJavv8lHdyw.png

--機能の役割--

Atoms(原子)…最小単位。それ以上分割できないボタンやテキストなど

Molecules(分子)…Atomを組み合わせて作られる要素。フォームなど

--レイアウトの役割--

Organisms(組織)…MoleculesやAtomsを組み合わせて作られる要素。ヘッダーなど。Moleculesと違い、複数の機能を担う

Template…Organismsを組み合わせたもの。いわゆるワイヤーフレーム。見た目の骨格の部分

Pages…実際の文言がTemplateに組み込まれたもの。つまり実際のページ

単一責任の原則

コンポーネントは一つのことに責任を持つべき。つまりコンポーネントの役割は一つにしぼりましょう、ということ。

コンポーネントの役割を一つに絞るべき理由は、ページによって再利用したりユーザーの状態に応じてページに表示する内容を変えたりする必要がある時にコンポーネント内部に条件分岐などを入れたりする必要が出てくるから。これでは開発しにくい。この考え方はAtomsやMoleculesの設計では特に重要。

じゃあOrganisms以上はどうすんのという話ですがこれは「アプリの見た目を一意に担うこと」を単一責任、とすれば考えやすそう。つまりヘッダーやフッターなどの部品がページによってデザインが変わったりしないということ。機能に対しての一意性を担っているのはあくまでAtomsやMoleculesなんですね。

じゃあ実際どう実装していくの?

ここまで理解したところでどう実装するのかですが、以下のようにやると進めやすそう(感想)
①設計書なり仕様書をみて部品の最小単位を割り出す
②最小単位で設計した際のスタイルを考える
③②で考えたスタイルのうち親要素に持たせたほうがよいものを選び親要素に持たせる

みたいな感じ。スタイルに関しても定義の仕方にルールがあるようなのでこちらは明日以降勉強していく。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む