20190714のvue.jsに関する記事は11件です。

[vue.js][typescript] Functional Componentを生成するコンポーネントを

Vue.jsは他のFrameWorkより不便な事はFunction型のコンポーネントを作成する事が面倒だと思います。

Function型のなぜ必要か?

  • 作成したコンポーネントの内部に簡単なコンポーネントを追加したり(コンポーネントのファイル増やしたくない)

この理由で作りました。簡単にパラメタ(props)を設定後Template返したらコンポーネントが生成完了です。

@Renderデコレーター利用方法

<template>
  <good :items="data" title="Title Prop"></good>
</template>
import {Render} from 'vue-corator'
@Component
export default class YourComponent extends Vue {

    private data = ['hello', 'function render'];

    @Render()
    private good(itmes:any, title:any) {
      return `
              <ul>
              <li v-for="item in items">
              {{ title }} {{ item }}
              </li>
              </ul>`;
    }
}

Decoratorのコード
https://github.com/joon610/vue-corator
https://www.npmjs.com/package/vue-corator

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

[vue.js][typescript] Functional Componentを生成するコンポーネントを作りました

Vue.jsは他のFrameWorkより不便な事はFunction型のコンポーネントを作成する事が面倒だと思います。

Function型のなぜ必要か?

  • 作成したコンポーネントの内部に簡単なコンポーネントを追加したり(コンポーネントのファイル増やしたくない)

この理由で作りました。簡単にパラメタ(props)を設定後Template返したらコンポーネントが生成完了です。

@Renderデコレーター利用方法

<template>
  <good :items="data" title="Title Prop"></good>
</template>
import {Render} from 'vue-corator'
@Component
export default class YourComponent extends Vue {

    private data = ['hello', 'function render'];

    @Render()
    private good(itmes:any, title:any) {
      return `
              <ul>
              <li v-for="item in items">
              {{ title }} {{ item }}
              </li>
              </ul>`;
    }
}

Decoratorのコード
https://github.com/joon610/vue-corator
https://www.npmjs.com/package/vue-corator

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

nuxt.js × Atomic Design での component 作成にhygenを使ってみる

nuxt × atomic design でのコンポーネントを量産していく過程で、
.vueファイルと storybookのjsファイルを hygen で生成していくフローが楽だったので、やり方をメモ。

storybookのドキュメント通りに始めると、
出力サンプルが /stories/ dirができ、そこに書いてくような形で始まる。

前提として、 .stories.js.vue ファイルは同じdirに収納していく形にする方が、管理しやすい用に思います。(違う?)
手動でやると大変、ミスもあるので、hygenを使い、この部分を自動化します。

hygenとは

hygen.png

Hygenとはコマンドラインからファイルを生成する対話式のコードジェネレーターのパッケージです。

参考 : https://qiita.com/usagi-f/items/ea4ecf7ec6a6b52567e3

nuxtとstorybookをセットアップ

まずはnuxtをセットアップ

サクッといれます。

$ npx create-nuxt-app <project-name>
$ cd <project-name>
$ npm run dev

動いた。

storybookのインストールとコンポーネントの作成

公式のドキュメント を参考に、今回は Manual setup(手動方式)でいれてみる。

スクリプトを入れる

$ npm install @storybook/vue --save-dev

$ npm install vue --save
$ npm install vue-loader vue-template-compiler @babel/core babel-loader babel-preset-vue --save-dev

package.jsonにコマンドを追加。今回はこんな感じで追加してみる。

package.json
{
  "scripts": {
    "storybook": "start-storybook -s ./static -p 3001 --ci",
    "build-storybook": "build-storybook -c .storybook"
  }
}

configをつくる

/.storybook/config.js を作成。

/.storybook/config.js
import { configure } from '@storybook/vue';

function loadStories() {
  // こちらを消し
  // require('../stories/index.js');

  // /components/ 配下の .stories.js を対象
  const req = require.context('../components', true, /\.stories\.js$/);
  req.keys().forEach(filename => req(filename));

}

configure(loadStories, module);

実際にはここでaddons.jsに、storybookのaddonを入れていくと思いますが、割愛。

vue開発で約に立ちそうなaddonの参考 :
https://qiita.com/asdfghjkl1234/items/3c7580718715c275a729

Atomic Design のルールに沿って、コンポーネントを作ってみる。

プロジェクト毎に微妙にルールが異なると思いますが、今回は/components/配下を以下のような、atom等の各粒度の配下に、「サブカテゴリ」を設けたルールにしてみます。
.stories.js も各コンポーネントとセットで定義していく。

components
├── atoms
│   ├── buttons
│   │   └── MyButton
│   │       ├── MyButton.stories.js  // ← ここ
│   │       └── MyButton.vue
│   ├── texts
│   │   └── MyText
│   │       ├── MyText.stories.js  // ← ここ
│   │       └── MyText.vue
│   ├── forms
│   ├── ... その他プロジェクトで必要なサブカテゴリ
│   └── others
├── molecules
├── organisms
├── pages
└── templates

