20191001のvue.jsに関する記事は8件です。

Vue.jsで作る フォーム確認画面

はじめに

アカウント登録などで、ユーザに情報を入力してもらったあとに、入力内容を確認してもらうための画面を用意しているサービスって多いですよね
SPAでそれを実現しようとすると、確認画面にデータを渡したりとか、戻ったときに入力内容が消えちゃったりして、頭を抱えました。
結果、こんな風に実装したよ〜、というのをご紹介できればと思います。

環境

Vue.js 2.6.10
vue-cli 3.9.1
vue-router 3.0.3

動作

動作確認用として、Githubにコード全文を上げています
https://github.com/tsk-wakabayashi/routing-nest-sample

Gifでみるとこんな感じ
Image from Gyazo

解説

基本的にはこちらの機能を使います
https://router.vuejs.org/ja/guide/essentials/nested-routes.html

簡単に説明すると、ネストされたルーティングの親に、パラメータを持たせます。

App.vueの中にメインのrouter-view

App.vue
<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

Index.vueの中にFormとConfirmをルーティングするrouter-viewを置いています。

Index.vue
<template>
  <div>
    <div>
      入力
      <span v-if="$route.meta.isConfirm">> 確認</span>
    </div>
    <router-view v-bind:user.sync="user"></router-view>
  </div>
</template>

Form.vueとConfirm.vueの親はIndex.vueとなり、親要素を返してデータのやり取りができます。

Form.vueとConfirm.vueを行き来しても、Index.vueはマウントされた状態のため、データが残り続けるという仕組みです。
これのいいところはブラウザバックをしてもデータが残るので、ユーザにも親切ですね

Form.vue
<template>
  <div>
    <form v-on:submit="$router.push('/confirm')">
      <div>
        名前
        <input v-model="user.name" type="text" required />
      </div>
      <div>
        パスワード
        <input v-model="user.password" type="password" required />
      </div>
      <button>確認する</button>
    </form>
  </div>
</template>

<script>
export default {
  props: {
    user: Object
  }
};
</script>
Confirm.vue
<template>
  <div>
    <div>名前: {{ user.name }}</div>
    <div>パスワード: {{ user.password }}</div>
    <button v-on:click="$router.back()">戻る</button>
  </div>
</template>

<script>
export default {
  props: {
    user: Object
  }
};
</script>

ルーティングは

  • '/'がフォームの入力画面
  • '/confirm'が確認画面です。

Indexのpathに引っかかったあとは、childrenの中にあるルーティングが優先されて判定されるイメージです。

router.js
export default new Router({
  mode: "history",
  routes: [
    {
      path: "/",
      component: Index,
      children: [
        {
          path: "/",
          component: Form
        },
        {
          path: "/confirm",
          component: Confirm,
          meta: {
            isConfirm: true
          }
        }
      ]
    }
  ]
});

今回のサンプルはIndex.vueから渡すデータをオブジェクトにしているので、”親が子のデータを勝手に変えてはいけない”というルールに反することが出来る書き方になっています。
ただ、入力項目が多いとその分データバインディングするのも大変ですし、ベストプラクティスになるものがあればご教示頂ければ幸いです。

さいごに

冒頭では確認画面を用意するサービスは多いと書きましたが、最近の傾向はどうなんでしょうか
モーダルで出すものもあれば、確認がないものもあるような気がします
それでもrouterをネストさせるのは、他にも使いみちがありそうですよね。

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

Vuetifyのdocsサーバが起動できないとき

Vuetifyの公式ドキュメントの日本語翻訳をするために、手元でドキュメントサーバを起動しようとしたらちょっとはまったので共有です。

クローンしてyarnで必要なモジュールをインストールして、yarn dev docsで起動できるかと(勝手に)思っていたら、モジュールが見つからないと怒っていらっしゃる。

image.png

