20220127のvue.jsに関する記事は6件です。

Vuetifyでローディング実装

はじめに 何か処理を実行しているとき、ローディング画面を実装したい場合があると思います。 Vuetifyではプロパティやコンポーネントでローディングを簡単に実装できます。今回はその実装方法を簡単にまとめました。 詳しく知りたい方は公式サイトで確認してください。 また、コピペでぱっと確認したい方は最後の方に機能をまとめたサンプルコードを載せているのでそちらをコピペしてください。 環境 vue 2.6.14 vuetify 2.6.2 npm: 7.21.1 node: 14.17.5 vuetifyのインストール 以下のコードでVuetifyをインストールできます。 vue add vuetify npm run serveで起動し、下の画面が出てきたら準備は完了です。 詳しい方法は以下のリンクで説明されています。 ローディング画面実装 今回ご紹介するのは4つの方法になります。 Vuetifyコンポーネントのローディング 円グラフを用いたローディング画面 棒グラフを用いたローディング画面 Dialogとの組み合わせ また、Vuetifyのインストールを無事終えたら、src/components/HelloWorld.vueが作成されてると思いますが、今回はその中身を変更するような形で実装していきます。 Vuetifyのコンポーネントのローディング Vueityfで用意されているv-cardやv-data-tableなどには標準機能としてローディングが実装されています。 loadingのオプションを設定することで表示が可能になります。 また、自分が調べたところloadingプロパティが利用できるコンポーネントは以下のようになるみたいです。(調べ損ねがあるかもしれません。) v-card v-data-table v-btn v-input v-overflow-btn v-switch src/components/HelloWorld.vue 今回はisLoadingでローディングの有無を操作しています。 <template> <div class="mx-auto mt-3 mb-6 text-center" style="width:600px;"> <v-btn class="my-2" color="primary" @click="isLoading=!isLoading" >Toggle Loading</v-btn> <v-card :loading=isLoading height="100px" class="mx-auto text-center " > <v-card-title> Card Loading </v-card-title></v-card> <v-data-table :loading=isLoading :headers="headers" :items="items" class="mx-auto my-2 elevation-3 " ></v-data-table> </div> </template> <script> export default { name: 'HelloWorld', data () { return { isLoading:true, } }, } </script> 結果 成功するとと以下のようなローディング画面が表示できます! 円グラフを用いたローディング画面 Vueitfyのコンポーネントにv-progress-circularという円グラフで状況を伝えるコンポーネントがあります。これを用いることで簡単にローディングを実装できます。 v-progress-circularのindeterminateプロパティを用いることで円グラフがクルクル回転するローディングを実装できます。 また、valueに値を設定すると円グラフのパーセント表示が可能になります。 v-progress-circularにはこれ以外にも様々な機能がありますので、詳しく知りたい方は以下のリンクで確認してください。 src/compnents/HelloWorld.vue <template> <div class="mx-auto mt-3 mb-6 text-center" style="width:600px;"> <v-btn class="my-2" color="primary" @click="isLoading=!isLoading" >Toggle Loading</v-btn> <v-card> <v-card-title>v-progress-circular </v-card-title> <v-progress-circular :indeterminate="isLoading" :size="100" color="primary" class="my-2" ></v-progress-circular> </v-card> <v-card> <v-card-title>v-progress-circular(%表示) </v-card-title> <v-progress-circular :size="100" :value="value" width="15" color="red" class="my-2" > {{ value }}% </v-progress-circular> </v-card> </div> </template> <script> export default { name: 'HelloWorld', data () { return { isLoading:true, value: 60, } }, mounted(){ this.interval = setInterval(() => { this.createIncrease() }, 100) }, methods:{ createIncrease(){ if(this.value <= 100) this.value++; else this.value = 0; } } } </script> 結果 棒グラフを用いたローディング画面 棒グラフでのローディング画面の表示はv-progress-linearのコンポーネントを使用します。 先ほど説明したv-progress-circularと使い方はほぼ同じです。 indeterminateでローディングを実装でき、valueでパーセント表示が可能になります。 v-progress-linearにはこれ以外にも様々な機能がありますので、詳しく知りたい方は以下のリンクで確認してください。 src/componetnts/HelloWorld.vue <template> <div class="mx-auto mt-3 mb-6 text-center" style="width:600px;"> <v-btn class="my-2" color="primary" @click="isLoading=!isLoading" >Toggle Loading</v-btn> <v-card> <v-card-title>v-progress-linear </v-card-title> <v-progress-linear :indeterminate="isLoading" color="primary" class="my-2" ></v-progress-linear> </v-card> <v-card> <v-card-title>v-progress-linear(%表示) </v-card-title> <v-progress-linear :value="value" height="20" color="red" class="mt-2" > {{ value }}% </v-progress-linear> </v-card> </div> </template> <script> export default { name: 'HelloWorld', data () { return { isLoading:true, value: 60, } }, mounted(){ this.interval = setInterval(() => { this.createIncrease() }, 100) }, methods:{ createIncrease(){ if(this.value <= 100) this.value++; else this.value = 0; } } } </script> 結果 Dialogとの組み合わせ ここでは自分が実際に使用しているダイアログとの組み合わせを紹介します。ダイアログを使用することでLoading中に画面を触らせないような実装が可能になります。 今回はv-dialogのv-modelでローディング表示の有無を操作しています。 円グラフ v-dialogでv-progress-circleを囲むことでローディングを実装できます。v-dialogのpersistentプロパティを使用することで処理中にユーザーに操作させないようにできます。 ただ、処理中にエラーが起きた場合にはpersistentがあるとユーザー画面でローディングが一生回ることになるのでキャンセルボタンをつけることをお勧めします。 src/componetnts/HelloWorld.vue <template> <div class="mx-auto mt-3 text-center" style="width:600px;"> <v-btn class="my-2" @click="dialog=true" >Dialog Circle Loading</v-btn> <v-dialog v-model="dialog" persistent width="300" > <v-card height="190" class="text-center"> <v-progress-circular :indeterminate="isLoading" :size="100" color="primary" class="mt-4 " >Loading... </v-progress-circular> <v-card-actions> <v-btn class="ml-auto my-2" color="primary" @click="dialog=false">close</v-btn> </v-card-actions> </v-card> </v-dialog> </div> </template> <script> export default { name: 'HelloWorld', data () { return { isLoading:true, dialog:false, } }, } </script> 結果 棒グラフ 棒グラフでの実装も円グラフと同様にして実装できます。 src/componetnts/HelloWorld.vue <template> <div class="mx-auto mt-3 text-center" style="width:600px;"> <v-btn class="my-2" @click="dialog=true" >Dialog Linear Loading</v-btn> <v-dialog v-model="dialog" persistent width="300" > <v-card height="110" class="text-center pa-2"> <v-progress-linear indeterminate height="25" color="primary" >Loading... </v-progress-linear> <v-card-actions> <v-btn class="ml-auto my-1" color="primary" @click="dialog=false">close</v-btn> </v-card-actions> </v-card> </v-dialog> </div> </template> <script> export default { name: 'HelloWorld', data () { return { isLoading:true, dialog:false } }, } </script> 結果 サンプルコード(まとめ) 今まで紹介したローディングをまとめたものです。ぱっと確認したい方は以下のコードをコピペで大丈夫です。 <template> <div class="mx-auto mt-3 mb-6 text-center" style="width:600px;"> <v-btn class="my-2" color="primary" @click="isLoading=!isLoading" >Toggle Loading</v-btn> <br> <v-btn class="my-2" color="pink" @click="dialogCircle=true" >Dialog Linear Loading</v-btn> <br> <v-btn class="my-2" color="red" @click="dialogLinear=true" >Dialog Linear Loading</v-btn> <v-card :loading=isLoading height="100px" class="mx-auto text-center " > <v-card-title> Card Loading </v-card-title></v-card> <v-data-table :loading=isLoading :headers="headers" :items="items" class="mx-auto my-2 elevation-3 " ></v-data-table> <br> <v-card> <v-card-title>v-progress-circular </v-card-title> <v-progress-circular :indeterminate="isLoading" :size="100" color="primary" class="my-2" ></v-progress-circular> </v-card> <v-card> <v-card-title>v-progress-circular(%表示) </v-card-title> <v-progress-circular :size="100" :value="value" width="15" color="red" class="my-2" > {{ value }}% </v-progress-circular> </v-card> <v-card> <v-card-title>v-progress-linear </v-card-title> <v-progress-linear :indeterminate="isLoading" color="primary" class="my-2" ></v-progress-linear> </v-card> <v-card> <v-card-title>v-progress-linear(%表示) </v-card-title> <v-progress-linear :value="value" height="20" color="red" class="mt-2" > {{ value }}% </v-progress-linear> </v-card> <v-dialog v-model="dialogLinear" persistent width="300" > <v-card height="110" class="text-center pa-2"> <v-progress-linear indeterminate height="25" color="primary" >Loading... </v-progress-linear> <v-card-actions> <v-btn class="ml-auto my-1" color="primary" @click="dialogLinear=false">close</v-btn> </v-card-actions> </v-card> </v-dialog> <v-dialog v-model="dialogCircle" persistent width="300" > <v-card height="190" class="text-center"> <v-progress-circular indeterminate :size="100" color="primary" class="mt-4 " >Loading... </v-progress-circular> <v-card-actions> <v-btn class="ml-auto my-2" color="primary" @click="dialogCircle=false">close</v-btn> </v-card-actions> </v-card> </v-dialog> </div> </template> <script> export default { name: 'HelloWorld', data () { return { isLoading:true, dialogCircle:false, dialogLinear:false, value: 60, headers: [ { text: '名前', value: 'name'}, { text: '体重', value: 'fat'}, ], items: [ {name: 'yoko', fat: 6.0}, {name: 'tae', fat: 9.0}, ], } }, mounted(){ this.interval = setInterval(() => { this.createIncrease() }, 100) }, methods:{ createIncrease(){ if(this.value <= 100) this.value++; else this.value = 0; } } } </script> まとめ 今回はVueitfyでのローディングの実装方法を簡単にまとめました。ほかにもこんなローディング実装があるよ!という方はコメントしていただけるとありがたいです。またご指摘等もぜひコメントしただけると幸いです。 参考 Vuetify公式サイト
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue3】Element-Plusのススメ