最小限のコンポーネントを作成。
例として MyButton.vueMyButton.stories.js

MyButton.vue
<template>
  <button class="my-button"><slot></slot></button>
</template>

<script>
export default {
  name: 'MyButton'
}
</script>

<style scoped>
.my-button{}
</style>
MyButton.stories.js
import { storiesOf } from '@storybook/vue'
import MyButton from './MyButton'

storiesOf('atoms/buttons/MyButton', module)
  .add('default', () => ({
    components: { MyButton },
    template: '<MyButton>私はボタンです</MyButton/>'
  }))

必要ファイルができたら以下で実行。

$ npm run storybook

package.jsonで指定した http://localhost:3001 へアクセスすると無事見れました。

スクリーンショット 2019-07-14 18.53.36.png

hygenをセットアップ

こちらも 公式ドキュメント通りに

$ cd <project-name>
$ npm i -g hygen
$ hygen init self

すると以下のような dir が作られる。

_templates
└── generator
    ├── help
    │   └── index.ejs.t
    ├── new
    │   └── hello.ejs.t
    └── with-prompt
        ├── hello.ejs.t
        └── prompt.ejs.t

/_templates/generator/ 以下はサンプルファイルの様子。
hygenのジェネレーターは以下のようなルールになってるらしい。

hygen <generator> <action> [NAME]

サンプルは無視して、 Atomic Designのコンポーネントを作るので、以下のような3ファイルでテンプレートファイルを準備する。

_templates
└── component
    └── new
        ├── prompt.js
        ├── story.ejs.t
        └── vue.ejs.t
prompt.js
// 対話式の設問でAtomic Designのコンポーネントを定義します

module.exports = [
  {
    type: 'select',
    name: 'category',
    message: '作成する Atomic Design のカテゴリを選択',
    choices: ['atoms', 'molecules', 'organisms', 'templates', 'pages']
  },
  {
    type: 'select',
    name: 'subcategory',
    message: 'サブカテゴリを選択',
    choices: [
      'no-subcategory', //サブカテゴリに属さない
      'buttons',
      'texts',
      'forms',

      // ... プロジェクトに必要なパーツのサブカテゴリをすべて定義する

      'others'
    ]
  },
  {
    type: 'input',
    name: 'componentname',
    message: 'component名を入力',
    hint: '"FormInputText" ...等(パスカルケース)'
  },

  // ・・・ プロジェクト毎、必要に応じて 設問を追加 ・・・

]
story.ejs.t
---
to: components/<%= category %><% if(subcategory && subcategory!=='no-subcategory'){ %>/<%= subcategory %><% } %>/<%= componentname || 'unnamed'%>/<%= componentname || 'unnamed'%>.stories.js
---
import { storiesOf } from '@storybook/vue'
import <%= componentname %> from './<%= componentname %>'
storiesOf('<%= category %><% if(subcategory && subcategory!=='no-subcategory'){ %>/<%= subcategory %><% } %>/<%= componentname %>', module)
  .add('default', () => ({
    components: { <%= componentname %> },
    template: '<<%= componentname %>/>'
  }))

vue.ejs.t
---
to: components/<%= category %><% if(subcategory && subcategory!=='no-subcategory'){ %>/<%= subcategory %><% } %>/<%= componentname || 'unnamed'%>/<%= componentname || 'unnamed'%>.vue
---
<template>
</template>

<script>
export default {
  name: '<%= componentname %>'
}
</script>

<style scoped>
</style>

hygenを使ってみる

ここまでできたら、hygenコマンドをつかってコンポーネントを作ってみる。

$ hygen component new

上記を実行すると対話式でコンポーネント作成が始まるので、質問に順に答えると、
nuxtの/components/内に新しいファイルが、Atomic Designとして設定したルール通りで新規作成されます。

アイデア次第ではもっと便利に

実際の開発では、templateにもっと大量に設定が追加されるので、新規作成はより便利に感じます。
storybookだけでなく、 jest 等のテストファイルも、テンプレも作っておくと捗ります。

もっと良いアイデアや使い方をご存知の方、コメントを頂ければ幸いです。

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

【iOS対応】Vue.jsで背景固定のモーダルを作る

モーダルを作る際に面倒なのが、スクロールしたときの背景の固定。
別に背景が動いても直接問題が起きることはないのですが、やっぱり気にはなります。ユーザーにもこのサービス大丈夫かな...と余計な不安感を与えることにもなりますし。

ただ、この背景固定、一筋縄ではいかないのが面倒なところ。とくにiOSは他のデバイスと異なる挙動を示し、AndroidやWebではちゃんと固定されるのにiOSだけ上手くいかない...と悩んでいる人も多いと思います。

何か解決方法はないかと探していたところ、非常に便利なライブラリを見つけたので、それで対応することにしました。

Body Scroll Lockを使う

名前の通り、機能を有効にすることで背景のスクロールを無効にできるライブラリです。便利なのは、ページ全てをスクロール無効にするのではなく、指定したDOM内部だけはスクロールできるように設定できること。
モーダル内部はスクロールさせたい!なんてケースにも対応可能ということです。

