- 投稿日:2020-01-12T21:46:51+09:00
【Jest】Vueのテストを書こう!
Vueのテストを書こう!
Vue.jsのコンポーネントのテストについてナレッジを貯めていきます。(随時追加)
テキスト表示についてのテスト
import { mount } from '@vue/test-utils' import HelloWorld from '@/components/HelloWorld.vue' describe('HelloWorld.vue', () => { it('renders a HelloWorld', () => { const wrapper = mount(HelloWorld) expect(wrapper.text()).toMatch("HelloWorld!!") }) })DOM要素についてのテスト
import { mount } from '@vue/test-utils' import HelloWorld from '@/components/HelloWorld.vue' describe('HelloWorld.vue', () => { it('renders a HelloWorld', () => { const wrapper = mount(HelloWorld) expect(wrapper.html()).toMatch("<div><p>HelloWorld!!</p></div>") }) })子コンポーネントをスタブにしてテスト
shallowMount
メソッドで子コンポーネントをスタブ(代替えの偽物)としてマウントします。
※mount
だと子コンポーネントまですべてマウントされます。const shallowWrapper = shallowMount(Parent) console.log(shallowWrapper.html())
- ログの結果
子コンポーネントが
<vuecomponent-stub />
とスタブとなって出力されています。<div><vuecomponent-stub></vuecomponent-stub></div>
コンポーネントのfactory関数を定義する
一番上に
values
オブジェクトをまとめてdata
にして、新しいwrapper
インスタンスを返すファクトリ関数を宣言します。このようにすると、すべてのテストで
const wrapper = shallowMount(Foo)
を複製する必要がありませんimport { shallowMount } from '@vue/test-utils' import Foo from './Foo' const factory = (values = {}) => { return shallowMount(Foo, { data () { return { ...values } } }) } describe('Foo', () => { it('welcome メッセージを描画する', () => { const wrapper = factory() expect(wrapper.find('.message').text()).toEqual("Welcome to the Vue.js cookbook") }) it('usernameが7未満のときエラーを描画する', () => { const wrapper = factory({ username: '' }) expect(wrapper.find('.error').exists()).toBeTruthy() }) it('usernameが空白のときエラーを描画する', () => { const wrapper = factory({ username: ' '.repeat(7) }) expect(wrapper.find('.error').exists()).toBeTruthy() }) it('usernameが7文字かそれ以上のとき、エラーが描画されない', () => { const wrapper = factory({ username: 'Lachlan' }) expect(wrapper.find('.error').exists()).toBeFalsy() }) })参考URL
vue-testing-handbook
➡︎より実践的な使い方がわかる
- 投稿日:2020-01-12T18:35:27+09:00
MonacaのアプリをCircleCIとDeployGateで自動デプロイした話
背景
Monacaで作成中のアプリの試験的配布を自動化したかった
↓
そんな中CircleCIとDeployGateでアプリのリリース自動化という記事を色々見つけた
↓
そこに検索ワードとしてMonacaやCordovaを足したらそれっぽい記事が見つからなかった....
↓
ので頑張った
(作った後にMonaca CIの存在に気付いた...)目的
Vue.jsにて開発しているMonacaアプリについて
ローカルで作成して
GitHubにpushして
CircleCIでビルドして
DeployGateでデバッガに配布したい......とりあえずAndroid版だけ
内容
端的に言えば
CircleCIとDeployGateのアカウントを無料のでいいので取得し、GitHubと連携
後はリリースしたいリポジトリに下記ファイルを置けば動く
最後の行の[トークン]と[ユーザー名]は自分のDeployGateの情報にて書き換える.circleci/config,ymlversion: 2 jobs: build: docker: - image: circleci/android:api-28-alpha working_directory: ~/repo # 作業フォルダ steps: # ビルド環境構築 - run: name: apt-get upgrade command: | sudo apt-get update sudo apt-get upgrade -y - run: name: Setup Node.js via nvm command: | curl --silent -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV echo 'source "$NVM_DIR/nvm.sh" --no-use' >> $BASH_ENV source $BASH_ENV nvm install v10.15.3 --no-progress nvm alias default v10.15.3 sed -i -e 's/ --no-use//' $BASH_ENV - run: name: Install Cordova command: | npm install -g cordova sudo apt-get install gradle -y gradle -v - checkout # キャッシュがある場合はキャッシュから依存関係を復元 - restore_cache: # 復元するキャッシュのkey keys: - v2-dependencies-{{ checksum "package-lock.json" }} - v2-dependencies- # Cordovaのビルド設定 # この作業はチェックアウトしてCordovaのプロジェクトが出来てから行う必要がある - run: name: Setup Cordova to build as Android app command: | cordova platform add android@8.0.0 gradle dependencies # 依存関係のインストール - run: name: Install dependencies command: npm install # ビルド - run: name: PreBuild command: npm run build # ビルドの確認 - run: name: Check dist command: ls -la www # キャッシュの保存 - save_cache: paths: - node_modules key: v2-dependencies-{{ checksum "package-lock.json" }} # ビルド - run: name: Cordova Build command: cordova build --debug --device # デプロイ - run: name: Upload to DeployGate command: | APK_PATH=platforms/android/app/build/outputs/apk/debug/app-debug.apk COMMIT_HASH=$(git log --format="%H" -n 1 | cut -c 1-8) curl -F "file=@${APK_PATH}" -F "token=[トークン]" -F "message=Test Build by CircleCI <${COMMIT_HASH}>" https://deploygate.com/api/users/[ユーザー名]/appsまとめ・所感
これで手元のVSCodeからPushするだけでDeployGateからアプリ配布の通知が来てインストールできるので超便利になった
ビルドしたアプリがVue製のためタグにVueがとりあえず入っているけれど、ビルド環境の内容としてはReactでもAngularでも変わらないかと
- 投稿日:2020-01-12T17:40:24+09:00
【勉強会ポエム】パンダ本:第8章 Vue.js入門&実践活用?
(出典:https://gihyo.jp/book/2018/978-4-7741-9706-7)記事の概要?♀️
- 勉強会に参加した感想と備忘録
- 通称パンダ本 p138〜
- 第8章 Vue.js入門&実践活用を読みながら、学んだことを残します
誰向けか?
- あんまり勉強会に参加したことがない人
- Vueの概要を知りたい人
- Vueの環境構築をしてみたい人
Vue.jsの概要
Vueとは
- UIを構築するためのプログレッシブフレームワーク
- 中国出身のEvanYou氏が開発
Evan You 氏
- Googleのフロントエンドエンジニア
- AngularJSとか
- JavaScriptフレームワークの開発元Metor経た
- Vue.jsに注力するため独立
Vue.jsの4つの特徴
1.テンプレートとCSS
テンプレート言語はHTML
- 新たなDSLやプリプロセッサ(PugやHaml)を学ぶ必要がない
- 既存のWEBアプリケーションの移行コストが低い
HTMLとCSS共通して、プリプロセッサを選択できるという特徴がある
2.リアクティブシステム
- あるデータを変更した際に、変化がデータのフローに沿って伝播して関連するデータや表示なども書き換わる
- モデルはプレーンなJavaScriptオブジェクト
- モデルを変更するときにビューを更新する
3.コンポーネント
- 独立した小さな部品に分割して再利用可能にする
- 開発や管理、更新が行いやすい
4.段階的な機能の取捨選択
- Vue.jsそのものは、コンポーネントを作成して描画するためのビューレンダリング用のライブラリ
- Vue RouterやVuexなどのさまざまな機能を使うことができる
- 上記を使うことで小さくコンパクトに、大規模に開発したいときなどスケールを合わせることができる
Vueをはじめるには
主に3つの方法がある
- CDN
- ダウンロード(ソースコードをプロジェクト内部に埋め込む)
- Vue CLI (npmでインストールしていく)
Vue CLIを推奨(公式)
- 必要な環境が簡単に整う
- 便利機能が使用できる
この記事では、Vue CLIを使って環境を構築していきます!
Vue CLIをインストール(npm) $ npm i -g vue-cli 無事にインストールできたか確認 $ vue --version #=>2.9.6プロジェクトを作成する
vue init webpack vueChat
- ↓エラーになる場合
Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
- 参考にした記事
- 記事を確認すると、nodeのバージョンを6以上にあげればOKとのこと(ちゃんと調べてなくてすみません。)
# 現在のNodeのバージョンを確認 nodebrew ls v5.3.0 v9.10.1 v10.1.0 v12.12.0 current: v5.3.0残念ながら、5.3.0でした
# とりあえず5よりもあげるようにする nodebrew use v9.10.1
- これでエラー出なくなりました!
引き続き開発環境を作ります(初期化)
// vueChatというプロジェクト名にしました $ vue init webpack vueChat # ここから作成するプロジェクトについて色々入力していく ? Project name vuechat ? Project description A sample chat of Vue.js ? Author azumax ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? No ? Set up unit tests No ? Setup e2e tests with Nightwatch? No ? Should we run `npm install` for you after the project has been created? (recommended) npm vue-cli · Generated "vueChat".
- インストールが完了したら作ったディレクトリに移動して、npm実行する
# To get started: $ cd vueChat $ npm run dev
- ブラウザにアクセスしてみる
(http://localhost:8080)
- 上図のような画面が表示されれば、ひとまず開発環境構築は成功です!
ディレクトリ構成の確認
開発環境のディレクトリ構成を確認してみましょう
index.html
- プロジェクトの起点になる
- 表示用HTML
src
- 作成したアプリケーションのソースコード格納
- 作業用ディレクトリ
src配下のディレクトリ
- main.js
- アプリケーションの起点。エントリーポイントとなるファイル
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. ## ライブラリやコンポーネントをインポートする ## この3つは大事そう! import Vue from 'vue' import App from './App' import router from './router' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
- 以下のコードでインスタンスを作成するとVueアプリケーションが実行される
new Vue({ el: '#app', #=> 出力・描画されるHTMLの要素を指定する。index.html router, #=> routerの設定 components: { App }, #=> 使用するコンポーネントの定義 template: '<App/>' #=> 描画 })
- インスタンスの引数のオブジェクトの各属性で各設定を行う
componentsには、使用したいコンポーネント
{key: コンポーネント}
で登録する定義されたkeyが、templateで使用するコンポーネントの要素名になる
components: { Hoge: App }, #=> keyを指定する template: '<Hoge/>' #=> 要素名も合わせる
- build
- webpackなどトランスパイルに必要な設定ファイルが格納される
npmコマンドについて
npm run dev
- ファイル更新すると表示されているページも更新されるホットリロード機能を持ったローカルホスト立ち上げコマンド
npm run build
- 実行すると「distディレクトリ」がプロジェクト直下に作成される
- distディレクトリには、minifyされたindex.htmlとかトランスパイルされたJSとCSSが格納されたstaticディレクトリが作成される
基本的には、
- ローカルホスト立ち上げなら run dev
- トランスパイル実行もしたければ run build
単一ファイルコンポーネント
- Vue.jsの醍醐味です
- 勉強会の時間内で全て終わらなかったので、途中で終わってしまいます
- 時間を見つけて続きを書いていこうかと思います?
1つのファイル内で3つのブロックに切り分けて記述を行う、Vue専用の仕組み
- JavaScriptのロジック
- テンプレート
- スタイル
拡張子は「*.vue」
コンポーネントを複数に分けると、色々煩雑
- すべてのコンポーネントに一意な名前を強制する
- エディタでのシンタックスハイライト使えない
- 複数行HTMLでバックスラッシュ、プラス記号が強要され、可読性さがる
- ビルド処理がないことでHTMLの制限をうける
これらの問題を解決するのが、単一ファイルコンポーネントのしくみ
最後にポエムさせてください?♂️
- 以前にVueの開発環境構築をしたときは、codesandboxを使ったのですが、今回はVueCLIで構築をしました
- 参考:【勉強会ポエム】Vue.js×Firebaseで簡単なTwitter風アプリケーションを作ろう
- 勉強会というタイトルではありましたが、内容はもくもく会でした
- 勉強会だと思い(ハンズオンやセミナー形式と勘違い)来場した方も複数いらっしゃり、もくもく会とわかったタイミングで帰宅する姿が見られました。
- 私自身は、もくもくやりながら、何か質問ができればいいなーくらいに考えていたので?♂️
- 主催者の方は何かつまずいていないか常に気にしてくれて、いい人でした!
- コミュニティ作りに力をいれているような印象を受けました!
参考記事
- 投稿日:2020-01-12T17:23:15+09:00
本当のimport Vue from 'vue'を研究して、分かってきたもの
import Vue from 'vue'はなぜ使えるか?
Vuejsの開発の際、よく最初に出てくるこれ
import Vue from 'vue';下のような相対パスなどはまだわかりやすいけど、
import Example from './Example.vue';
vue
はなずimport
できるのか、みんな様こんな疑問はないのか。
もしかして俺一人の疑問かも?少し研究してきたことをまとめてみた。
importとは
Javascriptのモジュールシステムです。他のファイルを使いたい時、
require
functionで他のファイルの内容を引用する。
es6
を使っている時、import
をrequire
にコンパイルする。
だから、実際に実行するコードは以下。import Vue from 'vue'; ⬇️ const Vue = require('vue')nodejs引用ルール
実は、nodejsの中に、
require
を使う時に、require.reslove
functionを使ってファイルのパスを探している。このfunctionは優先順位は以下になる。
require(X) from module at path Y
1.もしX
はコアのパッケージかどうか、普段のpath
などみたいは直接引用される。ではなければ、次へ。
2.もしX
は/
から始めれば、Y
のパスはOSのroot
と設定。ではなければ、次へ。
3.もしX
は./
,/
,../
から始めれば、(Y + X)
ファイルかディレクトリ引用。ではなければ、次へ。
4.node_modules
フォルダの中に、見つかる!node_modulesにあるvue
node_modules
に確かにvue
というフォルダは存在しているが、new Vue()
などの操作の時は、JsのObjectとして使っている。では、なぜか!
真の犯人まではもう少し?❗️
npm
のパッケージとして、内部の出力はまたルールがある!
まずは、node_modules/vue
のディレクトリツリーを見てみる。├── LICENSE ├── README.md ├── dist ├── package.json ├── src └── typesルールは以下になる。
1.package.json
にmain
が定義されたら、main
に入り口を探す。
2.package.json
がなければ、index.js
かindex.node
を読む。
3.どちらもなければ、Error: Cannot find module 'some-library'
を投げる。では、
node_modules/vue/packeage.json
こう書いてある❗️... "main": "dist/vue.runtime.common.js", ...ではでは、だんだん明らかになってきた❗️
本当にいつも
import
したものは...import vue from 'vue'; // 実は、これに変換する const vue = require('./node_modules/vue/dist/vue.runtime.common.js');その内容は
if (process.env.NODE_ENV === 'production') { module.exports = require('./vue.runtime.common.prod.js') } else { module.exports = require('./vue.runtime.common.dev.js') }これは普段
npm
のスクリプトにあるNODE_ENV=development
を読んで、実行環境に応じて違うvue
インスタンスのexport
ができるようになった?今回の
import
ルールや他にも今回出てなかったルールの詳細はnodejsのドキュメントに?
- 投稿日:2020-01-12T17:23:15+09:00
import Vue from 'vue'の意味を研究して、分かってきたもの
import Vue from 'vue'はなぜ使えるか?
Vuejsの開発の際、よく最初に出てくるこれ
import Vue from 'vue';下のような相対パスなどはまだわかりやすいけど、
import Example from './Example.vue';
vue
はなずimport
できるのか、みんな様こんな疑問はないのか。
もしかして俺一人の疑問かも?少し研究してきたことをまとめてみた。
importとは
Javascriptのモジュールシステムです。他のファイルを使いたい時、
require
functionで他のファイルの内容を引用する。
es6
を使っている時、import
をrequire
にコンパイルする。
だから、実際に実行するコードは以下。import Vue from 'vue'; ⬇️ const Vue = require('vue')nodejs引用ルール
実は、nodejsの中に、
require
を使う時に、require.reslove
functionを使ってファイルのパスを探している。このfunctionは優先順位は以下になる。
require(X) from module at path Y
1.もしX
はコアのパッケージかどうか、普段のpath
などみたいは直接引用される。ではなければ、次へ。
2.もしX
は/
から始めれば、Y
のパスはOSのroot
と設定。ではなければ、次へ。
3.もしX
は./
,/
,../
から始めれば、(Y + X)
ファイルかディレクトリ引用。ではなければ、次へ。
4.node_modules
フォルダの中に、見つかる!node_modulesにあるvue
node_modules
に確かにvue
というフォルダは存在しているが、new Vue()
などの操作の時は、JsのObjectとして使っている。では、なぜか!
真の犯人まではもう少し?❗️
npm
のパッケージとして、内部の出力はまたルールがある!
まずは、node_modules/vue
のディレクトリツリーを見てみる。├── LICENSE ├── README.md ├── dist ├── package.json ├── src └── typesルールは以下になる。
1.package.json
にmain
が定義されたら、main
に入り口を探す。
2.package.json
がなければ、index.js
かindex.node
を読む。
3.どちらもなければ、Error: Cannot find module 'some-library'
を投げる。では、
node_modules/vue/packeage.json
こう書いてある❗️... "main": "dist/vue.runtime.common.js", ...ではでは、だんだん明らかになってきた❗️
本当にいつも
import
したものは...import vue from 'vue'; // 実は、これに変換する const vue = require('./node_modules/vue/dist/vue.runtime.common.js');その内容は
if (process.env.NODE_ENV === 'production') { module.exports = require('./vue.runtime.common.prod.js') } else { module.exports = require('./vue.runtime.common.dev.js') }これは普段
npm
のスクリプトにあるNODE_ENV=development
を読んで、実行環境に応じて違うvue
インスタンスのexport
ができるようになった?今回の
import
ルールや他にも今回出てなかったルールの詳細はnodejsのドキュメントに?
- 投稿日:2020-01-12T15:48:28+09:00
Indexed Database APIを使ってスタンドアロンな付箋アプリを作ってみる
記事の趣旨
せっかくIndexed Database APIについて勉強したので,それを使ってブラウザアプリを作ってみた.
1. 作ったアプリと技術要素
ブラウザにスティッキー(付箋紙)っぽいメモを残していけるツール.本当はカンバン方式の管理ツールを作りたかったんだけれど,力尽きたのでいったん保留.画面キャプチャは以下のとおり.
使用した技術要素は以下のとおり.Vue.jsは初めて触るので,書籍と睨めっこしながらの対応.
- HTML
- CSS
- Vue.js
- Indexed Database API(敢えてライブラリ未使用)
ソースコードはGithubのリポジトリに置いているのでご自由にどうぞ.動作は「Chrome 79.0.3945.117」で確認.Edgeでも動作するがレイアウトが若干崩れる.
2. 操作方法
直感で扱えるレベルだと思うけれど,とりあえず以下のとおり.
- cloneなりzip downloadなりでローカルに落としてきたら
kanban.html
を開く.- 付箋紙を新たに作りたいときは左下のプラスマークをクリック.
- 付箋紙はドラッグ&ドロップで自由に移動可能.
- 付箋紙をダブルクリックすると編集ウィンドウ(後述)が開く.
- 編集ウィンドウでURLを登録しておけば,付箋紙左下の「URL」ボタンクリックでその画面に新タブで遷移可能.
3. 苦戦したポイント
スキル低いので,初歩的だったり,間抜けなものばかりだが,恥を忍んで書いていく.
3.1 Promise
以下の処理は,「DBへのコネクションを確立する」->「チケットを全件取得する」->「グローバル変数にチケット情報を詰め込む」という意図のコードになる.このうち,
createConnection()
およびgetAllTickets()
は,Promise
オブジェクトを返却する関数である.先日の記事でも述べたとおり,Indexed Database APIは非同期処理であるため,Promise
を活用することで同期を図っている.created: function() { createConnection().then( getAllTickets() ).then( (allTickets) => { allTickets.forEach( ticket => { tickets.push({ id: ticket.id, text: ticket.text, url: ticket.url, categoryId: ticket.categoryId, left: ticket.left, top: ticket.top, zIndex: ticket.zIndex, deleted: false }) } ) } ).catch( (reason) => alert(reason) ) }さて,上記コードは一部が不正で,これだと同期処理にならない.どこかわかるだろうか.
答えは3行目.
getAllTicket()
と書いているが,ここはgetAllTicket
と,関数オブジェクトを指定しないといけない.
promise.prototype.then()
は,あくまでメソッドであり,その引数指定するのはコールバック関数.ものすごく間抜けなミスだが,うっかりif/elseの構文と同じような感覚で記述してしまい,上記のミスに至ってしまった.3.2 Bubbling
今回の付箋紙オブジェクトは,複数のレイヤで構成されているので,Bubblingを意識してイベントをハンドリングしないといけない.が,そもそもその辺りを全然理解しておらず,序盤はかなり意図しない挙動に苛まれた.たぶん今も多少バグは残っていると思われる.
Bubblingについては,こちらのページの説明がとてもわかりやすいと思う.定義を引用させていただくと以下のとおり.
要素上でイベントが起きると、最初にその上のハンドラが実行され、次にその親のハンドラが実行され、他の祖先に到達するまでそれらが行われます。
今回でいうと,例えば「URL」ボタンをクリックすると,続けて付箋紙自体にセットされたマウスダウンイベントが処理されることになる.後者は付箋紙の移動に関わる処理なので,付箋紙がワープするなどの謎挙動が頻発していた.
Bubblingを防ぎたい場合は,
event.stopPropagation()
を呼び出すことで,それ以降の親オブジェクトへの伝播を抑制することができる.4. ペンディングしている事項
- 付箋紙の色の変更機能
- categoryIdという死にパラメータがその名残
- ファイルサーバやローカルへのショートカットボタン
- エクスプローラの直接操作は無理そうなので,パスをクリップボードにコピーする処理を想定
- ゴミ箱アイコンへのドロップによる付箋紙削除処理
- 面倒臭くなって今は削除ボタンで代替
- カンバンボード化と,付箋紙へのステータス(ToDo,WIP,Done)導入
- そもそもそれを目指したアプリだったので
- 複数タブ対応
- 現在は複数タブでこのアプリを開いたら何が起きるか不明
- 投稿日:2020-01-12T13:17:45+09:00
[Vuejs(Nuxtjs)] 僕のVee-validateカスタムルール
TL;DR
- 自分が業務で使用しているvee-validate 3.xのカスタムルールをまとめました。
概要
- 自分はメディア運営会社のエンジニアとして働いているもので、メディアのコンテンツを入稿するツールをnuxtjsで開発や運用しています。入稿されるデータに不整合が起きないように、データ作成/更新前のバリデーションには気を使っています。バリデーションライブラリでは、vee-validateを使用しています。
- 属性が多いモデルに関しては、様々な条件に柔軟に対応しないといけないのですが、デフォルトで提供されているvee-validateのルールだけだと対応できないな...と思い、色々と自分でカスタムで実装しました。が、そもそもそんなにカスタムルールの作り方が見つからなかったと思ったので、作り方などまとめました。
対象者
- vee-validateは使ったことあり、これからカスタムルールをどう実装していく方。
技術スタック
- nuxtjs 2.x
- vuetify 2.x
- vee-validate 3.x
カスタムルールの作り方
ここでは、vee-validate3.xをどうやってnuxtjsで使えるようにすればいいのかは詳細には書きません。
まずは、
vee-validate
をnuxtjs
で使えるようにするためのプラグインを用意します。
nuxt.config.js
のplugins
プロパティで読み込みます。plugin/vee-validate.js// vee-validateからルールを拡張できる関数をインポート import { extend } from 'vee-validate' // vee-validateがデフォルトで用意してくれているルールをインポート import * as Rules from 'vee-validate/dist/rules' // 自分が実装したvee-validateのカスタムルールをインポート import * as CustomRules from '~/utils/validation-custom-rules.js' for (const rule in Rules) { extend(rule, Rules[rule]) } for (const rule in CustomRules) { extend(rule, CustomRules[rule]) }そしてカスタムルールを下のように定義します。下のページを参考しました。
https://logaretm.github.io/vee-validate/advanced/rules-object-expression.html#cross-field-validationutils/validation-custom-rules.jsconst custom_rule = { // ルールを書くときに使う引数。 params: ['compare'], // バリデーションロジック validate(field, { compare }) { return true // or false true: バリデーションエラーなし, false: バリデーションエラーあり }, // バリデーションエラーメッセージ message(field, { compare }){ return `validation error. ${field}` }, } export { custom_rule }プロジェクトで実装したカスタムルールの一部を記載。
utils/validation-custom-rules.js/** * 数字が指定した桁数以下か検証する * @param max 最大桁数 */ const max_digits = { params: ['max'], validate(value, { max }) { return value ? String(value).length <= max : true }, message(field, { max }) { return `${field}は${max}桁以下でなければなりません` }, } /** * コレクションの要素数が指定していた数以下かを検証する * @param maxLength 最大要素数 */ const collection_max_length = { params: ['maxLength'], validate(value, { maxLength }) { if (!Array.isArray(value)) { return false } return value.length <= maxLength }, message(field, { maxLength }) { return `${field}は${maxLength}つまでしか選択することができません。` }, } export { max_digits, collection_max_length }実際にどう使うか
実際にコンポーネントでどうカスタムルールを使うかを記載します。
<template> <v-row justify="center"> <v-col cols="12"> <!-- rulesを文字列で渡す場合 --> <validation-provider v-slot="{ errors }" name="記事ID" rules="numeric|max_digits:7"> <v-text-field v-model="articleId" :error-messages="errors" label="記事ID" counter="7" type="number" /> </validation-provider> </v-col> <v-col cols="12"> <!-- オブジェクトを渡すこともできます。 --> <validation-provider v-slot="{ errors }" name="色" :rules="{ collection_max_length: { maxLength: 3 } }"> <v-select v-model="selectedColors" multiple chips :items="colors" :error-messages="errors" /> </validation-provider> </v-col> </v-row> </template> <script> export default { data() { return { articleId: 0, selectedColors: [], colors: ['red', 'blue', 'yellow', 'green', 'purple'].map((color) => ({ value: color, text: color })), } }, } </script>自分が指定したバリデーションエラーメッセージが表示されたことを確認。
まとめ
- メディアのコンテンツを入稿するツールを作っていく以上、不適切なデータが入稿され、メディアのブランドや信用性が損なわれるのを防ぐ必要があると思っています。こうやって、カスタムでバリデーションルールを実装できるので、コンテンツを作るユーザーが安心して、良いコンテンツを入稿できるように、日々起こりうるデータの不整合をなくしていければと思います。最後まで読んでいただき、ありがとうございました。
- 投稿日:2020-01-12T12:09:26+09:00
Vue ナビゲーション
○ <router-link :to="{ path: '/product' }"> ○ <router-link :to="{ path: '/product', query: { page: 1 } }"> x <router-link :to="{ path: '/product', param: { id: 1 } }"> ○ <router-link :to="{ name: 'product', param: { id: 1 } }">
- 投稿日:2020-01-12T11:40:53+09:00
Vue URLにハッシュをつけない
Vue Router
ハッシュ
ヒストリーハッシュモードはハッシュ値の変更によって現在のルートを検知するため、
ブラウザのHistory Apiのサポートやサーバ側の設定を必要としないが、自動的にURLに「#」が付与されページ内リンクが使用できない
export default new Router({
+ mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home,
},あと.htaccessかserver.confにmode_rewrite的な設定必要
- 投稿日:2020-01-12T09:20:03+09:00
npm run serveできない
Windowsで開発していたvue.jsファイルをmacで動かそうとしたら以下のようなエラーが出た。
$ npm run serve > my-project@0.1.0 serve /Users/hoge/hoge > vue-cli-service serve INFO Starting development server... 10% building 2/2 modules 0 activeevents.js:180 throw er; // Unhandled 'error' event ^ Error: getaddrinfo ENOTFOUND x86_64-apple-darwin13.4.0 at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:26) Emitted 'error' event at: at GetAddrInfoReqWrap.doListen [as callback] (net.js:1412:12) at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:17) { errno: 'ENOTFOUND', code: 'ENOTFOUND', syscall: 'getaddrinfo', hostname: 'x86_64-apple-darwin13.4.0' } npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! my-project@0.1.0 serve: `vue-cli-service serve` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the my-project@0.1.0 serve script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /Users/.npm/_logs/2020-01-11T15_34_59_526Z-debug.log解決策
モジュールを再インストールする。
rm -rf node_modules/ npm installsudoをつけて実行する。
https://stackoverflow.com/questions/49008498/npm-run-serve-errorsudo npm run serve試したこと
https://akamist.com/blog/archives/2827
上記の記事を参考にrm -rf node_modules rm package-lock.json npm cache clear --force npm installを実施。改善しない...。
なんなら
npm install
でpythonのエラーが出てきた...。gyp ERR! find Python gyp ERR! find Python Python is not set from command line or npm configuration gyp ERR! find Python Python is not set from environment variable PYTHONpythonエラーはcondaの仮想環境を停止させたら消えたが、依然として解決できず...
vueのバージョン確認
~/documents/vue $ vue --version @vue/cli 4.1.2原因はなんだったのか
調査中
- 投稿日:2020-01-12T02:49:30+09:00
Vue AtomicDesignでフォルダ構成する
AtomicDesign
今回はAtomicDesignの考えのもと、フォルダ構成していきたいと思います。
AtomicDesignとは
一言で言うと5段階に区切って定義するUIデザイン手法。
5段階とは、
Atoms(原子)
,
Molecules(分子)
,
Organisms(有機体)
,
Templates(テンプレート)
,
Pages(ページ)
です。
化学用語が分からなくても実は簡単。5段階詳しく
Atoms(原子)
ボタンやテキスト入力などの分けられない単位。
Molecules(分子)
ボタンやテキスト入力を組み合わせたフォーム(検索フォーム)。
Organisms(有機体)
フォームだったりボタンなど組み合わせたヘッダー。
Templates(テンプレート)
ヘッダーとかフッターを組み合わせたページの枠組みです。
Pages(ページ)
テンプレートの枠組みに内容を入れた状態がページ。VueでAtomicDesign
AtomicDesignの考えをもとにVueでフォルダ構成しました。
それがこちら. ├── node_modeuls/ ├── src/ │ ├── assets/ │ ├── components/ │ ├── atoms/ │ │ └──buttons/ │ ├── molecules/ │ └── organisms/ │ └── footer.vue │ ├── pages/ ├── main.js ├── router/ │ └── index.js ├── store/ └── App.vueAtomicDesignをカスタマイズして構成しました。
カスタマイズ点
1.Templateは必要がないので削除
2.organismsとpagesのみstoreとやりとりするのはOK。
3.pagesはrouterとやりとりするのでcomponents外
4.atomsの中にもボタンや入力欄を分けるためにフォルダを作成
人それぞれの好みとプロジェクト規模により異なる点もあるかと思うので参考にしてもらえればと思います。
以上!はてなブログもやってます
はてなブログのVue系⬇︎
https://taitoajiki.hatenablog.com/archive/category/Vue