Vuexの導入部分のカウンターのコードを書いてみた
動くようにしたかったので ちょっとだけ付け足しました
vuex勉強会制作途中
完全版はこちら
http://qiita.com/P0cChi/items/ebf8fbf035b36218a37e
手順
src/router/index.js ルーティングをするためのjs
// `src/router/index.js` import Vue from 'vue' import Router from 'vue-router' import Hello from '@/components/Hello' //コンポーネントを読み込む Vue.use(Router) export default new Router({ routes: [ { path: '/', //パスを指定 name: 'Hello', component: Hello // 上で読み込んだコンポーネントを指定 } ] })
Formに書き換え
Formというコンポーネントを表示したいので、書き換えます
// `src/router/index.js` import Vue from 'vue' import Router from 'vue-router' import Form from '@/components/Form' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Form', component: Form } ] })
Form.vueを作成
書き換えるだけでは、もちろん対象ファイルがないのでエラーになります。 ファイルを作成しましょう!
src/components/Hello.vue
をコピーします。
src/components/Form.vue
という名前にしましょう。
これで、エラーは解消されたはずです。
必要な部分を残して消します。
<template></template>
の中身を削除しちゃいましょう!
適当に書き換えてみます。
<template> <div> Formページ </div> </template>
ロゴも残ってしまっているので、削除しましょう。
src/App.vue
<img src="./assets/logo.png">
を削除します
//modules/head.vue <template> <div id="app"> <!--ここを削除 <img src="./assets/logo.png"> --> <router-view></router-view> </div> </template>
モジュールを作成します
今回はわかりやすいようにcomponents/modules/
ディレクトリを作成します。
その下に以下のファイルを作っていきます。
- modules/Head.vue
- modules/Textarea.vue
- modules/String.vue
- modules/Button.vue
まずHead.vue
src/components/Form.vue
をsrc/components/moduls/Head.vue
にコピーします。
// `src/components/moduls/Head.vue` <template> <h1>{{title}}</h1> </template> <script> export default { name: 'head', data () { return { title: '感想を入力' } } } </script>
Head.vueをFormに登録
// `src/components/Form.vue` <template> <div> Formページ <Head></Head> </div> </template> <script> import Head from '@/components/modules/Head' export default { name: 'form', data () { return { msg: 'Welcome to Your Vue.js App' } }, components: { Head } } </script>
TextArea.vueを作成
// `src/components/Textarea.vue` <template> <div> <p class="error">{{error}}</p> <textarea></textarea> </div> </template> <script> export default { name: 'textarea', data () { return { error: '入力は必須です' } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .error { color: red; } </style>
// `src/components/Form.vue` <template> <div> Formページ <Head></Head> <Textarea></Textarea> </div> </template> <script> import Head from '@/components/modules/Head' import Textarea from '@/components/modules/Textarea' export default { name: 'form', data () { return { msg: 'Welcome to Your Vue.js App' } }, components: { Head, Textarea } } </script>
String.vueを作成
// `src/components/modules/String.vue` <template> <p>{{string}}</p> </template> <script> export default { name: 'string', data () { return { string: '入力された感想' } } } </script>
// `src/components/Form.vue` <template> <div> Formページ <Head></Head> <Textarea></Textarea> <String></String> </div> </template> <script> import Head from '@/components/modules/Head' import Textarea from '@/components/modules/Textarea' import String from '@/components/modules/String' export default { name: 'form', data () { return { msg: 'Welcome to Your Vue.js App' } }, components: { Head, Textarea, String } } </script> --- # Button.vueを作成
// `src/components/modules/String.vue` <template> <button>{{button}}</button> </template> <script> export default { name: 'button', data () { return { button: '確認' } } } </script>
// `src/components/Form.vue` <template> <div> Formページ <Head></Head> <Textarea></Textarea> <String></String> <Button></Button> </div> </template> <script> import Head from '@/components/modules/Head' import Textarea from '@/components/modules/Textarea' import String from '@/components/modules/String' import Button from '@/components/modules/Button' export default { name: 'form', data () { return { msg: 'Welcome to Your Vue.js App' } }, components: { Head, Textarea, String, Button } } </script>
モジュール作成完了!
お気づきでしょうか・・ dataが分散しています
これの管理を楽にするために一箇所に集めましょう。 ここでvuexの登場です。
vuex構成
- getter
- state
- mutation
- action
今回は、store.jsにまとめて作成します。
vuexをインストール
ターミナル上でnpm install --save vuex
を入力します
``
storeをmain.jsに登録する
// src/main.js import Vue from 'vue' import App from './App' import router from './router' import store from './store' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, template: '<App/>', components: { App }, store })
storeを作成します
src/store/index.js
を作成してください
//`src/store/index.js` import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const head = { state: { title: { form: "感想を入力", confirm: "確認画面", thanks: "送信完了" } }, mutations: { }, actions: { }, getters: { getTitle (state, getters, rootState) { return state.title[rootState.status] } } } export default new Vuex.Store({ state: { status: "form" }, modules: { head } })
// src/component/modules/Head.vue <template> <h1>{{title}}</h1> </template> <script> import { mapGetters } from 'vuex' export default { name: 'head', computed: mapGetters({ 'title': 'getTitle' }) } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
computedとは算出プロパティ statusをグローバルで管理し、statusに合った文言のtitleを返却しています。 state.XXXで自身のstateにアクセスが可能。 rootState.XXXでこの中でいうグローバルのstateにアクセスできます。
メソッドを指定しましょう
butotnにオンクリックイベントを指定します。
// src/component/Form.vue <template> <div> Formページ <HeadComp></HeadComp> <TextareaComp></TextareaComp> <StringComp></StringComp> <button v-on:click="buttonAction">{{button}}</button> </div> </template> <script> import HeadComp from '@/components/modules/Head' import TextareaComp from '@/components/modules/Textarea' import StringComp from '@/components/modules/String' import { mapActions } from 'vuex' export default { name: 'form', data () { return { msg: 'Welcome to Your Vue.js App', button: '確認' } }, methods: mapActions({ 'buttonAction': 'buttonAction' }), components: { HeadComp, TextareaComp, StringComp } } </script>
// src/store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const head = { state: { title: { form: "感想を入力", confirm: "確認画面", thanks: "送信完了" } }, mutations: { }, actions: { }, getters: { getTitle (state, getters, rootState) { return state.title[rootState.status] } } } const Form = { state: { }, mutations: { }, actions: { buttonAction({ commit, state }) { console.log("buttonAction"); } }, getters: { } } export default new Vuex.Store({ state: { status: "form" }, modules: { head, Form } })
これで、メソッドを使うことができました。
stateをとりあえず変えてみましょう!
// src/store/index.js const Form = { state: { }, mutations: { }, actions: { buttonAction({ commit, state, rootState }) { console.log("buttonAction"); rootState.status = "confirm"; } }, getters: { } }
これで、ボタンを押したら、h1が変更されます。
Formのstoreにstateとmutationを追加します
グローバルのアクセスが必要になるためnamespaceを追加します。 名前空間を追加するによって、どこのなんのstate,action,getterか明示できるようになります。
//store const Form = { namespaced: true, state: { step: ['form', 'confirm', 'thanks'] }, mutations: { setStepCount (state, rootState) { console.log("setStepCount"); } }, actions: { buttonAction({ commit, state, rootState }) { console.log("buttonAction"); commit('setStepCount', null, {root: true});//rootへのアクセス } }, getters: { } } export default new Vuex.Store({ state: { status: "form", stepCount: 0 }, mutations: { setStepCount(state) { console.log("rootsetStepCount"); state.stepCount++; } }, modules: { head, Form } })
buttonの表示も変数化
//store import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const head = { state: { title: ["感想を入力", "確認画面", "送信完了"] }, mutations: { }, actions: { }, getters: { getTitle (state, getters, rootState) { return state.title[rootState.stepCount] } } } const Form = { namespaced: true, state: { button: ["確認", "送信"] }, mutations: { setStepCount (state, rootState) { console.log("setStepCount"); } }, actions: { buttonAction({ commit, state, rootState }) { console.log("buttonAction"); commit('setStepCount', null, {root: true});//rootへのアクセス } }, getters: { getButton (state, getters, rootState) { return state.button[rootState.stepCount] } } } export default new Vuex.Store({ state: { stepCount: 0 }, mutations: { setStepCount(state) { console.log("rootsetStepCount"); state.stepCount++; } }, modules: { head, Form } })
//Form <script> import HeadComp from '@/components/modules/Head' import TextareaComp from '@/components/modules/Textarea' import StringComp from '@/components/modules/String' import { mapActions, mapGetters } from 'vuex' export default { name: 'form', methods: mapActions('Form', { 'buttonAction': 'buttonAction' }), computed: mapGetters('Form', { 'button': 'getButton' }), components: { HeadComp, TextareaComp, StringComp } } </script> ``
markdownでdiffを出す
勉強会資料で使えるかも
console.log('aaa') - console.log('bbb') +console.log('ccc')
今日覚えたgitコマンド(git revert)
緊急対応で一時的に非公開にするみたいなことがあって、削除。
それを戻すっていう状況になった時に使ったコマンド。
コミットを1つだけにしたい場合は -n オプションをつけるって下のブログで言っていました。
対象コミットの打ち消しの差分を作ってくれます。
git revert -n XXX(コミットのハッシュ)
あとは普通にコミット。私はtigを使用してます。(同期に教えてもらった)
qiita.com
マージのコミットのハッシュでまとめてrevertできないかと思ってやってみたけどできませんでした。
いちいちコミット単位で打ち消していくのは漏れが発生しそうでちょっと怖い。だからlog管理が必要なんだなぁと・・
最近gitブランチ運用改善の会を行っていて、
git rebase
でログを綺麗にするっていうのを教えてもらっています。
早く実務導入してみたい。
以下参考 d.hatena.ne.jp
CasperJSで非同期部分をテストしたい
firefoxの仕様か何かで、iframeのadがうまく表示されないということがありました。 実装を非同期のものに変えたのですが、 非同期実装した広告が出ているかどうか、テストがしんどいと思い、CasperJSでE2Eテストを実装しました。
デフォルトで要素を待って実行できるなんて、Casperさんは偉い。
.hogehoge
要素を待って、要素を取得します。
casper.waitForSelector(".hogehoge", function _then() { //要素取得 this.test.assertExists(".hogehoge"); },function _onTimeout(){ //タイムアウト時 this.echo("hogehoge not found", "WARNING"); this.test.assertExists(".hogehoge"); });
jsのObjectで.mapしたらはまった
//オブジェクトを作成 var tagNameArray = ["name1", "name2"]; var pushObjs = {}; tagNameArray.map(function (tagName, index){ pushObjs[index] = { "tagname": tagName, "size": "3", "id": index }; }); //勘違い実装 pushObjs.map(function (pushObj){ consoel.log(pushObj); });
ってやると死にます。死にました。 配列の時だけ.mapしましょう。。
for (var i in pushObjs) { pushObjs[i].map(function (pushObj){ consoel.log(pushObj); }); }
これもダメです。
for (var i in pushObjs) { console.log(pushObjs[i]); }
大人しくこうしておきますか・・・
ていねいにvue-cliを使った環境構築手順を書いてみる
Vue-cli環境構築
vue-cliで簡単にvue.jsの環境構築ができます。
前提条件
以下がインストールされていること
- node.js
- npm
node -v
npm -v
でインストールされているバージョンが確認できます。
インストールしていない方はしてください。 nodeはnodebrewなどを使用して、バージョンを管理しておきましょう。
1.ターミナルを開きます。
spotlight(command
+space
)で
ターミナルって入れると候補で出してくれます。
vue-cliをインストールします
npm install -g vue-cli
インストールが始まります。
ちょっと長いかも・・・
終わりました。
プロジェクトを作成します
vue init webpack my-project
webpackをボイラーテンプレートとしてプロジェクトを作成します。
色々聞いてきます。
EnterでOK
EnterでOK
EnterでOK
EnterでOK
yを入力
lintの設定ですね。慣れないうちは、ここはnにしておきましょう
テストの環境を構築するかどうか?にします
こちらはe2eテストの環境ですね。nにします
project作成終了です
まだ終わっていません!
cd my-project
でディレクトリを移動します。
これで、現在地はmy-projectです
npm install
します。
ちょっと長いです。
package.jsonに記載してある依存モジュールをインストールしています。
終わりました。
起動します
環境構築は完了です。
立ち上げてみましょう!
npm run dev
でローカルのnodeサーバーが起動します。
URLを教えてくれるので、アクセスしてみましょう。
この場合はhttp://localhost:8080
です
開きました!
起動したサーバーはctrl
+c
で終了することができます。
便利ツールを導入しておきましょう!
vue.js devtoolsというchromeのアドオンがあります。
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
先ほど立ち上げたhttp://localhost:8080
で、このように使うことができます。
環境構築は以上です!!
参考