githubでのスターも1400個以上ついていますし、ある程度安心して導入できるのもメリットですね。公式サイトはこちら↓

Body Scroll Lock

Body Scroll Lockの使い方

何はともあれ、まずはnpm/yarnでinstallしましょう。

npm install body-scroll-lock

次に、背景固定を行いたいページ(コンポーネント)でimportします。

import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';

名前からしてそのままですが、背景を固定したい場合はdisableBodyScrollを、解除したい場合はenableBodyScrollを使えばOKです。

たとえば、モーダルコンポーネントに使うならこんな感じ。

ModalLayout.vue
<template>
  <div class="modal-layer">
    <div class="modal">
      <slot />
    </div>
  </div>
</template>

<script>
import {
  disableBodyScroll,
  enableBodyScroll,
  clearAllBodyScrollLocks
} from 'body-scroll-lock';

export default {
  mounted() {
    const modal = document.querySelector('.modal')
    disableBodyScroll(modal)
  },

  beforeDestory() {
    clearAllBodyScrollLocks()
  }
}
</script>

ModalLayoutは親コンポーネントからv-ifで呼ばれる想定のコンポーネントです。
v-ifがtrueになったときにmounted()が走ることと、falseになるとbeforeDestoryが走ることを利用して、モーダルが表示されている場合にのみ背景が固定されるようにしています。

まとめ

非常にシンプルで使いやすいので、背景固定に困っているケースで便利です。モーダル系ライブラリとも簡単に組み合わせられそうなのも良さそうですね。

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

vueをtypescriptで使っていてCombinedVueInstanceのエラーが出た時の解決方法

↓こんなエラーが出た時の対応策
image.png

package.jsonは以下の通り

  "devDependencies": {
    "@types/dateformat": "^3.0.0",
    "@vue/cli-plugin-typescript": "^3.9.0",
    "@vue/cli-service": "^3.9.2",
    "node-sass": "^4.12.0",
    "sass-loader": "^7.1.0",
    "stats-webpack-plugin": "^0.7.0",
    "typescript": "^3.5.3",
    "vue": "^2.6.10",
    "vue-template-compiler": "^2.6.10",
    "webpack-bundle-analyzer": "^3.3.2"
  }

解決策は、functionに戻り値の型を書く。anyでも良い。

before

  computed: {
    listUlClass: function (){
      return "";
    },
    listLIClass: function () {
      return {};
    },
}

after

  computed: {
    listUlClass: function ():string{
      return "";
    },
    listLIClass: function () :any{
      return {};
    },
}

アロー関数式でない普通のfunctionで戻り値の型を書く発想が無かった・・・。vue3では全部アローで書けるといいな

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

ドキュメントもないナレッジもないチームに捧ぐVue.js社内勉強会を開催した件

【概要】

開発・運用に携わるエンジニアがドキュメントやテストコードも残さず退職した結果、ドキュメントのないサービスの開発・運用にアサインされた経験がある方も多いのではないでしょうか。私の所属するチームの場合はドキュメントもナレッジもないVue.jsの案件が回ってきました。
チームの概要は以下の通りです。

  • メンバー8人(うちマネージャー1人)
  • 全員サーバーサイドエンジニア
  • 普段使う言語はPHP
  • 設計が分からないのか、Vue.jsが分からないのか、JSが分からないのかすら分からないレベル
  • 某RPGで言うとスライムに苦戦するレベル(チーム公式表現)
  • フロントエンドチームは別であり、Vue.jsのナレッジがあるエンジニアもいるが他の案件で忙しいため丸投げできない

この記事ではそんなチームのためにVue.jsの勉強会を行うまでの経緯と勉強会の内容を記載します。

【勉強会にこぎつけた経緯】

チームメンバーの1人が奮闘しGitLab CIによるCI/CD環境を整えるまでに持って行ってくれたため開発・運用が出来る体制はできました。そのため何個か小さい案件のデプロイは行いましたが、そもそもVue.jsのナレッジがないためレビューも機能せず、バグに対する危機察知能力もなりない、その代わりに結合テストで担保するという現状でした。
この現状はさすがにまずいとマネージャーに訴えた結果、理解をいただくことができ業務時間中に週2時間のVue.js勉強会を行う権利を獲得しました。
持ち回りで勉強会を行うことも考えたのですが勉強会が形骸化してしまう可能性が高まると判断して勉強会の裁量は自分に集約させました。
前述の通りスライムにすら苦戦するレベルであるため、せめてバブルスライムくらいには圧勝できるくらいのレベルに持っていくことを目的としました。

【勉強会を始めるまで】

私もVue.jsのナレッジがなかったため、まずは自身のナレッジを高めることから始めました。とりあえず入門書として Vue.js入門 基礎から実践アプリケーション開発まで を土日で読破しました。書籍を選んだ理由は単純で会社にあったからです。