一部抜粋.log
vuetifyjs.com:     ERROR in ./src/components/style/Colors.vue?vue&type=script&lang=js& (/Users/totto357/Private/vuetify/node_modules/babel-loader/lib!/Users/totto357/Private/vuetify/node_modules/vue-loader/lib??vue-loader-options!./src/components/style/Colors.vue?vue&type=script&lang=js&)
vuetifyjs.com:     Module not found: Error: Can't resolve 'vuetify/es5/util/colors' in '/Users/totto357/Private/vuetify/packages/docs/src/components/style'
vuetifyjs.com:      @ ./src/components/style/Colors.vue?vue&type=script&lang=js& (/Users/totto357/Private/vuetify/node_modules/babel-loader/lib!/Users/totto357/Private/vuetify/node_modules/vue-loader/lib??vue-loader-options!./src/components/style/Colors.vue?vue&type=script&lang=js&) 69:0-45 73:14-20
vuetifyjs.com:      @ ./src/components/style/Colors.vue?vue&type=script&lang=js&
vuetifyjs.com:      @ ./src/components/style/Colors.vue
vuetifyjs.com:      @ ./src/components sync \.vue$
vuetifyjs.com:      @ ./src/components/index.js
vuetifyjs.com:      @ ./src/main.js
vuetifyjs.com:      @ ./src/entry-server.js
vuetifyjs.com:     
vuetifyjs.com:     ERROR in ./src/components/doc/Parameters.vue?vue&type=script&lang=js& (/Users/totto357/Private/vuetify/node_modules/babel-loader/lib!/Users/totto357/Private/vuetify/node_modules/vue-loader/lib??vue-loader-options!./src/components/doc/Parameters.vue?vue&type=script&lang=js&)
vuetifyjs.com:     Module not found: Error: Can't resolve 'vuetify/es5/util/helpers' in '/Users/totto357/Private/vuetify/packages/docs/src/components/doc'
vuetifyjs.com:      @ ./src/components/doc/Parameters.vue?vue&type=script&lang=js& (/Users/totto357/Private/vuetify/node_modules/babel-loader/lib!/Users/totto357/Private/vuetify/node_modules/vue-loader/lib??vue-loader-options!./src/components/doc/Parameters.vue?vue&type=script&lang=js&) 73:0-64 141:26-46 142:33-53 146:28-48 150:35-55
vuetifyjs.com:      @ ./src/components/doc/Parameters.vue?vue&type=script&lang=js&
vuetifyjs.com:      @ ./src/components/doc/Parameters.vue
vuetifyjs.com:      @ ./src/components sync \.vue$
vuetifyjs.com:      @ ./src/components/index.js
vuetifyjs.com:      @ ./src/main.js
vuetifyjs.com:      @ ./src/entry-server.js
vuetifyjs.com: ℹ 「wdm」: Failed to compile.

インストールし直してみたりしたけどうまくいかないので、issueを探してみる。
すると、他にもはまっている人がいたらしく、issueがたってました。

How to solve dependencies not found #8300

そのなかでの回答はこちら。

in root folder:

yarn
yarn build
yarn dev docs // for development
yarn start // for browsing

https://github.com/vuetifyjs/vuetify/issues/8300#issuecomment-524555249