初めましての方は初めまして、けこです。 今回はVue3対応のUIライブラリを探していたElementPlusというライブラリが良かったので、どこが良かったかと使い方について簡単に紹介していきます。 Vue3におけるUIライブラリの選択肢狭い問題 皆さん、Vue3使ってますか? Vueは良いですよね。コンポーネント志向なのでコードが探しやすく、ミニマムな実装から大規模な実装まで対応できる。しかもライブラリが豊富。UIライブラリだって…… 「あれ……、Vue3.0に対応したUIライブラリ少なくない?」 「VuetifyまだVue3.0対応してないじゃん!」 「lonic良さげだけどコマンド入れるの面倒~!」 Vue2にするか?いや、Vue3使ってみたいな……よし、色々試してみよう。ということで、 こちらの記事を参考に探してElement-Plusに落ち着きました。 決め手としては、 1. 導入が用意である 2. 選択できるコンポーネントが豊富である 3. MITライセンスである 4. マテリアルデザインを採用している これらの要素が良かったですね。公式サイトもシンプルで分かりやすいです。 ↓ ※公式、英語 Vuetify早くVue3正式対応してくれないかな~~~ Element-Plus導入 導入はよくあるパターン、私はvue-cliを使っているのでそれで入れました。 # Choose a package manager you like. # NPM $ npm install element-plus --save # Yarn $ yarn add element-plus # pnpm $ pnpm install element-plus 下記ページから引用 https://element-plus.org/en-US/guide/installation.html#using-package-manager Element-Plusの使い方 例えば、装飾済のボタンを出したい場合はという名前で文字を囲むだけで出せます。 <template> <el-button>Default</el-button> </template> 色を変えた場合、丸みをつけた場合、押せないようにしたい場合 <template> <el-button type="primary">Change color</el-button> <el-button round>Round</el-button> <el-button disabled>Disable</el-button> </template> スタイルのいじり方にはインラインとCSSの2種類の選択肢があります。 <template> <el-button :style="{backgroundColor: 'red'; color: 'white'}">Inline style</el-button> <el-button class="bg-blue">CSS</el-button> <template> <style> .bg-blue { background-color: blue; color: white; } </style> ボタン全体に適用されているスタイルをいじることもできます。 <template> <el-button>.コンポーネント名のスタイル指定で</el-button> <el-button>同じコンポーネント全体のスタイルを指定できます</el-button> </template> <style> .el-button { color: yellow; background-color: purple; } </style> 無限スクロールリスト、タイムピッカー、テーブル、カルーセルといったあると嬉しいコンポーネントも用意されています。 使い方は各々のコンポーネントのページを見て、メソッドが用意されている場合はそれを使って、用意されていない場合はCSSや@click等で実装しましょう。 ↓コンポーネント一覧 終わりに ここまで、Vue向けUIライブラリであるElement-Plusについての簡単な紹介をしてきました。 皆様のVue生活に彩りを加えることができれば幸いです。 好評ならElement-Plusでこんなもの作れるよーという内容の記事でも書いてみようかなと思います。 オススメのVueライブラリ等ありましたらコメントで教えて下さい!募集しています~! それでは、良きVueライフを!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsとVue.js3のSPAアプリにDeepL apiを導入する