次に勉強会の内容を考えました。大きく分けると講義形式とハンズオンがあると考えましたが、すでに開発案件は回ってきておりすぐにチームのナレッジをためる必要があったためハンズオンを選択しました。
ハンズオンの題材を考えていたところ、初回はProgateを使えば良いんじゃないかと考えProgateを見てみましたがVue.jsは扱っていないようでした。代わりになるサービスを探したところ CODEPREP に行き当たりました。

【CODEPREPとは】

image.png

CODEPREPとはProgateのようにプログラミング言語を修学できるWebサービスで、コードの一部が虫食いになっているため主に予約語を埋めていくことにより修学ができるサービスです。
ドキュメントとエディタ、実行画面が一体化しているため気軽に修学ができます。私が考えるCODEPREPのメリット・デメリットは以下の通りです。

- メリット

  • 開発環境を整えることなく修学ができる
  • ドキュメントを読めば問題がすぐに理解できるため初心者にはオススメ
  • 無料ででき、また選択できる言語・フレームワークも豊富

- デメリット

  • 広く扱っている代わりに浅いため深く理解はできない
  • 穴埋めのため何となくでも正答できてしまう

【勉強会当日】

想定していた勉強会当日の流れは以下の通りです。

  • CODEPREPの「はじめてのVue.js」を修学する(1時間)
  • Todoリストのコードを写経する(15分)
  • 自分が課題を用意したTodoリストの改修を行う(45分)

- CODEPREPの「はじめてのVue.js」を修学する(1時間)

前述の通りCODEPREPの修学を行いました。ただしデメリットにも記載した通り、CODEPREPだけでは浅いため深く理解することが出来ないため都度Vue.jsの公式ドキュメントを読むようにしました。
1時間を想定していたのですが、実際には1時間20分程度かかってしまいました。

- Todoリストのコードを写経する(15分)

「はじめてのVue.js」では最終的にTodoリストを作るのですが、穴埋めで作っていくため出来上がったコードを写経するつもりでした。
しかし、CODEPREPの修学で時間をオーバーしてしまっていたため写経は各自の任意としてコードを共有しました。

- 自分が課題を用意したTodoリストの改修を行う(45分)

CODEPREPおよび写経だけでは自身で考えるといった過程が少ないため課題を3問用意して解かせてみました。用意した課題は以下の3つです。

  • Todoリストの件数を表示する
  • 「〇〇を追加しました」、「〇〇を削除しました」といったTodoリストの操作履歴を表示する
  • 新しく追加したTodoにはNEW!!と表示する

解かせてみた結果として1問目は全員解答出来ましたが、2問目以降は時間が足りませんでした。また私のミスとして2問目より3問目の方が簡単であったため、順番を入れ替えればもう少し解けていたと反省しました。

【勉強会の所感と今後】

初回の勉強会の内容としてCODEPREPを採用し、またデメリットである浅い理解を補うために公式ドキュメントを読むようにしたのは以下の点で良かったと思います。

  • 題材を用意してくれているため自分の負荷が少ない
  • 勉強会がスムーズに進む

今後はVue.jsのふりかえりと時間が足りず解けなかった課題の再挑戦を行ったのちに本格的にTodoリストを作っていこうかと考えています。

もし自分と同じような境遇にいる方は参考にしていただけると幸いです。

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

ドキュメントもないナレッジもないチームに捧ぐVue.js勉強会

【概要】

開発・運用に携わるエンジニアがドキュメントやテストコードも残さず退職した結果、ドキュメントのないサービスの開発・運用にアサインされた経験がある方も多いのではないでしょうか。私の所属するチームの場合はドキュメントもナレッジもないVue.jsの案件が回ってきました。
チームの概要は以下の通りです。

  • メンバー8人(うちマネージャー1人)
  • 全員サーバーサイドエンジニア
  • 普段使う言語はPHP
  • 設計が分からないのか、Vue.jsが分からないのか、JSが分からないのかすら分からないレベル
  • 某RPGで言うとスライムに苦戦するレベル(チーム公式表現)
  • フロントエンドチームは別であり、Vue.jsのナレッジがあるエンジニアもいるが他の案件で忙しいため丸投げできない

この記事ではそんなチームのためにVue.jsの勉強会を行うまでの経緯と勉強会の内容を記載します。

【勉強会にこぎつけた経緯】

チームメンバーの1人が奮闘しGitLab CIによるCI/CD環境を整えるまでに持って行ってくれたため開発・運用が出来る体制はできました。そのため何個か小さい案件のデプロイは行いましたが、そもそもVue.jsのナレッジがないためレビューも機能せず、バグに対する危機察知能力もなりない、その代わりに結合テストで担保するという現状でした。
この現状はさすがにまずいとマネージャーに訴えた結果、理解をいただくことができ業務時間中に週2時間のVue.js勉強会を行う権利を獲得しました。
持ち回りで勉強会を行うことも考えたのですが勉強会が形骸化してしまう可能性が高まると判断して勉強会の裁量は自分に集約させました。
前述の通りスライムにすら苦戦するレベルであるため、せめてバブルスライムくらいには圧勝できるくらいのレベルに持っていくことを目的としました。