yarn buildしないといけないということでした。(考えてみれば当たり前ですよね。:joy:

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

vue.js /newを呼んで欲しいのに/:idを呼んでしまう場合の原因

/newを呼んで欲しいのに/:idを呼んでしまう場合の原因

RailsとVue.jsを使用。

router.jsに、下記のように各コンポーネントへのルーティングを設定していた。

router.js
    { path: '/expenses', component: Expense },
    { path: '/expenses/:id', name: 'expenseShow', component: ExpenseShow },
    { path: '/expenses/:id/edit', name: 'expenseEdit', component: ExpenseEdit },
    { path: '/expenses/new', name: 'expenseNew', component: ExpenseNew },

/expenses(一覧)から/expenses/new(登録ページ)へは問題なく遷移出来る。

が、
/expenses/new(登録ページ)でリロードをすると、
なぜかパスは /expenses/new のままだが expenseShow(/expenses/:id) のコンポーネントが読み込まれる、という現象が発生。

調べると、/new がリクエストパラメータとして見なされ、

Started GET "/expenses/new" for ::1 at 2019-10-01 17:06:53 +0900
17:06:53 web.1       | Processing by HomeController#index as HTML
17:06:53 web.1       |   Parameters: {"id"=>"new"} <==== これ

結果、/expenses/:id が適用され、
expenseShowのコンポーネントが読み込まれていた。

なので、/expenses/new/expenses/:id より手前に持ってくるよう順番を入れ替えることで解消した。

router.js
    { path: '/expenses', component: Expense },

    // /expenses/newを手前に
    { path: '/expenses/new', name: 'expenseNew', component: ExpenseNew },

    { path: '/expenses/:id', name: 'expenseShow', component: ExpenseShow },
    { path: '/expenses/:id/edit', name: 'expenseEdit', component: ExpenseEdit },
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue CLI 3.0でCI環境を最短で構築する

VueのCI環境を構築しようとした時に、参考にしたサイトの情報が古かったり、今となっては不要な作業が入っていたりしたので、最短の手順(2019/10/1時点)を残しておく。

ただ最短と言いながら、何を何のためにしているかが分かるようにTravisCI、Coverallsの連携部分は別々の手順としています。

環境

  • Windows 10
  • Node:12.2.0
  • npm:6.9.0
  • Vue CLI3.11.0
  • GitHub
  • TravisCI
  • Coveralls

0. 環境構築

は終わっている前提で進めます。

1. Vueプロジェクトを作成する

プロジェクトを作成したいフォルダにて、下記コマンドを実行する。

$ vue create [project-name]

Manually select features を選択する。
デフォルトだと記載されているようにテスト機能が含まれていない為。

Vue CLI v3.11.0
? Please pick a preset:    
  default (babel, eslint)  
> Manually select features 

BabelLinter / Formatterに加えて、Unit Testingを選択する。
E2E Testingはお好みで選択してください。私は普段使わないので。

Vue CLI v3.11.0
? Please pick a preset: Manually select features
? Check the features needed for your project: 
>(*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support        
 ( ) Router
 ( ) Vuex
 ( ) CSS Pre-processors
 (*) Linter / Formatter
 (*) Unit Testing
 ( ) E2E Testing

ESLintの設定はお好みで。

Vue CLI v3.11.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Linter, Unit
? Pick a linter / formatter config: 
> ESLint with error prevention only 
  ESLint + Airbnb config
  ESLint + Standard config
  ESLint + Prettier
Vue CLI v3.11.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Linter, Unit
? Pick a linter / formatter config: Basic
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Lint on save
 ( ) Lint and fix on commit

テストランナーはJestを選択。
※私がJestを使い慣れているだけなので

Vue CLI v3.11.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Linter, Unit
? Pick a linter / formatter config: Basic
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
? Pick a unit testing solution: (Use arrow keys)
  Mocha + Chai
> Jest

package.json にBabelの設定を保存

Vue CLI v3.11.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Linter, Unit
? Pick a linter / formatter config: Basic
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
? Pick a unit testing solution: Jest
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? 
  In dedicated config files
> In package.json

設定の保存はお好みで。
この設定をする事で、package.json に下記の設定が追加されている。

    "test:unit": "vue-cli-service test:unit"

試しに以下コマンドを実行してみると、テストが実行される。

$ npm run test:unit

> xxxxx@0.1.0 test:unit yyyyyy
> vue-cli-service test:unit

 PASS  tests/unit/example.spec.js
  HelloWorld.vue
    √ renders props.msg when passed (20ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.704s, estimated 5s
Ran all test suites.

GitHubに公開する

詳細は割愛。

2. TravisCIと連携する

TravisCI側の設定

  1. GitHubアカウントでログインする。
  2. 設定画面で対象のリポジトリを連携対象にする。

テスト設定ファイルの作成する

プロジェクトルートに .travis.yml を作成する。

travis.yml
language: node_js
node_js:
  - "12.2.0"

cache:
  directories:
    - node_modules

script:
  - npm run test:unit

GitHubにPushする

詳細は割愛。

3. Coverallsと連携する

TravisCI側の設定

  1. GitHubアカウントでログインする。
  2. 設定画面(ADD REPO)で対象のリポジトリを連携対象にする。

※対象リポジトリが表示されない場合は、「SYNC REPOS」を押してみる。

coverallsライブラリを追加する

下記コマンドを実行する。

$ npm install --save-dev coveralls

Jestでカバレッジをとる設定を追加する

package.jsoncollectCoveragecollectCoverageFrom の設定を追加する。

  "jest": {


    "collectCoverage": true,
    "collectCoverageFrom": [
      "<rootDir>/src/**/*.{js,vue}",
      "!**/node_modules/**"
    ]
  }

余談だが、この設定を追加する事で、npm run test:unitを実行すると、カバレッジが出力されるようになる。

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |        0 |      100 |        0 |        0 |                   |
 App.vue  |        0 |      100 |      100 |        0 |                 9 |
 main.js  |        0 |      100 |        0 |        0 |         1,2,4,6,7 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.183s
Ran all test suites.

テスト設定ファイルを変更する

.travis.yml にカバレッジを渡す設定を追加する。

travis.yml
  - npm run test:unit && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls

GitHubにPushする

詳細は割愛。

4. README.mdにバッチを表示する。

詳細は割愛。
他のサイトを参考にしてください。

参考サイト

https://knowledge.sakura.ad.jp/3754/
https://chaika.hatenablog.com/entry/2019/07/18/083000

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

Vue.js伸縮サイドバー

ポインターに合わせ伸縮するサイドバー

fbbf620fac7bd46db0e9a14edc15c956.gif

ソース

動機

Vue.jsでポインターに合わせ伸縮するサイドバーを実装する機会があったので、やり方をメモしておきます。
もっと良い実装方法がありましたら、指摘して頂けましたら嬉しいです。

大まかな流れ

サイドバーの横に設置したボーダー要素()のmousedownイベントが発火する。

mousemoveイベントを画面全体(window)に対して登録し(window.addEventListener('mousemove', this.handleMove))、
画面上でポインターが動く度に、handleMoveメソッドが呼ばれるようにする。

handleMoveメソッドの引数から、移動後のポインターの位置を取得し、
サイドバーの横幅が画面左端からポインターまでの距離(割合)になるように変更する。

ポインターの動きに合わせて、サイドバーが伸び縮みするように見える。

細かい点

サイドバーの親要素のwidth(pageRect.width)だけはpx値で持ち、
サイドバーのwidthやトグルボタンのwidthは、
pageRect.widthを1とした時の割合で保持しています。
理由は、割合で持っておけば、画面のリサイズが起こっても、
pageRect.widthだけ変更すれば、リサイズ前と同じ見た目が維持されるからです。

また、pageRect.widthは今回の例で言えば、window.innerWidthと同値になります。
なので、pageRect.widthと書かれているところ、window.innerWidthとしても成り立ちます。
サイドバーの親要素のwidthと画面の横幅が等しいという条件が常に成り立つ場合は、
pageRect.widthとなっているところを、window.innerWidthにした方がシンプルになり、良いかもしれません。

サンプルコード

Page.vue
<template>
  <div id="page">
    <StretchableSidebar
      :isSidebarOpened="isSidebarOpened"
      :style="stretchableSidebarComputedStyle" />
    <SidebarBorder
      :isSidebarOpened="isSidebarOpened"
      @mousedown.native="startStretch"
      @toggle-sidebar="toggleSidebar" />
  </div>
</template>

<script>
import StretchableSidebar from './StretchableSidebar.vue'
import SidebarBorder from './SidebarBorder.vue'
const TOGGLE_BTN_WIDTH = 35
const DEFAULT_SIDEBAR_WIDTH = 0.2

export default {
  name: 'page',
  components: {
    StretchableSidebar,
    SidebarBorder
  },
  data() {
    return {
      stretchableSidebarStyle: {
        width: DEFAULT_SIDEBAR_WIDTH // 初期表示時の横幅は親要素の20%
      },
      pageRect: {
        width: 0,
        height: 0
      },
      toggleBtnStyle: {
        width: null
      }
    }
  },
  computed: {
    stretchableSidebarComputedStyle () {
      return { width: `${ this.stretchableSidebarStyle.width * 100 }%` }
    },
    isSidebarOpened () {
      return this.stretchableSidebarStyle.width > this.sidebarMinSize
    },
    sidebarMinSize () {
      // トグルボタンの横幅の割合の半分をサイドバーの最小値にする
      return this.toggleBtnStyle.width / 2
    }
  },
  mounted() {
    this.setScreenData()
    this.addResizeEvent()
  },
  beforeDestroy() {
    this.removeResizeEvent()
  },
  methods: {
    setScreenData () {
      this.setPageRect()
      this.setToggleBtnStyle()
    },
    setPageRect () {
      // サイドバーの親要素の横幅と高さを保存。
      const { width, height } = document.getElementById('page').getBoundingClientRect()
      this.pageRect.width = width
      this.pageRect.height = height
    },
    setToggleBtnStyle () {
      // 35px(ボタンの横幅)が親要素の横幅に対してどれぐらいの割合かを保存する。
      this.toggleBtnStyle.width = TOGGLE_BTN_WIDTH / this.pageRect.width
    },
    startStretch () {
      // 画面上でポインターを動かす度に、handleMoveが呼ばれるようにする。
      window.addEventListener('mousemove', this.handleMove)
      window.addEventListener('mouseup', this.finishStretch)
    },
    finishStretch () {
      window.removeEventListener('mousemove', this.handleMove)
      window.removeEventListener('mouseup', this.finishStretch)
    },
    handleMove (event) {
      const { pageX } = event
      const sidebarWidth = pageX / this.pageRect.width // サイドバーの親要素に対する横幅の割合 = 画面最左からポインターまでの距離 / 親要素の横幅
      if (sidebarWidth >= this.sidebarMinSize) {
        this.stretchableSidebarStyle.width = sidebarWidth
      } else {
        this.stretchableSidebarStyle.width = this.sidebarMinSize
        this.finishStretch()
      }
    },
    addResizeEvent () {
      window.addEventListener('resize', this.setScreenData)
    },
    removeResizeEvent () {
      window.removeEventListener('resize', this.setScreenData)
    },
    toggleSidebar () {
      if (this.stretchableSidebarStyle.width === this.sidebarMinSize) {
        this.stretchableSidebarStyle.width = DEFAULT_SIDEBAR_WIDTH
      } else {
        this.stretchableSidebarStyle.width = this.sidebarMinSize
      }
    }
  }
}
</script>

<style scoped>
#page {
  display: flex;
}
</style>
StretchableSidebar.vue
<template>
  <aside id="strechable-sidebar">
    <div :style="sidebarContentComputedStyle">
      <ul>
        <li>あああああ</li>
        <li>いいいいい</li>
        <li>ううううう</li>
      </ul>
    </div>
  </aside>
</template>
<script>
export default {
  name: 'stretchable-sidebar',
  props: {
    isSidebarOpened: {
      type: Boolean,
      required: true
    }
  },
  computed: {
    sidebarContentComputedStyle () {
      if (this.isSidebarClosed) {
        return { transform: `translateX(-${window.innerWidth}px)` }
      } else {
        return {}
      }
    },
    isSidebarClosed () {
      return !this.isSidebarOpened
    }
  }
}
</script>
<style scoped>
#strechable-sidebar {
  background-color: rgb(244, 245, 247);
  height: 100vh;
  overflow: hidden;
  user-select: none;
}
</style>
SidebarBorder.vue
<template>
  <div id="sidebar-border">
    <span id="sidebar-border-btn" @click.stop="toggleSidebar">
      <i :class="['fas', isSidebarOpened ? 'fa-chevron-left' : 'fa-bars']" />
    </span>
  </div>
</template>
<script>
export default {
  name: 'sidebar-border',
  props: {
    isSidebarOpened: {
      type: Boolean,
      required: true
    }
  },
  methods: {
    toggleSidebar () {
      this.$emit('toggle-sidebar')
    }
  }
}
</script>
<style scoped>
#sidebar-border {
  width: 3px;
  height: 100vh;
  position: relative;
}
#sidebar-border:hover {
  background-color: #708090;
  cursor: col-resize;
}
#sidebar-border-btn {
  width: 35px;
  height: 35px;
  background-color: #B0C4DE;
  border: 1px solid #708090;
  border-radius: 50%;
  display: inline-block;
  text-align: center;
  box-shadow: .5px .5px .5px rgba(0,0,0,0.6);
  position: absolute;
  top: 17.5px;
  left: -17.5px;
}
.fas {
  line-height: 35px;
  color: #696969;
}
.fa-chevron-left {
  cursor: w-resize;
}
.fa-bars {
  cursor: e-resize;
}
</style>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue.js サイドバーを作る

