- 投稿日:2020-10-09T21:25:34+09:00
v-modelをVuexで使用する方法
はじめに
複数のコンポーネントで同じv-modelを共有したい時がありますよね。
そんな時、$emitやpropsを使っても良いですが、プロジェクトが大きいとコードが肥大化してしまいます。
そこで今回はVuexを使用して、v-modelのデータを一元管理しましょう。ソースコード
inputタグにv-modelを設定し、imputのvalueをinputタグ直下のpタグに出力しています。
Test1.vue<template> <div> <input type="text" v-model="$store.state.user.name" > <p>{{ $store.state.user.name }}</p> <input type="text" v-model="$store.state.user.email" > <p>{{ $store.state.user.email }}</p> <input type="text" v-model="$store.state.user.password" > <p>{{ $store.state.user.password }}</p> </div> </template>Test1.vue<script> export default { computed: { name: { get() { return this.$store.state.user.name; }, set(value) { this.$store.commit('userName', value); } }, email: { get() { return this.$store.state.user.email; }, set(value) { this.$store.commit('userEmail', value); } }, password: { get() { return this.$store.state.user.password; }, set(value) { this.$store.commit('userPassword', value); } } } } </script>store.jsimport Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { user: { name: '', email: '', password: '' } }, mutations: { userName(state, name) { state.user.name = name }, userEmail(state, email) { state.user.email = email }, userPassword(state, password) { state.user.password = password } } })実行結果が以下です。
v-modelが正常に動作していますね。Vuexで値を管理しているので、
別のコンポーネントでも動作します。
その様子も見てみましょう。Test2.vue<template> <div> <p>{{ $store.state.user.name }}</p> <p>{{ $store.state.user.email }}</p> <p>{{ $store.state.user.password }}</p> </div> </template>この通り、別コンポーネントにも反映されています。
...
し か し
非 常 に 冗 長 で あ る
mutationsとget,setで同じ処理が何回も繰り返されています。
なんとかしましょう。
リファクタしてみる
スプレッド演算子を用いて、簡単に記述していきます。
(vueファイルのHTML部分は何も変えないので割愛します。)Test1.vue<script> export default { data() { return { user: { name: '', email: '', password: '' } } }, methods: { setSignUpData() { this.$store.commit('setSignUpData', this.user); } } } </script>store.jsimport Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { user: {} }, mutations: { setSignUpData(state, inputSignUpData) { state.user = {...state.user, ...inputSignUpData} } } })とても綺麗になりましたね。
この記述方法でも正常に動作します。以上がv-modelをVuexで使用する方法でした。
- 投稿日:2020-10-09T12:52:43+09:00
Sage 9 + Vue.JS を設置
sage9を設置
- sage9をインストール
- sagajsを上書き
- Vue.jsをインストール
yarn add vue
- その他アプリ
yarn add --dev vue-loader vue-template-compiler eslint-plugin-vue vue-style-loader
- resources/assets/config.jsonにパスを通す
"resources/assets/scripts/vue/**/*.vue"
コンパイルでエラーが出るのでcosmiconfigをアップデート
yarn add cosmiconfig
- 投稿日:2020-10-09T10:58:15+09:00
dialogをコンポーネント化にする
やりたいこと
ボタンをクリックして、ダイアログをポップアップ出る。かつ、ボタンとダイアログのコンポーネントが同じではない場合。
親コンポーネント
Click.vue<template> <div id="app"> <v-app id="inspire"> <v-row justify="center"> <v-btn slot="activator" color="red lighten-2" @click="dialogs.dialog = true" dark>Click Me</v-btn> <dialog-card :dialog="dialogs"></dialog-card> </v-row> </v-app> </div> </template> <script> export default { components: { DialogCard: () => import("./DialogCard.vue") }, data() { return { dialogs: { dialog: false, notifications: false, sound: true, widgets: false } }; }, }; </script>
- 親部分説明
:dialog="dialogs" で子供にdialog(プロパティ)転送するデーターとします。
@clickでダイアログの表示非表示を切り替えます。子コンポーネント
DialogCard.vue<template> <v-dialog v-model="dialog.dialog" max-width="600px" persistent> <v-card> <v-card-title> <span class="headline">連絡先</span> </v-card-title> <v-card-text> <v-container> <v-row> <v-col cols="12" sm="6" md="4"> <v-avatar color="indigo"> <v-icon dark>mdi-account-circle</v-icon> </v-avatar> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field label="姓*" required></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field label="名" required></v-text-field> </v-col> <v-col cols="12"> <v-text-field label="Email*" required></v-text-field> </v-col> <v-col cols="12"> <v-text-field label="住所"></v-text-field> </v-col> <v-col cols="12" sm="6"> <v-select :items="['ディレクトリ1', 'ディレクトリ2', 'ディレクトリ3']" label="分類"></v-select> </v-col> <v-col cols="12" sm="6"> <v-autocomplete :items="['経理', 'プラットフォーム', 'プラットフォーム2', '人事']" label="組織" multiple ></v-autocomplete> </v-col> <v-col cols="12" sm="6"> <v-text-field label="メモ"></v-text-field> </v-col> </v-row> </v-container> </v-card-text> <v-card-actions> <v-spacer></v-spacer> <v-btn color="blue darken-1" text @click="dialog.dialog = false">Close</v-btn> <v-btn color="blue darken-1" text @click="dialog.dialog = false">Save</v-btn> </v-card-actions> </v-card> </v-dialog> </template> <script> export default { props: ["dialog"], }; </script>
- 子部分説明
v-model="dialog.dialog" で表示非表示を切り替え
props: ["dialog"] で親のデーターを受け取る
@click で表示非表示を切り替え完成図
- 投稿日:2020-10-09T00:33:12+09:00
VueでURLをフォームに入力してリスト表示したもののリンクを有効にしたい!!
こんばんは!
今日は、個人的に面白いことを学んだので、備忘録も兼ねて、まとめてみます!
まだまだ初心者の身なので、本当に、個人的に面白いことですよ!で、その面白いことっていうのが、タイトルにあるように、
「URLをフォームに入力してリスト表示したものを、クリックしたら、ちゃんとそのURLのページ(サイト)に遷移させたい!!っていう時のやり方」
です!※Vue CLIを利用しています。
完成形
まず、実装完了した完成形からお見せします。
以下の画像のように、下線付きでURLが表示されるようにします!
上部の入力フォームからURL等入力して、直下にリスト表示するという仕様です。デザインの関係でテーブルになってますが、リストでも同じです。URLに下線が入っていて、検索できるようになっていますね。
実装方法
それでは、実装方法を記述していきます。
実装にあたって、以下の投稿を参考にしました!
v-bindでaタグの属性値を動的に表現する。 ❏Vue.js❏ディレクティブの中でも、引数を取ることができるv-bindを利用します。
Vue.js公式テンプレート構文通常の場合
HTML部分では、
<a v-bind:href="url"> ... </a>のように、記述します。
hrefという引数を取っています。
この引数hrefに、urlの値を渡します。
urlの値を渡すことで、リンクを有効にすることができるという仕組みです。
いつもの、HTMLでURLを渡す時と同じですね。<a href="https://google.com">Google</a>aタグのhrefにURLを記述し渡すことで、リンクが有効になりますよね。
それと同じことをVueでやっているのです。
(v-bindでは、省略記法で、:hrefで表記可能です。)次に、Vue部分では、
Vue.jsnew Vue({ el: "#app", data: { url: "https://google.com" } })のように記述すれば、URLがクリックしたら、反応するようになります。
ユーザがフォームに入力したURLの場合は??
今回、私が実装したいのは、上で例示したような書き方では実装できませんでした。
ユーザによる入力なので、ユーザによって使用するURLも異なります。
そんな時、どうするのか...
まず、Vue部分は、一部省略していますが、以下になります。
ここでは、url関連部分がどうなっているのかだけ注目して頂いたら良いかなと思います。Vue.jsexport default { // 省略 data() { return { name: '', area: '', progress: '', url: '' // ここ注目! } }, methods: { onclick() { this.$store.commit('addCompanies', { company: { name: this.name, area: this.area, progress: this.progress, url: this.url // ここ注目! }, }) this.name = ''; this.area = ''; this.progress = ''; this.url = ''; // ここ注目! }, // 省略 }一般的な、フォーム入力からリストに追加し、表示するための処理ですね。
そして、肝心なHTML部分が以下になります。<a :href="company.url" target="_blank" rel="noopener noreferrer"> {{ company.url }} </a>aタグで囲われた、Mustache構文(二重中括弧)で記述されたデータバインディング部分に注目して下さい。
データバインディングは、プロパティの値を展開する際に行いますよね。
ユーザが入力したURLを、urlプロパティを展開することで、プロパティの中身を取り出します。
だから、リストにテキストとして、表示されるようになるのです。このURLリンクを有効にするために、周りのaタグがあるのです。
それでは、aタグ部分に注目してみて下さい。
最初に例示したように、v-bind:hrefが省略記法で書かれているのがわかります。
hrefは、引数でしたね。
今回は、この引数hrefに、ユーザ任意のURLの値を渡す必要があります。その方法は、
Mustache構文で、URLをテキスト展開するために利用した、company.urlプロパティを引数hrefに渡すのです。これで、ユーザが入力した任意のURLでリンクが有効になります。
データバインディングにおいて、動的に表示を変化させる時と原理は同じ。
今回の例で言うと、Mustache構文内のcompany.urlプロパティの値が変更されれば、表示される値も変わりますよね。URLのリンクの有効化でも、
company.urlプロパティが変更されると、hrefに渡すURLの値が変わり、遷移させるURLも変える必要がありますよね。ユーザが値を入力し、submitすることで、nullになっていたプロパティにユーザが入力した値が渡され、そこで、プロパティが変更されます。
これで、任意のURLもリンクを有効にすることが無事、できました!
めでたし、めでたし!長くなりましたが、ここまで読んでくださり、ありがとうございました。
何かあれば、コメントでお願い致します。参考資料