- 投稿日:2019-09-29T22:42:38+09:00
VSCodeでVue.jsのモダンな開発環境を整えよう
はじめに
みなさん、Visual Studio Code(以下VSCode)使ってますか?VSCodeはかなりの頻度で開発されており、色々と便利な機能が随時アップデートされているので、多くの現場で使われていることだと思います。今回は、VSCodeを使って、Vue.jsの開発環境の設定についてご紹介します。主にデバッグの部分に軸をおいて解説していますので、VSCodeでVue.jsの開発をされている方には有益な情報になるかと思います。
では、早速はじめましょう。
\(^o^)/前提条件
検証している環境は下記になります。
環境 バージョン OS Mac OS Mojave vue cli 3.11.0 VSCode 1.38.1 Node.js 10.15.3 事前に下記のインストールが済んでいる前提となりますので、インストールがまだの場合は、インストールをお願いします。
- Node.js
- npm
- yarn
- Vue CLI
- VSCode
- Google Chrome
環境構築
VSCodeにプラグインを追加
VSCodeに必要なプラグインを追加します。
プラグインの追加方法は解説しておりませんので、別途別の資料を参照頂ければ幸いです。Vue.js Extension Pack
リンク
Vue.jsでよく使うプラグインをまとめたもの。Debugger for Chrome
リンク
Javascriptのデバッグをするためのプラグイン。
使い方は後ほど解説します。Google Chromeに拡張機能を追加
Google Chromeに必要な拡張機能を追加します。
拡張機能の追加方法は解説しておりませんので、別途別の資料を参照頂ければ幸いです。Vue.js devtools
リンク
Vue.jsのサイトのデバッグをするためのツール。
使い方は後ほど解説します。Vueのテンプレートを作成
# Vue.jsのテンプレートを作成する $ vue create my-app # 下記選択肢が表示されるので、「Manually select features」を選択しEnter Vue CLI v3.11.0 ? Please pick a preset: default (babel, eslint) ❯ Manually select features # 下記選択肢が表示されるので、「Babel」、「TypeScript」、「Router」、「Vuex」、「Linter / Formatter」を選択し、Enter (選択はSPACEキーで可能です) ? 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 # 下記の様に聞かれるので、「n」を入力し、Enter ? Use class-style component syntax? (Y/n) n # 下記のように聞かれるので、「y」を入力し、Enter ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n) y # 下記のように聞かれるので、「y」を入力し、Enter ? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) y # 下記のように聞かれるので、「TSLint」を選択し、Enter ? Pick a linter / formatter config: (Use arrow keys) ❯ TSLint ESLint with error prevention only ESLint + Airbnb config ESLint + Standard config ESLint + Prettier # 下記のように聞かれるので、「Lint additional lint features」を選択し、Enter ? Pick additional lint features: ❯◉ Lint on save ◯ Lint and fix on commit # 下記のように聞かれるので、「In dedicated config files」を選択し、Enter ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys) ❯ In dedicated config files In package.json # 下記のように聞かれるので、「n」を入力し、Enter ? Save this as a preset for future projects? (y/N) n # 最終的には以下のようになっているはず Vue CLI v3.11.0 ? Please pick a preset: Manually select features ? Check the features needed for your project: Babel, TS, Router, Vuex, Linter ? Use class-style component syntax? No ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Pick a linter / formatter config: TSLint ? Pick additional lint features: Lint on save ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files ? Save this as a preset for future projects? (y/N) n $ cd my-app $ yarn serveブラウザに「http://localhost:8080/」を入力し、下記画像のようにVue.jsのページが表示されることを確認して下さい。
VSCodeでVue.jsのデバッグを行う
# my-app内にいることを必ず確認した後、コマンドを実行して下さい。 $ yarn add axiosまず、先程作成したmy-appをVSCodeで開いて下さい。
HelloWorld.vueを開いて、<script>
タグ内を下記コードで上書きして下さい。
郵便番号から住所を取得する処理を追加しております。HalloWorld.vue(抜粋)import Vue from 'vue'; import axios from 'axios'; export default Vue.extend({ name: 'HelloWorld', props: { msg: String, }, created: async ()=>{ const response = await axios.get('https://api.zipaddress.net/?zipcode=6048151') window.console.log(response); } });最終的には下記のようになるかと思います。
次に、下記画像のようにして、44行目にブレークポイントを設定して下さい。
では、デバッグを実行していきましょう。
左のアイコンの中からデバッグアイコン(虫の形)をクリックして下さい。「構成がありません」の右側にある、歯車アイコンをクリックして下さい。
ポップアップが表示されますので、「Chrome」をクリックして下さい。「デバッグ」の右にある緑三角をクリックして下さい。(下記画像参照)
Google Chromeでページが開くので、上部にある「About」をクリック後、「Home」をクリックして下さい。
(下記画像参照)
もしページが開かない場合は、バックグラウンドでyarn serve
コマンドが実行されている必要がありますので、実行されているかどうかを確認下さい。すると、下記画像のようにデバッグ画面に遷移するかと思います。
左の「変数」の部分では、変数の中身を見ることが出来ます。
中央上部のツールパネルでは、処理を進めたりなどの操作が可能です。
中央の黄色い背景の部分(44行目)で、処理がストップしている事がわかります。ツールパネルについて、少し説明します。
アイコンが6個あるかと思いますが、左から順番に下記意味となります。
- 続行
- ステップオーバー
- ステップイン
- ステップアウト
- 再起動
- 停止
では、ツールパネルの一番左にある「続行」をクリックして下さい。
(下記画像参照)すると、変数responseの中身が表示されています。
京都の郵便番号を入れているので、京都の住所がAPIで取得できていることがわかります。
(下記画像参照)メモ
本来であれば、createdの中の処理は、画面を初回に表示した際にブレークポイントで止まってほしいのですが、なぜかそうなりませんでした。また、一度目にブレークポイントで止まったときには、responseには値が入っていません。このあたりの挙動は、Vue.jsのバックグラウンドのロジックが関係しているのかもしれないのですが、詳細にはわかりませんでした。もし詳しい方がいらっしゃいましたら、コメントでご教授頂ければ幸いです。
Vue.js devtoolsでVue.jsでVue.jsのデバッグを行う
ブラウザに「http://localhost:8080/」を入力し、ページを開きます。
デベロッパーツールを開きます。(Macの場合は、Command+Option+i)
メニューの右側にある「Vue」をクリックします。(下記画像参照)Vueのパネルを開くと、Vueの構造が表示されます。(下記画像参照)
試しに、HelloWorldコンポーネントを開いてみましょう。
propsで渡ってきた値やdata属性の中身などを見ることが出来ます。date属性、propsの値も変更することが可能です。
propsの値を変更するためには、設定の変更が必要になります。(下記画像参照)
これは非常に便利ですね。Vuexとして保存されているデータを確認することも出来ます。
今回は何も保存していませんので、値は表示されていませんが、Vuexを利用している場合は確認することが出来ます。次にイベントの表示です。
emitで発行したイベントの履歴を見ることが出来ます。
今回はemitを使っていないので何も表示されていませんが、emitを使う場合は、自分の想定しているタイミングでイベントが実行されているかを確認することが出来ます。次にルーターの表示です。
ルーターの遷移履歴、ルーターのパス一覧を見ることが出来ます。終わりに
今回の記事で、Vue.jsの開発環境、デバッグ手法についての基礎は解説できたのかなと思っています。デバッグは非常に難しいので、ツールに頼れる部分はどんどんツールに頼っていくのが効率の良い開発に繋がるのではないでしょうか。この記事が少しでも皆さんの開発、デバッグの助けになれば幸いです。
- 投稿日:2019-09-29T22:01:32+09:00
Vue.jsをTypeScriptと使うメモ -設定-(@vue/cliは使わずに)
設定
必要なpackageを取得
npm install vue-property-decorator npm install --save-dev typescript webpack webpack-mergetsconfig(基本的に推奨構成より)
{ "compilerOptions": { "target": "es5", "module": "es2015", "strict": true, "moduleResolution": "node", "noImplicitAny": true, // 暗黙のany "strictNullChecks": true, //nullやundefinedを明示するように "noImplicitThis": true, "moduleResolution": "node", // importのpathを./src/...から@src/...に "paths": { "@src/*": ["src/*"] }, "include": [ "./src/**/*.ts" ] } }includeなどは自分の設定に合わせて…
webpack設定
webpack.common.jsconst path = require('path'); const VueLoaderPlugin = require('vue-loader/lib/plugin') const webpack = require('webpack') module.exports = { entry: { app: ["./src/index.ts"] }, output: { filename: "[name].bundle.js", path: path.resolve(__dirname, "public/js") }, resolve: { extensions: [".js", ".ts", ".vue", ".json", ".css"], alias: { vue$: "vue/dist/vue.esm.js", // importのpathを./src/...から@src/...に '@src': path.resolve(__dirname, './src') }, modules: ["node_modules"] }, plugins: [ new VueLoaderPlugin(), ] }開発用のビルドと本番用のビルドで分けたりする。(sourcemap出力したり)
webpack.dev.js// 開発ビルド用 const merge = require('webpack-merge') const common = require('./webpack.common.js') module.exports = merge(common, { mode: 'development', module: { rules: [ { test: /\.vue$/, exclude: /node_modules/, loader: 'vue-loader', options: { cssModules: { camelCase: true } } }, { test: /\.ts$/, exclude: '/node_modules/', use: [ { loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/] } } ] }, ] } })
- 投稿日:2019-09-29T21:48:23+09:00
Nuxtから利用したChart.jsでイベントを発行する
はじめに
以前書いたNuxtでChart.jsを利用するで実装した
doughnut-chart
にて、hover時とレンダリング完了時にそれぞれイベントが発行されるよう改修しました。hoverイベントを発行
doughnut-chart
はChart.jsのDoughnut Chart
を利用しており、hover時に処理を実行するためにはoptions.onHover
にコールバック関数を渡すことで可能となります。
https://www.chartjs.org/docs/latest/general/interactions/events.htmlそのため、
doughnut-chart
ではコールバック関数をコンポーネントのメソッドとして実装し、renderChart時にonHoverプロパティの値として定義することとしました。plugins/vue-chartjs.js// ・・・省略 mounted() { this.renderChart(this.chartData, { onHover: this.hover, ...this.options }); }, methods: { hover: function(point, event) { const element = event[0] || null; if (element === null) { return; } this.$emit('hover', element._index); }, }, });実装した
hover
メソッドでは2つの引数point
とevent
を受け取り、これらにはそれぞれMouseEvent
とChartElement
が渡されます。
ChartElement
にはlabelやvalueをはじめとするChart情報が含まれており、今回はその中のindex
情報を利用することとしました。
this.$emit
にてカスタムイベントを発行することが可能なため、hoverイベントを発行しindex
を返却しております。plugins/vue-chartjs.js<template> <v-container fluid> <doughnut-chart :chart-data="chartData" :options="chartOptions" @hover="hover"/> // ・・・省略 </v-container> </template> <script> // ・・・省略 methods: { // ・・・省略 hover: function(index) { console.log(index); }, }, }; </script>
doughnut-chart
にてhoverイベントを発行するよう実装したため、呼び出し側からは上記のようにevent handlerをメソッドにて実装し、@hover="event handler名"
にてイベントを受け取ることが可能となります。renderedイベントを発行
次にレンダリングが完了した際にイベントを発行するよう
doughnut-chart
を改修します。
Chart.jsのDoughnut Chart
では、options.animation.onComplete
にコールバック関数を渡すことでレンダリング完了時に処理を実行することが可能です。
https://www.chartjs.org/docs/latest/configuration/animations.htmlそこでhoverイベントの発行時と同様に
options
プロパティにコールバック関数をdefault値として渡すことで実装しようと試みたのですが、onComplete
はanimation
オブジェクトのプロパティであり一つネストした階層に定義する必要があるため、新たに算出プロパティoptionsMergedDefaultEvents
を実装し、そこでdefaultのイベントをpropsで渡されたoptions
にmergeするようにしました。plugins/vue-chartjs.js// ・・・省略 computed: { optionsMergedDefaultEvents: function() { let options = this.options; const animation = this.options.animation || {}; options.animation = { onComplete: this.rendered, ...animation, }; options = { onHover: this.hover, ...options, }; return options; }, }, mounted() { this.renderChart(this.chartData, this.optionsMergedDefaultEvents); }, methods: { // ・・・省略 rendered: function() { this.$emit('rendered'); }, }, // ・・・省略上記により、レンダリング完了時もhoverイベントと同様に呼び出し側から
@rendered="event handler名"
にてイベントを受け取ることが可能となりました。plugins/vue-chartjs.js<template> <v-container fluid> <doughnut-chart :chart-data="chartData" :options="chartOptions" @hover="hover" @rendered="rendered"/> // ・・・省略 </v-container> </template> <script> // ・・・省略 methods: { // ・・・省略 rendered: function() { console.log('rendered'); }, }, }; </script>
- 投稿日:2019-09-29T17:17:51+09:00
250行のVue.jsで陣取りゲームを作った
こんにちは、猫チーズです。
黒色:ユーザー
灰色:自陣
赤色:敵
白色:敵陣
茶色:縄(自陣を広げるためのもの)前回書いた記事『200行のVue.jsでスネークゲームを作った』が中々反響良さそうでしたので、Vue.js勉強用ゲーム 第2弾として陣取りゲームを作ってみました。
十数年前に何かのゲーム機で遊んだこのゲームを、うろ覚えで再現しています。
もし本家を知っている方いましたら教えてください!デモページ
https://miyauchiakira.github.io/vue-game-jintori/
GitHub ソースコード
https://github.com/miyauchiakira/vue-game-jintori
ゲームルール
- 自陣の中では矢印キーで自由に動き回れる
- 敵陣に入ると、縄を張りながらまっすぐ進む
- 縄を張ったまま自陣に戻ると、自陣が増える
- 敵が縄にぶつかるとゲームオーバー
- 自陣を増やすとスコアUP
これらのルールをVue.jsで作りました。
250行のプログラム
以下の250行のhtmlファイルに全ての機能が纏まっています。
jintori.htmlなどの名前で保存して、ブラウザでそのファイルを開くと遊べます。
機能の改造などをして遊んでみてください。jintori.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>陣取りゲーム</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> <style> /* グリッドレイアウト */ #grid { display: grid; grid-template-columns: repeat(20, 20px); /* 横20マス 幅20px */ grid-template-rows: repeat(20, 20px); /* 縦20マス 高さ20px */ } /* セルの色 */ .cell { border: 1px solid white; background: whitesmoke; } /* ユーザーの陣地の色 */ .cell.area { background: darkgray; } /* ロープの色 */ .cell.lope { background: burlywood; } /* ユーザーの色 */ .cell.user { background: black; } /* 敵の色 */ .cell.enemy { background: orangered; } </style> </head> <body> <div id='app'> <p>SCORE: {{ score }}</p> <div id='grid'> <!-- セルを400個生成して、必要に応じてuser, area, lope, enemyクラスを付ける --> <!-- (注意:Vueは v-for="i in 数値" としたとき、iが1から始まる) --> <div v-for="i in grid.width * grid.height" :class="{ cell: true, area: user.area_indexes.includes(i - 1), lope: user.lope_indexes.includes(i - 1), user: user_index === i - 1, enemy: enemy_index === i - 1, }" ><!--{{ i - 1 }}--></div> </div> <p v-if='is_gameover'> GAME OVER<br> <button onclick="location.reload()">RETRY</button> </p> </div> <script> new Vue({ el: '#app', data: { speed: 200, // 1マス進むのにかかる時間[ms] // グリッドのデータ grid: { width: 20, // 横20マス height: 20, // 縦20マス }, // ユーザーのデータ user: { pos: { x: 0, y: 0 }, // 位置座標 direction: { dx: 1, dy: 0 }, // 進行方向(初期値は右) area_indexes: [], // ユーザーの陣地(インデックスの配列) lope_indexes: [], // ロープ(インデックスの配列) }, // 敵のデータ enemy: { pos: { x: 10, y: 10 }, // 位置座標 direction: { dx: -1, dy: 1 }, // 進行方向(初期値は左下) }, }, // 初期化 created() { // 上下左右端をユーザーのエリアにする for(let x = 0; x < this.grid.width; x++) { for(let y = 0; y < this.grid.height; y++) { const is_side = x === 0 || x === this.grid.width - 1 || y === 0 || y === this.grid.height - 1 if(is_side) { this.user.area_indexes.push(this.pos2index({x, y})) } } } // キーボード入力のイベントをon_keydownメソッドに投げる document.onkeydown = () => { this.on_keydown(event.keyCode) } // 時間を動かし始める this.time_goes() }, computed: { // スコア = ユーザーのエリアの量(初期の領域を除く) score() { return this.user.area_indexes.length - this.grid.width * 2 - this.grid.height * 2 + 4 }, // ユーザーの座標をインデックスに変換 user_index() { return this.pos2index(this.user.pos) }, // 敵の座標をインデックスに変換 enemy_index() { return this.pos2index(this.enemy.pos) }, // ゲームオーバーの条件 is_gameover() { return this.user.lope_indexes.includes(this.enemy_index) }, }, methods: { // 時間を進める time_goes() { if(this.is_gameover) return this.forward_user() this.forward_enemy() setTimeout(this.time_goes.bind(this), this.speed) // speedミリ秒後に自分自身を呼び出す }, // 受け取った座標をインデックスに変換する pos2index({x, y}) { return this.grid.width * y + x }, // ユーザーを進める forward_user() { const old_pos = { ...this.user.pos } // directionの分だけ移動させる this.user.pos.x += this.user.direction.dx this.user.pos.y += this.user.direction.dy const pos_owner = this.get_cell_owner(this.user.pos) // 現在地の所有者 // 現在地が場外なら、位置座標を巻き戻す if(pos_owner === 'frameout') { this.user.pos = old_pos return } // 現在地が敵陣の中なら、ここにロープを追加 if(pos_owner === 'enemy') { this.user.lope_indexes.push(this.user_index) } // ロープを伸ばしたままユーザーの陣地まで辿り着いた場合 if(pos_owner === 'user' && this.user.lope_indexes.length) { const enemy_area = this.get_enemy_area() // 敵エリア以外のエリアをユーザーのエリアにする this.user.area_indexes = [] this.user.lope_indexes = [] for(let x = 0; x < this.grid.width; x++) { for(let y = 0; y < this.grid.height; y++) { // このセル(x, y)が敵の陣地か否か const is_enemy_area = enemy_area.left <= x && x <= enemy_area.right && enemy_area.top <= y && y <= enemy_area.bottom if(is_enemy_area) continue this.user.area_indexes.push(this.pos2index({x, y})) } } } }, // 敵を進める forward_enemy() { const { pos, direction } = this.enemy // ユーザーのエリアにぶつかるなら跳ね返す const is_collided_x = this.get_cell_owner({ x: pos.x + direction.dx, y: pos.y }) === 'user' const is_collided_y = this.get_cell_owner({ x: pos.x, y: pos.y + direction.dy }) === 'user' if(is_collided_x) direction.dx *= -1 // 進行方向を左右反転 if(is_collided_y) direction.dy *= -1 // 進行方向を上下反転 // directionの分だけ移動させる pos.x += direction.dx pos.y += direction.dy }, // 指定したセルの所有者を取得する get_cell_owner({x, y}) { if(x < 0 || this.grid.width <= x || y < 0 || this.grid.height <= y) return 'frameout' if(this.user.area_indexes.includes(this.pos2index({x, y}))) return 'user' if(this.user.lope_indexes.includes(this.pos2index({x, y}))) return 'lope' return 'enemy' }, // 敵陣地の範囲(left, top, right, bottom)を取得する get_enemy_area() { const { x, y } = this.enemy.pos const area = { left: x, top: y, right: x, bottom: y } // 初期値 = 敵自身の座標 // 上下左右それぞれの方向で敵陣地の範囲を調べる while(this.get_cell_owner({x: area.left - 1, y}) === 'enemy') area.left-- while(this.get_cell_owner({x: area.right + 1, y}) === 'enemy') area.right++ while(this.get_cell_owner({x, y: area.top - 1}) === 'enemy') area.top-- while(this.get_cell_owner({x, y: area.bottom + 1}) === 'enemy') area.bottom++ return area }, // キー入力を受け取ってユーザーの進行方向を変える on_keydown(keyCode) { if(this.get_cell_owner(this.user.pos) !== 'user') return // ユーザーのエリア外では方向転換できない switch(keyCode) { case 37: this.user.direction = {dx: -1, dy: 0}; break // 「←」キーが押された case 38: this.user.direction = {dx: 0, dy: -1}; break // 「↑」キーが押された case 39: this.user.direction = {dx: 1, dy: 0}; break // 「→」キーが押された case 40: this.user.direction = {dx: 0, dy: 1}; break // 「↓」キーが押された } }, }, }) </script> </body> </html>以下の機能は私が今思いついたものですが、よければ機能追加してみてください。難易度順です。
・スピードを速くする
・配色を変える
・マップのサイズを変える
・経過時間を表示
・敵の出現位置をランダムにする
・敵を増やす猫チーズ
高校一年の頃からアプリ作りに没頭していて、今はアプリクリエイターとして生きるために奮闘中です。
今年の4月からサイバーブレイン株式会社でデザイナーを始めました。Hello 猫チーズ | 猫チーズと擬似会話ができるブログ
https://blog.miyauchi-akira.app/post/20190927/Twitter | 猫チーズ
https://twitter.com/miyauchoiポートフォリオ | ミヤウチアキラ
https://miyauchi-akira.app
- 投稿日:2019-09-29T17:14:01+09:00
【Vuetify】<v-app-bar>を<v-content>にかぶらないようにする
はじめに
<v-app-bar>において特に属性を指定せずに<v-content>を用いると以下のようにページをロードした初期画面において<v-content>領域が<v-app-bar>領域を隠してしまうので、解決方法を紹介する。
解決方法
app属性を指定する。
<template> <v-app> <v-app-bar app> ... </v-app-bar> ... </template>おわりに
こちら(公式)を参考。
最近Vuetifyを触り始めたのだが、公式サイトの情報のわかりやすさに感心した。ただ各コンポーネントの属性値などの日本語紹介は公式サイトではまだ一部しか書かれておらず本題の方法が未記入だったため、こちらに投稿する。
- 投稿日:2019-09-29T14:57:06+09:00
vue.js methodsやcomputedを共通化(mixin)する
methodsやcomputedを共通化(mixin)する
参考にしました。
https://qiita.com/_katomasa/items/7d0732306590e2831c0e手順
1
共通化したいmethodsやcomputed等を記述したファイルを作成する。例として utils.js を作成します。
パスは javascript/packs/mixins/utils.js とします。
以下は、moment.jsで日時をparseする関数です。
utils.jsimport moment from 'moment' export default { methods: { startParse: function(start) { return moment(start).format('YYYY-MM-DD') }, endParse: function(end) { return moment(end).format('YYYY-MM-DD') } } }2
1のmethodsを使用するコンポーネントに以下を記述some_component.vueexport default { import utilsMixin from utils.jsへのパス mixins: [utilsMixin] // 上記mixinを使用する宣言 }3
こうすると、2のコンポーネント内で、1で定義したmethodsを使用することが出来る。some_component.vue<td>{{ startParse(task.start) }}</td> <td>{{ endParse(task.end) }}</td>
- 投稿日:2019-09-29T11:00:53+09:00
Nuxt.js + axiosで非同期データ通信ハンズオン風
ここで言う非同期データ通信とは
- apiサーバからデータを取得してページ上に表示することとします。
前提
npm v5.2.0以上
がローカルまたは開発環境に入っていることプロジェクト作成
create-nuxt-app [プロジェクト名]package.json{ "name": "async-test", "version": "1.0.0", "description": "My supreme Nuxt.js project", "author": "yosuke0517", "private": true, "scripts": { "dev": "nuxt", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate", "lint": "eslint --ext .js,.vue --ignore-path .gitignore ." }, "dependencies": { "nuxt": "^2.0.0", "@nuxtjs/axios": "^5.3.6" }, "devDependencies": { "@nuxtjs/eslint-config": "^1.0.1", "@nuxtjs/eslint-module": "^1.0.0", "babel-eslint": "^10.0.1", "eslint": "^6.1.0", "eslint-plugin-nuxt": ">=0.4.2" } }動作確認(とりあえずデフォでOK)
学習で使うデータを作る
JSONPlaceholderというWebサービスを使用。実際の実務でもデータを用意するコストを省くことができる。
https://jsonplaceholder.typicode.com/users
データを取得して表示する
- index.vueの余計な箇所を削除し先ほどのurlから単純にデータを取得し表示(以下のようになっていればOKでstyleタグは削除)
index.vue<template> <div class="container"> <div> {{ users }} </div> </div> </template> <script> const axios = require('axios') const url = 'https://jsonplaceholder.typicode.com/users' export default { asyncData ({ params }) { //コンポーネントを初期化する前に非同期処理を行えるようにするメソッド return axios.get(url) //apiからのデータ取得をリクエスト .then((res) => { //thenはレスポンスを受け取った段階で呼ばれるメソッド(res)にはレスポンスデータが入っている return { users: res.data } //res.dataにはjsonオブジェクトが入っている }) } } </script>1人分のデータを取り出して表示する
- 考え方
- 配列となっているためインデックスを指定したりキーを指定したりするだけ
index.vue{{ users[0] }}とか
index.vue{{ users[0].id }},{{ users[0].name }}とか
v-forで複数のデータをリストで表示する。
- 考え方
- v-forを使う
index.vue<!--{{ users[0].id }},{{ users[0].name }}--> <ul> <li v-for="user in users" :key="user.id"> {{ user.id }},{{ user.name }} </li> </ul>エラーハンドリング
状況
- 404エラーが発生したとする
index.vue
内のurlを存在しないurlへ変更
- 例)
const url = 'https://jsonplaceholder.typicode.com/usersxxx'
考え方
- 引数に
error
を入れてcatchメソッド
で処理するindex.vueexport default { asyncData({ params, error }) { return axios.get(url) .then((res) => { return { users: res.data } }) .catch((e => { //errorメソッドにはステータスコードと表示するメッセージを指定する error({ users: e.response.status, message: '404Error!!!!!' }) })) } }とりあえず以上です。
- 投稿日:2019-09-29T08:00:59+09:00
plunkerでvue その37
概要
plunkerでvueやってみた。
練習問題やってみた。練習問題
XMLを読んで
成果物
http://embed.plnkr.co/OZBXg3xksMECcPIdsbwD/
以上。
- 投稿日:2019-09-29T07:58:47+09:00
plunkerでvue その36
概要
plunkerでvueやってみた。
練習問題やってみた。練習問題
スネークゲームを設置して
参考したページ
https://qiita.com/miyauchoi/items/f753e5fa0209ab2034dd
成果物
http://embed.plnkr.co/fcOo3VltiOqsexYdrBFF/
以上。