サイドバーを作る

参考にしました。
stackoverflow
https://stackoverflow.com/questions/48905654/css-fixed-sidebar-in-vue-js

Vue.jsで使えるテンプレ一覧
https://sounansa.net/archives/2360

↑の一つ
https://www.creative-tim.com/product/vue-light-bootstrap-dashboard#

Vue Plugin Component
https://gist.github.com/davewoodall/c8bc710fc258268c29617473be47d2c0

1.
サイドバーのコンポーネントを作る

ファイル名は、 sidebar.vue

パスは app/javascript/packs/components/layouts/sidebar.vue とする

2.
土台のコンポーネント(scafold.vueとする)を作り、1をimportする

scafold.vue
<script>
import Top from './top.vue' // ヘッダー
import Bottom from './bottom.vue' // フッター
import Welcome from '../welcome.vue' // トップページのコンテンツ
import Sidebar from './sidebar.vue' // サイドバー

export default {
  components: {
    Top,
    Bottom,
    Welcome,
    Sidebar
  },
}
</script>

3.
2のtemplate内で1を使用

ポイントは、
サイドバーのコンポーネントと、メインコンテンツ(router-view)のコンポーネントを、別々の要素として配置させること。

scafold.vue
<template>
  <div>
    <top></top>
    <sidebar class="sidebar-area"></sidebar>
    <div class="scafold-wrapper text-center">
      <router-view/>
    </div>
    <bottom class="footer-area"></bottom>
  </div>