ポートフォリオ作りの過程でRails×Vue.js3のSPAアプリにDeepL apiを導入したので過程を初学者視点で紹介します。 開発環境にはdockerを使用しています。 #version Ruby 3.0.2 Rails 6.0.4 Vue.js3 #開発環境 Docker docker-compose APIで実現したいこと 上記の画像の「AI翻訳の結果を表示する」ボタンを押すと上部に表示された日本語文を英訳して表示する。 DeepL apiの登録 こちらから登録します。 50,000文字/1ヶ月の制約はありますが無料プランもあります。 登録すると自身のアカウントに認証キーが表示されるのでそれをコピーしておきます。 Rails側の実装 gem httpclient 上記gemをインストールします。DeepL apiは"https://api-free.deepl.com/v2/translate" というurlにget(もしくはpost)リクエストを認証キー、翻訳したいテキスト、変換結果の言語の3点をパラメーターとして含んだ上で送信する必要があります。httpclientはrailsのcontrollerからそのリクエストを送信するための記述を提供してくれるgemになります。 $ docker-compose build --no-cache 今回はdockerを使用しているので上記コマンドでgemをインストールします。 $ rails g controller api/translations apiを叩くためのコントローラーを用意します。既存のコントローラーを使用しても問題ありません。 $ EDITOR="vi" bin/rails credentials:edit deepl_api: api_key: DeepL apiの認証キーを貼り付け 認証キーを直打ちしなくて済むようにcredentials.ymlに秘匿します。 translations_controller.rb class Api::TranslationsController < ApplicationController require 'httpclient' #httpclientを使用できるようにします def translate @question = Question.find(params[:id]) api_key = Rails.application.credentials.deepl[:api_key] uri = "https://api-free.deepl.com/v2/translate" client = HTTPClient.new params = { auth_key: api_key, text: @question.content, target_lang: "EN" } @response = client.get(uri, query: params) render json: @response.body end end 前述の「実現したいこと」の画像に表示されている翻訳したい文章はQuestio モデルのcontentカラムに保存されているものになるのでparamsのtextには@question.contentを代入しています。 routes.rb namespace :api, format: 'json' do get '/translate/:id', to: 'translations#translate' end questionモデルのidをパラメーターとして送信するため/:idを付け加えていますが'/translate'の部分は自由に書き換えてください(例えば'/aaa/:id'でも'translations#translate'によってapi/translations_controllerのtranslateアクションを実行してくれます)。 Vue側の実装 <template> <button @click="translateWithDeepL"> AI翻訳の結果を確認する </button> <h1>翻訳結果: {{result}}</h1> </template> <script> methods: { translateWithDeepL: function() { const question_id = this.question.id axios.get('/api/translate/'+ question_id) .then(response => { this.result = response.data.translations[0].text }) } } </script> axios.get('/api/translate/' + question_id)でroute.rbに設定したget '/translate/:id'にアクセスし、translations_controllerのtranslateアクションを実行という流れになります。 具体的には仮に翻訳したいテキストが[hello]で翻訳結果の言語を日本語に設定すると https://api-free.deepl.com/v2/translate?auth_key=認証キー&text=hello&target_lang=JA というURLにgetリクエストが送信され、 { "translations": [{ "detected_source_language":"JA", "text":"こんにちは" }] } というresponseがjson形式でかえってきます。 このレスポンスのtextの部分だけ表示したいので response.data.translations[0].text という形でフロントエンド上では受け取っているわけです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3.0+VeeValidate4.0で関数内の任意の場所でバリデーション実行する