【勉強会を始めるまで】

私もVue.jsのナレッジがなかったため、まずは自身のナレッジを高めることから始めました。とりあえず入門書として Vue.js入門 基礎から実践アプリケーション開発まで を土日で読破しました。書籍を選んだ理由は単純で会社にあったからです。

次に勉強会の内容を考えました。大きく分けると講義形式とハンズオンがあると考えましたが、すでに開発案件は回ってきておりすぐにチームのナレッジをためる必要があったためハンズオンを選択しました。
ハンズオンの題材を考えていたところ、初回はProggateを使えば良いんじゃないかと考えProgateを見てみましたがVue.jsは扱っていないようでした。代わりになるサービスを探したところ CODEPREP に行き当たりました。

【CODEPREPとは】

image.png

CODEPREPとはProgateのようにプログラミング言語を修学できるWebサービスで、コードの一部が虫食いになっているため主に予約語を埋めていくことにより修学ができるサービスです。
ドキュメントとエディタ、実行画面が一体化しているため気軽に修学ができます。私が考えるCODEPREPのメリット・デメリットは以下の通りです。

- メリット

  • 開発環境を整えることなく修学ができる
  • ドキュメントを読めば問題がすぐに理解できるため初心者にはオススメ
  • 無料ででき、また選択できる言語・フレームワークも豊富

- メリット

  • 広く扱っている代わりに浅いため深く理解はできない
  • 穴埋めのため何となくでも正答できてしまう

【勉強会当日】

想定していた勉強会当日の流れは以下の通りです。

  • CODEPREPの「はじめてのVue.js」を修学する(1時間)
  • Todoリストのコードを写経する(15分)
  • 自分が課題を用意したTodoリストの改修を行う(45分)

- CODEPREPの「はじめてのVue.js」を修学する(1時間)

前述の通りCODEPREPの修学を行いました。ただしデメリットにも記載した通り、CODEPREPだけでは浅いため深く理解することが出来ないため都度Vue.jsの公式ドキュメントを読むようにしました。
1時間を想定していたのですが、実際には1時間20分程度かかってしまいました。

- Todoリストのコードを写経する(15分)

「はじめてのVue.js」では最終的にTodoリストを作るのですが、穴埋めで作っていくため出来上がったコードを写経するつもりでした。
しかし、CODEPREPの修学で時間をオーバーしてしまっていたため写経は各自の任意としてコードを共有しました。

- 自分が課題を用意したTodoリストの改修を行う(45分)

CODEPREPおよび写経だけでは自身で考えるといった過程が少ないため課題を3問用意して解かせてみました。用意した課題は以下の3つです。

  • Todoリストの件数を表示する
  • 「〇〇を追加しました」、「〇〇を削除しました」といったTodoリストの操作履歴を表示する
  • 新しく追加したTodoにはNEW!!と表示する

解かせてみた結果として1問目は全員解答出来ましたが、2問目以降は時間が足りませんでした。また私のミスとして2問目より3問目の方が簡単であったため、順番を入れ替えればもう少し解けていたと反省しました。

【勉強会の所感と今後】

初回の勉強会の内容としてCODEPREPを採用し、またデメリットである浅い理解を補うために公式ドキュメントを読むようにしたのは以下の点で良かったと思います。

  • 題材を用意してくれているため自分の負荷が少ない
  • 勉強会がスムーズに進む

今後はVue.jsのふりかえりと時間が足りず解けなかった課題の再挑戦を行ったのちに本格的にTodoリストを作っていこうかと考えています。

もし自分と同じような境遇にいる方は参考にしていただけると幸いです。

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

ドキュメントもないナレッジもないチームに捧ぐVue.js社内勉強会を開催開催した件

【概要】

開発・運用に携わるエンジニアがドキュメントやテストコードも残さず退職した結果、ドキュメントのないサービスの開発・運用にアサインされた経験がある方も多いのではないでしょうか。私の所属するチームの場合はドキュメントもナレッジもないVue.jsの案件が回ってきました。
チームの概要は以下の通りです。

  • メンバー8人(うちマネージャー1人)
  • 全員サーバーサイドエンジニア
  • 普段使う言語はPHP
  • 設計が分からないのか、Vue.jsが分からないのか、JSが分からないのかすら分からないレベル
  • 某RPGで言うとスライムに苦戦するレベル(チーム公式表現)
  • フロントエンドチームは別であり、Vue.jsのナレッジがあるエンジニアもいるが他の案件で忙しいため丸投げできない

この記事ではそんなチームのためにVue.jsの勉強会を行うまでの経緯と勉強会の内容を記載します。

【勉強会にこぎつけた経緯】