</template>

4.
2にcssを適用

scafold.vue
<style scoped>
.sidebar-area {
  /* 左側に固定 */
  float: left;
}

.footer-area {
  margin-top: 40px;
}

.scafold-wrapper {
  /* display: flex; 要素を横並びにする */
  flex-direction: column; /* 要素の並び順の主軸を指定 上 => 下 */
  min-height: 100vh; /* 要素の高さの最小値を指定 vhはviewport(表示領域) heightの略 */

  /* サイドバーのwidth分だけ範囲を削除 */
  width: calc(100% - 200px);

  /* サイドバーで隠れるので右に寄せる */
  margin: 0 0 0 180px;
}
</style>

5.
1のサイドバーのコンポーネントを実装

sidebar.vue
<template>
  <div class="sidebar">
    <div class="sidebar-wrapper">
      <div class="sidebar-link-area">
        <!-- サイドバーメニュー -->
        <p><router-link to="/counselings" class="sidebar-link">カウンセリング</router-link></p>
        <p><router-link to="/expenses" class="sidebar-link">経費</router-link></p>
        <p><router-link to="/problems" class="sidebar-link">悩み</router-link></p>
        <p><router-link to="/calendars" class="sidebar-link">カレンダー</router-link></p>
        <p><router-link to="/admins" class="sidebar-link">管理者</router-link></p>
        <p><router-link to="/users" class="sidebar-link">生徒一覧</router-link></p>
        <p><router-link to="/tasks" class="sidebar-link">イベント一覧</router-link></p>
      </div>
    </div>
  </div>