やることはタイトルの通りなんですが、公式のドキュメントは薄めだし、意外とググっても国内海外ともに情報が出てこなかったので、忘れないように残しておきます。 やりたいこと submit時ではなく、ボタンのクリック時とかにFormレベルのバリデーションを噛ませたい こんな感じで export default defineComponent({ setup() { }, methods: { onClick() { // ここでバリデーションしてエラーしてたらreturnみたいなこと } } }) どうやる? 他にもやり方はあるかもしれないですが、一旦こうやればやれた、というのを書いておきます。 template Formのv-slotにvalidateを設定して、clickイベントで呼ぶ関数の引数に渡してやる <template> <Form v-slot="{ validate }" :validation-schema="schema"> <!-- Fieldとかは必要なものを --> <button type="button" @click="onClick(validate)"> </Form> </template> script <script> import { Form, defineComponent } from 'vee-validate' export default defineComponent({ setup() { const schema = { // 省略 } return { Form, schema, } }, methods: { onClick(validate: any) { // ここでvalidation実行 validate().then((result: any) => { if (result.valid) { // バリデーション突破 } else { // バリデーション失敗 } } } } }) </script>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【全プログラミング共通】Vueの学習中に出たエラーの原因がしょうもなかった

記事はこちらに移管しましたmm
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javascript スプレッド演算子メモ

概要 スプレッド演算子がなにかわからない // このようにも書ける1 ...mapGetters([ 'getGenreById' ]) この...の書き方わからなかった. 結果 javascript のスプレッド演算子の書き方であった. Vue.js に依存する書き方ではない. 参考: https://www.it-swarm-ja.tech/ja/javascript/%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E6%A7%8B%E6%96%87%EF%BC%88%EF%BC%89%E3%81%AFmapgetters%E3%81%A7%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E6%A9%9F%E8%83%BD%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/836866119/ mapGettersとmapActionsは、基本的にvuexが提供するヘルパーであり、メソッド名としてキーを持ち、定義が定義されたメソッドとして値を持つオブジェクトを返します。このオブジェクトを...(オブジェクトスプレッド演算子)と組み合わせると、それを計算オブジェクトまたはメソッドオブジェクトの個々の関数にそれぞれ広げます。 実装例 moview_list.vue <script> import axios from "axios"; import {mapState, mapGetters} from 'vuex'; export default { created() { this.$store.dispatch('set_movie_list') }, computed: { saleMovies(){ return this.$store.getters.saleMovies; }, // このようにも書ける1 // ...mapGetters([ // 'getGenreById' // ]) // このようにも書ける2 getGenreById() { return this.$store.getters.getGenreById; }, }, } </script>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む