チームメンバーの1人が奮闘しGitLab CIによるCI/CD環境を整えるまでに持って行ってくれたため開発・運用が出来る体制はできました。そのため何個か小さい案件のデプロイは行いましたが、そもそもVue.jsのナレッジがないためレビューも機能せず、バグに対する危機察知能力もなりない、その代わりに結合テストで担保するという現状でした。
この現状はさすがにまずいとマネージャーに訴えた結果、理解をいただくことができ業務時間中に週2時間のVue.js勉強会を行う権利を獲得しました。
持ち回りで勉強会を行うことも考えたのですが勉強会が形骸化してしまう可能性が高まると判断して勉強会の裁量は自分に集約させました。
前述の通りスライムにすら苦戦するレベルであるため、せめてバブルスライムくらいには圧勝できるくらいのレベルに持っていくことを目的としました。

【勉強会を始めるまで】

私もVue.jsのナレッジがなかったため、まずは自身のナレッジを高めることから始めました。とりあえず入門書として Vue.js入門 基礎から実践アプリケーション開発まで を土日で読破しました。書籍を選んだ理由は単純で会社にあったからです。

次に勉強会の内容を考えました。大きく分けると講義形式とハンズオンがあると考えましたが、すでに開発案件は回ってきておりすぐにチームのナレッジをためる必要があったためハンズオンを選択しました。
ハンズオンの題材を考えていたところ、初回はProggateを使えば良いんじゃないかと考えProgateを見てみましたがVue.jsは扱っていないようでした。代わりになるサービスを探したところ CODEPREP に行き当たりました。

【CODEPREPとは】

image.png

CODEPREPとはProgateのようにプログラミング言語を修学できるWebサービスで、コードの一部が虫食いになっているため主に予約語を埋めていくことにより修学ができるサービスです。
ドキュメントとエディタ、実行画面が一体化しているため気軽に修学ができます。私が考えるCODEPREPのメリット・デメリットは以下の通りです。

- メリット

  • 開発環境を整えることなく修学ができる
  • ドキュメントを読めば問題がすぐに理解できるため初心者にはオススメ
  • 無料ででき、また選択できる言語・フレームワークも豊富

- メリット

  • 広く扱っている代わりに浅いため深く理解はできない
  • 穴埋めのため何となくでも正答できてしまう

【勉強会当日】

想定していた勉強会当日の流れは以下の通りです。

  • CODEPREPの「はじめてのVue.js」を修学する(1時間)
  • Todoリストのコードを写経する(15分)
  • 自分が課題を用意したTodoリストの改修を行う(45分)

- CODEPREPの「はじめてのVue.js」を修学する(1時間)

前述の通りCODEPREPの修学を行いました。ただしデメリットにも記載した通り、CODEPREPだけでは浅いため深く理解することが出来ないため都度Vue.jsの公式ドキュメントを読むようにしました。
1時間を想定していたのですが、実際には1時間20分程度かかってしまいました。

- Todoリストのコードを写経する(15分)

「はじめてのVue.js」では最終的にTodoリストを作るのですが、穴埋めで作っていくため出来上がったコードを写経するつもりでした。
しかし、CODEPREPの修学で時間をオーバーしてしまっていたため写経は各自の任意としてコードを共有しました。

- 自分が課題を用意したTodoリストの改修を行う(45分)

CODEPREPおよび写経だけでは自身で考えるといった過程が少ないため課題を3問用意して解かせてみました。用意した課題は以下の3つです。

  • Todoリストの件数を表示する
  • 「〇〇を追加しました」、「〇〇を削除しました」といったTodoリストの操作履歴を表示する
  • 新しく追加したTodoにはNEW!!と表示する

解かせてみた結果として1問目は全員解答出来ましたが、2問目以降は時間が足りませんでした。また私のミスとして2問目より3問目の方が簡単であったため、順番を入れ替えればもう少し解けていたと反省しました。

【勉強会の所感と今後】

初回の勉強会の内容としてCODEPREPを採用し、またデメリットである浅い理解を補うために公式ドキュメントを読むようにしたのは以下の点で良かったと思います。

  • 題材を用意してくれているため自分の負荷が少ない
  • 勉強会がスムーズに進む

今後はVue.jsのふりかえりと時間が足りず解けなかった課題の再挑戦を行ったのちに本格的にTodoリストを作っていこうかと考えています。

もし自分と同じような境遇にいる方は参考にしていただけると幸いです。

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

<初心者>vue.jsでリンクの動的生成とルーティング。おまけでPythonによる頻出語のピックアップ。

やったこと

以前作ったwebサービスに機能追加しました。

サービスの詳細はこちらの記事参照ください。「<初心者>レファレンス協同データベースの記事をランダムに表示するWEBサービスをvue.jsで作りました。

記事の詳細ページにキーワードの項目を設けて、クリックすると検索画面に飛ぶようにしました。

test9.gif

なぜやるのか

現状の問題点

前回記事(cssのアニメーションで検索ボックス上部にレコメンド事例紹介機能を搭載してみた。[2019/07/13追記※3回])と同様、「レファレンスサービス利用経験者が少ないため、どんな事例があるかわかりにくい。」という欠点があります。

今回採用する改善方法