</template>

<style>
.sidebar {
  background-color: #191970;
  height: 100%; /* サイドバーの高さ */
  width: 200px; /* サイドバーのwidthを指定 */
  max-width: 200px; /* widthの最大値 */
  opacity: 0.9.5; /* 透過する 0に近くほど透過する */
  position: fixed; /* 左上に要素を固定する(スクロールしても位置は固定される) */
  overflow-x: hidden; /* 横軸ではみ出た要素を非表示にする */
  box-sizing: border-box; /* paddingとborderを、widthとheightに含める */
  padding-left: 40px; /* サイドバー内のリンクの位置を右にずらす */
}

.sidebar-link-area {
  padding-top: 20px; /* サイドバーリンクの上部に空白を作る */
}

.sidebar-link {
  color: #ffffff; /* リンクの文字色を白に */
}

.sidebar-link:hover {
  color: #ffffff /* マウスがリンクに乗った時も文字色を白に */
}
</style>

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

create-nuxt-appで"Error: Cannot find module './prompts'"

発生した問題

nuxt.jsで新規アプリケーションを開発しようと思い、create-nuxt-appを実行

npx create-nuxt-app hogehoge

以下のエラーが発生

create-nuxt-app v2.11.0
✨  Generating Nuxt.js project in hogehoge
Trace: { Error: Cannot find module './prompts'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (C:\Users\xxx\AppData\Roaming\npm\node_modules\create-nuxt-app\saofile.js:9:12)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3) code: 'MODULE_NOT_FOUND' }
    at sao.run.catch (C:\Users\xxx\AppData\Roaming\npm\node_modules\create-nuxt-app\cli.js:46:17)

