ChromeでデバイスにPort fowardingできるの知らなかった
今までローカル上で開発中にモバイル端末で確認したいとき、
browsersync
Browsersync - Time-saving synchronised browser testing
でライブリロード用にローカルサーバ立ててついでにモバイルでも確認するのが快適で良いのですが、
ポートが空いてなくてちょっとめんどくさいとか、ちょろっと確認したいだけだからもっと手軽にやりたい時。
Chromeでフォワード(?)してモバイルで確認できるのを初めて知ったのでメモ。
ちなみに知ったのはPWAの記事からでした。
デバイスをusbでつなぎ、
developerツールの
3点のアイコン > More tools > Remote devices
でコンソールを開く。
Port fowarding にチェックを入れて
指定したいポートをaddする。
PHPの配列の値比較にin_arrayが便利
最近はフロントながらサーバーサイドも触れるというおいしい位置にいるため、 リンクの非表示などでもcontrollerでちゃんと出し分けする意識がつきました。
逆にviewだけ触っていた今までがどうなのって感じですが・・
フロントだとテンプレートにロジックを書きがちな現場です。他のところはどうなのかなぁ。
phpでレビューを受けて改善されたものを以下にメモ。
hogehogeという配列のid2と3に該当するものを除きたい場合。こう書いていました。
foreach ($hogehoge as $key => $hoge) { if ($hoge["id"] == 2 || $hoge["id"] == 3) { unset($hogehoge[$key]); } } return $hogehoge;
それがレビューを受けてこうなる。
foreach ($hogehoge as $key => $hoge) { if (in_array($hogehoge["id"], [2, 3])) { unset($hogehoge[$key]); } } return $hogehoge;
配列にある値をチェックするin_array
比較が配列で書けて便利。比較値の増減にも対応が簡単。
おお!と思ったのですが、レビューからさらに変更し、controllerの処理を消してmodelで取得のidを絞りました。
CasperJsでnode-notifier が動かない
確実に勉強不足です。
CasperJsでe2eテストを書きました。 全てを実行してログをとるというよりは、実行するだけして、テストの通らないところを適宜直したい。 と思ったのですが、1つのテストが通るのが遅い。(非同期の部分のテストのため、表示を待つからです)
それを眺めているわけにもいかないので、テストが失敗した時点でデスクトップ通知が欲しい。 nodeのモジュールでいけないかとも思ったのですが、実行できませんでした。
CasperJsでnodeのできることがわからない( ´•̥ו̥)
できないのかな( ´•̥ו̥
)
何かいい方法ないかな・・ 普通にログを全部出力して後で眺めてもいいような気もしますが・・
もう少し考えます。
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