そこで、一つの記事を読んだあとに関連する記事を見てもらえるようにキーワードのタグを作成。タグによって新たな検索行動を促すことで、サイト内での回遊率アップに繋げます。

キーワードは、レファレンス協同データベースの各記事のおそらく半数近くには設定されているのでこれを利用します。設定されていない記事も多いので、プラスαとしてPythonによる頻出単語のピックアップも行いました。しかし、Pythonについてはまだ実装はしていません。

実装方法

シンプルです。

詳細ページにおける他の項目と同様、xmlからキーワードを取得します。

Detail.vue
const keywords = result.getElementsByTagName("reference")[0].getElementsByTagName("keyword")||

ページに反映する際にリンクを設定。

Detail.vue
      <h3 id="keyword">キーワード</h3>
      <span v-for="keyword in refqa.keywords" class="tag" v-bind:key=keyword>
        <a v-bind:href="'https://testreftika.web.app/keyword/' + keyword">{{keyword}}</a>
      </span>

リンクはルーターでトップページに飛ばす

router.js
{
  path: '/keyword/:keyword',
  component: Home
},

トップページでは、リンクを解釈します。/keyword/hogeであれば、hogeを検索ボックスに入力。

Home.vue
created: function() {
    省略
    if(this.path.match(/\/keyword\/./) ){this.keyword=this.$route.params.keyword}
}

上記パス(this.path)はjavascriptで取得している。

