- 投稿日:2020-11-21T23:39:07+09:00
【Vue.js】カウンター作成記録
はじめに
vueの練習したいけど何を作ればいいのか。
そうだ、カウンターを作ろう。とりあえず作った
コード
counter.html<template> <div> <b-button v-on:click="countUp" variant="success">カウントアップ</b-button> <b-button v-on:click="countDown" variant="primary">カウントダウン</b-button> <b-button v-on:click="countClear" variant="danger">カウントクリア</b-button> <h1>{{displayCount}}</h1> <div v-if="displayCount > 10"> {{successCount()}} </div> </div> </template>counter.js<script> export default { data() { return { displayCount: 0 }; }, methods: { countUp() { this.displayCount++; }, countDown() { this.displayCount--; }, countClear() { this.displayCount = 0; }, successCount() { alert('great!!') } } }; </script>さいごに
マウスをカチカチするだけでも楽しくなっちゃう自分としては
かなり良い暇つぶしグッズを作ってしまった。
vue.jsで作った意味があるのかわからない感じだけど、記法とかをおぼえる練習としては良かったかな。
ここまで読んでくれた方ありがとうございました!おまけ
下記のリンクで遊べます。
ちなみにCodeSandboxはかなり優秀な開発環境ですので是非使ってみてほしいです。
https://codesandbox.io/s/counter-practice-xlquf
- 投稿日:2020-11-21T21:52:09+09:00
Vuetifyの初期画面を表示するまで
マテリアルデザインフレームワークvuetifyの
半日ぐらいかかったので未来の自分へメモWindows版PyCharmでのセットアップ
- Node.jsインストール
Windows 10へNode.jsをインストールする - Qiita
そのままインストールする
- PyCharmのVue.jsプラグインのインストール
- New Project Locationのプロジェクト名を任意のものに変更して
Create
ボタン実行
- Terminal
ターミナルウィンドウから
npm install --save-dev @vue/cli
実行ターミナルウィンドウから
.\node_modules\.bin\vue add vuetify
実行
WARN There are uncommitted changes in the current repository, it\'s recommended to commit or stash them first.
? Still proceed? (y/N)y ←yでEnterDefault (recommended)を選択してEnter
Shift+F10
実行してブラウザでアクセスLinux上でのセットアップ
$ npm init --yes $ npm install --save-dev @vue/cli $ ./node_modules/.bin/vue create --default . ? Generate project in current directory? (Y/n)Y ←YでEnter $ ./node_modules/.bin/vue add vuetify WARN There are uncommitted changes in the current repository, it\'s recommended to commit or stash them first. ? Still proceed? (y/N)y ←yでEnter ? Default (recommended) ←そのままEnter $ cat vue.config.js module.exports = { "transpileDependencies": [ "vuetify" ], devServer: { port: 8080, disableHostCheck: true, }, } $ npm run serve $ npm run buildFlaskとの結合は以下参照
Vue.js + FlaskでWebアプリケーション制作 - herokuにデプロイするまで - - Qiita
画面変更は以下参照
- 投稿日:2020-11-21T19:37:36+09:00
vue-routerの戻るボタンを押してback()した時は処理を変えたい
目的
<keep-alive />
やvuexを使った場合、ブラウザのメモリ上にデータが残る
これらの機能を使った一覧画面の場合、
- 過去データをそのまま表示するか?
- サーバーに再検索するか?
の判断が必要になるケースが稀にある。
例えば、戻るボタン、backで画面遷移したい場合は過去の検索結果のデータを表示し、
メニュー等、他からの画面遷移なら再検索させたい場合がこれにあたる案
vuer-router経由で読み込むPage Componetに対して、
共通でextendsするcomponentとして下記を定義するexport default { name: 'base-page', beforeRouteLeave(to, from, next) { if (this.backing) to.params.isBack = true this.backing = false next() }, data() { return { backing: false, } }, computed: { isBack() { return this.$route && this.$route.params.isBack }, }, methods: { backPage() { this.backing = true this.$router.back() }, }, }一覧ページなどの戻るボタンで戻るページでは下記のように処理分岐する
<script> import BasePage from '../base-page.js' export default { extends: BasePage, beforeRouteEnter: function () { if (this.isBack) { // 戻るボタン経由の場合 } else { // それ以外の場合 } }, } </script>戻るボタンでは、
backPage
メソッドを呼び出す。
もしくは、ブラウザのback eventを監視し、backPage
メソッドと同様の処理を行わせる
- 投稿日:2020-11-21T19:26:40+09:00
vue.js 検索窓
1まずは、検索窓の入力をvalueにして、searchにいれる
Searchi.vue 検索窓見た目<template> <!-- 検索窓 親app.vue--> <v-text-field :value="$store.state.search" ●追加 @input="$store.commit('setSearch',$event)" ●追加 @focus="searchClosed = false" @blur="searchClosed = true" class="expanding-search mt-1" :class="{ 'closed' : searchClosed && !$store.state.search}" placeholder="Search" prepend-inner-icon="mdi-magnify" filled dense clearable ></v-text-field> </template>store.js データが保管されるとろexport default new Vuex.Store({ state: { search:null, ●追加 .....いろいろ... mutations: { setSearch(state,value){ ●以下追加 state.search = value console.log('value',value) },イメージ
$eventは特殊らしい
ステートの値が、バリューとミューテーションでsetSearchに加工された
2,次は、検索窓に入力したものと、タスクを一致させて呼び出す
- 投稿日:2020-11-21T19:26:40+09:00
vue.js vuetify使って検索窓
1まずは、検索窓の入力をvalueにして、searchにいれる
Searchi.vue検索窓見た目 <template> <!-- 検索窓 親app.vue--> <v-text-field :value="$store.state.search" ●追加 @input="$store.commit('setSearch',$event)" ●追加 @focus="searchClosed = false" @blur="searchClosed = true" class="expanding-search mt-1" :class="{ 'closed' : searchClosed && !$store.state.search}" placeholder="Search" prepend-inner-icon="mdi-magnify" filled dense clearable ></v-text-field> </template>store.jsデータが保管されるところ export default new Vuex.Store({ state: { search:null, ●追加 .....いろいろ... mutations: { setSearch(state,value){ ●以下追加 state.search = value console.log('value',value) },イメージ
$eventは特殊らしい
ステートの値が、バリューとミューテーションでsetSearchに加工された
2,次は、検索窓に入力したものと、タスクを一致させて呼び出す
store.jsexport default new Vuex.Store({ state: { search:null, tasks:[ ●入ってるデータ {id:1, title:'Wake up', done:false, dueDate:'2020-10-16' }, {id:2, title:'get banana', done:false, dueDate:'2020-10-16' }, {id:3, title:'eat banana', done:false, dueDate:null }, ], getters:{ ●追加一致してるものを呼び出す tasksFiltered(state){ ●作成 if(!state.search){ ●stateが入っているなら return state.tasks ●タスクのデータ全部返す } return state.tasks ●配列になってるタスクの中から .filter(task => ●一致するものをループで呼び出して task.title ●タスクタイトルの .toLowerCase() ●大文字小文字 .includes(state.search.toLowerCase()) ●検索窓に含んでるやつ ) } }ListTask.vueタスクの見た目 親のコンポーネントではループ処理をしているのでゲッターで一致してるやつを呼び出すようにする <task v-for="task in $store.getters.tasksFiltered" ●ゲッターを適応 :key="task.id" :task="task" ></task>これで、データの中身を検索窓から取り出せるようになった。
ムズい!!!
ので、図でまとめないとわからん!!
- 投稿日:2020-11-21T09:55:17+09:00
【Vue.js】Vue.jsとcssアニメーションで作るスライドショー
Vue.js
とCSS
を用いてスライドショーを実装するメモです。目的
実装
テンプレート
Imageslide.vue<template> <div> <transition-group tag="ul" class="images"> <li v-for="(image, index) in demoimages" v-show="currentImage == index + 1" :key="index" > <img :src="image.image" alt="" /> </li> </transition-group> </div> </template>画像を
v-for
でリストしてv-show
で表示を切り替えています。
v-show
はv-if
とは違い、DOMを消したり追加したりはせず、display:none
を付与して要素を非表示にします。そのため非表示の画像をもう一度表示する場合も、再度画像が読み込まれるわけではありません。スクリプト
Imageslide.vue<script> export default { data() { return { currentImage: 1, } }, computed: { demoimages() { return [ { image: '/images/1.jpg' }, { image: '/images/2.jpg' }, { image: '/images/3.jpg' }, ] }, }, watch: { currentImage() { this.autoSlide() }, }, mounted() { this.autoSlide() }, methods: { async autoSlide() { const wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms)) await wait(2000) if (this.currentImage > this.images.length - 1) { this.currentImage = 1 } else { this.currentImage++ } }, }, } </script>表示されている画像のインデックスを示す
currentImage
をウォッチしてautoSlide()
を実行しています。currentImageが画像のリストを超えた場合に初期化することで無限ループになります。スタイル
Imageslide.vue<style lang="scss" scoped> .images { width: 100%; height: 100%; padding: 0; margin: 0; position: relative; li { width: 100%; height: 100%; max-height: 627px; position: absolute; top: 0; left: 0; } } img { width: 100%; height: 100%; max-height: 627px; margin: auto; z-index: 2; } .v-enter-active, .v-leave-active { transition: opacity 0.5s; } .v-enter, .v-leave-to { opacity: 0; } </style>リストの親要素に
position:relative
を指定し、子要素にposition:absolute top:0 left:0
を指定することで同じ位置に画像を重ねることができます。
.v-enter-active,.v-leave-active,.v-enter,.v-leave-to
はtransition
によってVueから自動的に付与されるクラスです。まとめ
Vue.jsとCSSを使用したスライドショーの実装方法について簡単に説明してみました。私はこのように実装しましたが、おそらく別の方法もあるかと思います。いろいろ試してみてください!
- 投稿日:2020-11-21T09:52:24+09:00
v-bind:keyは並び替えるためのものじゃない
結論
v-bind:keyはそれぞれの要素に一意なキーを与えるだけ。並べ替えはしません。
並べ替えるなら関数使って新しく作りましょう。例
お恥ずかしいことに、下記のようにキーに数字を与えると自動で並べ替えられると思っていました。
<span v-for="num in [3, 2, 1]" :key="num"> {{ num }} </span> <!-- 期待したのは出力はこっち--> <!-- 1 2 3 --> <!-- 実際の出力は以下になる --> <!-- 3 2 1 -->具体的な並び替え方は以下が参考になりました。
Vue.jsのv-forでの並び順を指定したキーの値順にしたり、昇順、降順を切り替えたりするまとめ
keyは一意に定めるものでそれ単体で並び替えに使えるものではありません。並び替えるならcomputedプロパティなどを使って並び替えたデータを用意しましょう。
私のように変な勘違いを起こした方が路頭に迷わないためにここに残しておきます。