解決策

create-nuxt-app v2.11.0を使用するとエラーが発生する場合があるそうです。
バージョンを下げて一時的に対応します。

npx create-nuxt-app@2.10.1 hoge

追記 2019/10/01 04:50

この記事を書いている最中に修正版(v2.11.1)が出てたみたいです。
更新しましょう。

npm update -g create-nuxt-app
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue-routerの使用方法

はじめに

laravelとvue-routerが入っている前提としての記事になります。
もしvue-routerをインストールされていない方がいましたら
こちらの記事を参照ください。
https://qiita.com/KARENN/items/48334437eb06628b78fc

今回は実際にvue-routerで指定したURLに、vueファイルで記述した内容を画面に表示できるようにする方法になります。

今回使用するファイル構成

projectName
 ↳resorces
  ↳js
   ↳components
    ↳index.vue
    ↳detail.vue
  ↳views
   ↳index.blade.php

router.jsの内容

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);

import index from './components/index.vue';
import detail from './components/detail.vue';

export default new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: index
            component: index
        },
        {
            path: '/detail',
            name: detail,
            component: detail
        }
    ]
});

vue-routerの中身がこのようになっていることが前提となります。

index.blade.php

index.blade.php
<!doctype html>
<head>
    <script src="{{ asset('js/app.js') }}" defer></script>
</head>
<body>
    <div id="app">
       <router-view />
    </div>
</body>
</html>

headの中身に必ずコンパイルしたjsを使用するようにしてください。
idをapp.jsで指定した内容を記述して¸router-viewを呼ぶようにすると
router.jsの中身を見るようになります。
ここまでがbladeに記述する内容になります。

vue内の記述

では実際ここからはvue-router を使用したvue.jsの内容です。

index.vue
<template>
    <div>
        index.vueの中身になります。
        <router-link to="/detail">detail.vueに遷移</router-link>
    </div>
</template>

URLに/を入力するとrouter.jsで指定したindex.vueの中身が表示されます。
この場合、画面に下記のように表示されます。
スクリーンショット 2019-10-01 0.47.16.png

detail.vueに遷移を押下するとdetail.vueの内容が表示されます。

detail.vue
<template>
    <div>
        detail.vueに遷移しました。
    </div>
</template>

実際の画面ではこのようになります。
スクリーンショット 2019-10-01 0.48.04.png

これでvue-routerを使用した画面遷移になります。

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