Home.vue
  data() {
    return {
      省略
      path:location.pathname,
    }

検索ボックスに入力語は自動で検索されるように実装している。前回記事「cssのアニメーションで検索ボックス上部にレコメンド事例紹介機能を搭載してみた。[2019/07/13追記※3回]」参照。

Home.vue
クリックしたときに、検索ボックスにキーワードを入力するメソッド
setInputBox(searchtext){
      document.getElementById( "searchbox" ).value = searchtext;
      this.keyword=searchtext;   ←この後、this.keywordを監視しているメソッドが検索を実行する
    },

プラスα:Pythonによる頻出語のピックアップ

大まかな流れ

①xmlでデータ取得
②mecabで名詞・形容詞のみピックアップ&stopwordを除外して単語をリスト化
③Counterでリストの各要素の出現個数をカウント、出力

全文です。

import MeCab
from collections import Counter
import urllib.request
import xml.etree.ElementTree as ET

#②mecabで名詞・形容詞のみピックアップ&stopwordを除外して単語をリスト化する関数
def get_dokuritsugo_by_mecab(text):
    tagger = MeCab.Tagger('/usr/local/lib/mecab/dic/mecab-ipadic-neologd/')
    tagger.parse('') 
    node = tagger.parseToNode(text)
    word_list = []
    while node:
        pos = node.feature.split(",")[0]
        if pos in ["名詞", "形容詞"]:
            word = node.surface
            if not word in stoplist:
                word_list.append(word)
        node = node.next
    return(word_list)

#ストップワードについては下記
with open('stopword.txt', 'r', encoding='utf-8') as file:
    stoplines = file.readlines()
    stoplist = []
    for l in stoplines:
        stoplist.extend(l)

#①xmlでデータ取得。「。」で区切り一文ずつmecabを呼び出している。
url = 'http://crd.ndl.go.jp/api/refsearch?type=reference&query=sys-id=1000161493'    ←apiの呼び出し
req = urllib.request.Request(url)

with urllib.request.urlopen(req) as response:
    XmlData = response.read()
    root = ET.fromstring(XmlData)
    QAtext = root[4][0][0].text + root[4][0][2].text
    #※レスポンスのxmlの仕様です。
    #※root[4][0][0]に質問、root[4][0][2]に回答が入っています。
    print(QAtext)

    texts = QAtext.split('。')
    list = []
    sentences = []
    for text in texts:
        list.extend(get_dokuritsugo_by_mecab(text))
        c = Counter(list)
    #③Counterでリストの各要素の出現個数をカウント、出力
    print(list)
    print(c.most_common()[0])
    print(c.most_common()[1])
    print(c.most_common()[2])

ストップワードは、
英語は、sklearn.feature_extraction、日本語はslothlibを使用させていただきました。2つをローカルでtxtファイルにがっちゃんこした上で、記号を付け加えて利用しています。

出力結果

くしゃみの回数で意味が違うという迷信を友人と話していると解釈が違いました。何種類かあるのでしょうか。(北九州市立中央図書館)では、

('くしゃみ', 23)
('噂', 5)
('風邪', 5)

インドの教育事情と教育に関わる社会問題について分かる資料(日本貿易振興機構アジア経済研究所図書館)

('教育', 8)
('インド', 7)
('請求', 5)

※「請求」は図書の「請求記号」という文言が多数使われているため多くなっている。

「この道をいけばどうなるものか」から始まる言葉の全文が知りたい。良寛の言葉らしい。(福井県立図書館)

('言葉', 7)
('詩', 5)
('一休宗純', 5)

記事との偶然の出会いをつくるサービスとしては、そこそこ十分な結果かと思われます。

「請求記号」「国立国会図書館」など、図書館で頻繁に使用される語は除くように調整すれば使えるかもしれません。応答速度などを見ながら、今後試していきます。

参考:
◆mecabのインストール(Windows)
PythonとMeCabで形態素解析(on Windows)
◆mecabの使い方
B'zの歌詞をPythonと機械学習で分析してみた 〜LDA編〜
◆NEologd辞書のインストール
WindowsでNEologd辞書を比較的簡単に入れる方法

◆PythonのCounter
PythonのCounterでリストの各要素の出現個数をカウント
◆PythonとXML
PythonでXMLをパースする

今回は単純な頻出語で行ったが、調べるうちにTF-IDFによる重みづけやJaccard係数を使用した共起ネットワークも気になった。
検索機能に用いられている、特徴語とそのさまざまな抽出方法
世界のラーメンスタイルをNetworkXで可視化する
Pythonを使って文章から共起ネットワークを作る

reftikaもぜひのぞいてみてください。

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

Step by step Vue SPA入門:単一ファイルコンポーネント

Step by step Vue SPA入門:単一ファイルコンポーネント

Vue CLI3 で作成した SPA(Single Page Application)プロジェクト上で、段階的に Vue.js を学んで行きましょう。

今回は 単一ファイルコンポーネント編です。

前提事項

Step by step Vue SPA入門:ページの追加編 が完了していること。

単一ファイルコンポーネント

Vue CLI3 で生成したプロジェクトでは単一ファイルコンポーネントに対して Vue のコーディングを行っていきます。単一ファイルコンポーネントとは *.vue 拡張子を持つファイルのことです。

src/views/SandBox.vue を以下のように修正してみましょう。

src/views/SandBox.vue
<template>
  <div class="sandbox">
    <!-- ここにこのコンポーネントの HTML を書きます -->
    <h1>SandBox</h1>

    <p>{{ msg }}</p>
    <p>{{ today() }}</p>
  </div>
</template>

<script>
// ここに JavaScript を書きます

// このコンポーネントで使用する Vue オブジェクト
export default {
  // データ
  data() {
    return {
      msg: "Hello, World!"
    };
  },

  // メソッド
  methods: {
    today() {
      return new Date();
    }
  }
};
</script>

<style>
/* ここに、このコンポーネントに適用する CSS を書きます */
.sandbox {
  color: black;
}
</style>

単一ファイルコンポーネントは以下の3つの要素で構成されています。

構成要素 内容
template タグ HTMLを記述します。
自分が作成したコンポーネントもHTMLタグとして使えます。
script タグ JavaScriptを記述します。
主に Vue オブジェクトを定義します。
Vue オブジェクトでは data や methods 等を定義します。
style タグ CSSを記述します。

動作確認

画面トップのメニューのSandBoxをクリックします。以下の条件を満たしていればOKです。

  • ページ内の文字が赤色
  • Hello, World!が表示されている
  • 現在の時刻が表示されている

次回

Coming Soon...

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

ASAP Vue SPA入門:単一ファイルコンポーネント

Vue CLI3 で作成した SPA(Single Page Application)プロジェクト上で、段階的に Vue.js を学んで行きましょう。

今回は 単一ファイルコンポーネント編です。

前提事項

ASAP Vue SPA入門:ページの追加編 が完了していること。

単一ファイルコンポーネント

Vue CLI3 で生成したプロジェクトでは単一ファイルコンポーネントに対して Vue のコーディングを行っていきます。単一ファイルコンポーネントとは *.vue 拡張子を持つファイルのことです。

src/views/SandBox.vue を以下のように修正してみましょう。

src/views/SandBox.vue
<template>
  <div class="sandbox">
    <!-- ここにこのコンポーネントの HTML を書きます -->
    <h1>SandBox</h1>

    <p>{{ msg }}</p>
    <p>{{ now() }}</p>
  </div>
</template>

<script>
// ここに JavaScript を書きます

// このコンポーネントで使用する Vue オブジェクト
export default {
  // データ
  data() {
    return {
      msg: "Hello, World!"
    };
  },

  // メソッド
  methods: {
    now() {
      return new Date();
    }
  }
};
</script>

<style>
/* ここに、このコンポーネントに適用する CSS を書きます */
.sandbox {
  color: black;
}
</style>

単一ファイルコンポーネントは以下の3つの要素で構成されています。
HTML, JS, CSS が1つのファイル内に書かれているので、生産性、保守性に優れています。

構成要素 内容
template タグ HTMLを記述します。
自分が作成したコンポーネントもHTMLタグとして使えます。
script タグ JavaScriptを記述します。
主に Vue オブジェクトを定義します。
Vue オブジェクトでは data や methods 等を定義します。
style タグ CSSを記述します。

動作確認

画面トップのメニューのSandboxをクリックします。以下の条件を満たしていればOKです。

  • ページ内の文字が赤色
  • Hello, World!が表示されている
  • 現在の時刻が表示されている

次回

Vue の基本

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