20210603のvue.jsに関する記事は4件です。

plunkerでvue その45

概要 plunkerでvueやってみた。 練習問題、やってみた。 三日、かかった。 練習問題 vuetifyとaxiosを使って、crudを実装せよ。 サンプルコード <!doctype html> <html> <head> <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"> <link rel="stylesheet" href="//unpkg.com/vuetify@1.5.18/dist/vuetify.min.css"> <link rel="stylesheet" href="//cdn.materialdesignicons.com/3.5.95/css/materialdesignicons.min.css"> <script src="//unpkg.com/vue/dist/vue.js"></script> <script src="//unpkg.com/vuetify@1.5.18/dist/vuetify.min.js"></script> <script src="//unpkg.com/axios/dist/axios.min.js"></script> <link rel="stylesheet" href="lib/style.css"> </head> <body> <v-app id="app"> <v-container> <v-row> <v-col cols="10"> <v-toolbar flat color="white"> <v-toolbar-title>My CRUD</v-toolbar-title> <v-divider class="mx-2" inset vertical ></v-divider> <v-spacer></v-spacer> <v-dialog v-model="dialog" max-width="500px"> <template v-slot:activator="{ on }"> <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn> </template> <v-card> <v-card-title> <span class="headline">{{ formTitle }}</span> </v-card-title> <v-card-text> <v-container grid-list-md> <v-layout wrap> <v-flex xs12 sm6 md4> <v-text-field v-model="editedItem.name" label="name"></v-text-field> </v-flex> <v-flex xs12 sm6 md4> <v-text-field v-model="editedItem.email" label="email"></v-text-field> </v-flex> </v-layout> </v-container> </v-card-text> <v-card-actions> <v-spacer></v-spacer> <v-btn color="blue darken-1" flat @click="close">Cancel</v-btn> <v-btn color="blue darken-1" flat @click="save">Save</v-btn> </v-card-actions> </v-card> </v-dialog> </v-toolbar> <v-data-table :headers="headers" :items="serverDatas"> <template slot="items" slot-scope="props"> <td class="text-xs-left">{{ props.item.id }}</td> <td class="text-xs-left">{{ props.item.name }}</td> <td class="text-xs-left">{{ props.item.email }}</td> <td class="justify-center layout px-0"> <v-btn small color="aqua" @click="editItem(props.item)"> edit </v-btn> <v-btn small color="error" @click="deleteItem(props.item)"> delete </v-btn> </td> </template> </v-data-table> </v-col> </v-row> </v-container> </v-app> <script src="lib/script.js"></script> </body> </html> new Vue({ el: "#app", data() { return { dialog: false, isCreate: true, editedItem: { id: 0, name: '', email: 0 }, headers: [{ text: 'ID', value: 'id' }, { text: '名前', value: 'name', }, { text: 'メルアド', value: 'email' }, { text:'修正/削除', value:'delete', sortable:false }], serverDatas:[], } }, computed: { formTitle() { return this.isCreate ? 'New Item' : 'Edit Item' } }, watch: { dialog(val) { val || this.close() } }, methods: { deleteItem(item) { const index = this.serverDatas.indexOf(item) confirm('削除しますか') && this.serverDatas.splice(index, 1) }, editItem(item) { this.isCreate = false this.editedItem = item this.dialog = true }, close() { this.dialog = false }, save() { if (!this.isCreate) { this.update() } else { this.create() } this.dialog = false }, update() { const index = this.serverDatas.indexOf(this.editedItem) this.serverDatas[index] = this.editedItem }, create() { this.serverDatas.push(this.editedItem) }, }, created() { axios.get('https://jsonplaceholder.typicode.com/users').then( res => { this.serverDatas = res.data }).catch(e => { alert(e) }).finally(()=>{ //alert("通信完了") }) } }) 成果物 以上。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vueでselectのコンポーネントを作成

rippleにはvuetifyのものを使っている。 時間があるときにrippleも作成したい。 ItemSelect.vue <template> <div class="w100" :style="{width: `${width}px`}"> <div class="bar"> <div class="text-box" @click.stop="openMenu" :style="indexChange"> <div class="placeholder" v-if="selectedItems.length==0"> <div style="margin-left: 5px;" :style="{color: color}">{{ placeholder }}</div> <div style="position:relative"><div :class="iconClass"></div></div> </div> <div class="flex-wrap" v-else><span class="chip" v-for="(selectedItem, i) in selectedItems" :key="i">{{selectedItem.text}}<span style="margin-left:5px;font-size:15px" @click.stop="clear(i)">×</span></span></div> </div> <div class="view" @click.stop=""> <form :class="menuClass"> <label class="item" v-ripple="ripple" v-for="(item, i) in items" :key="i" :for="item.name"><input type="checkbox" :value="item" v-model="selectedItems" :id="item.name"><label :for="item.name">{{item.text}}</label></label> <label class="item" v-ripple="ripple" @click="openMenu">決定</label> <label class="item" v-ripple="ripple" for="reset"><input type="reset" id="reset" value=""><label for="reset" @click="reset">リセット</label></label> </form> </div> </div> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ props:{ placeholder: String || null, width: Number || null, color: String || null, backgroundColor: String || null, ripple: String || null, }, model: { event: "change"//このコンポーネントのv-model用 }, data() { return { items: [ {name: 'JR', text:'JR'}, {name: 'Keio', text:'京王電鉄'}, {name: 'TokyoMetro', text:'東京メトロ'}, ], value: '', isSelect: false, menuClass: { 'active': false, 'menu': true }, iconClass:{ 'down-icon': true, 'rotate': false }, selectedItems: [] } }, computed:{ indexChange(){ return (this as any).menuClass.active ? {zIndex: 0, backgroundColor: this.backgroundColor} : {zIndex: 1,transitionDelay: '.5s', backgroundColor: this.backgroundColor}; }, }, watch:{ selectedItems(){ this.$emit('change', this.selectedItems); } }, methods:{ openMenu(){ const that = this; if (this.menuClass.active) { this.$root.$el.removeEventListener('click',that.menuActive); this.menuActive(); } else { this.menuClass.active = true; this.iconClass.rotate = true; this.$root.$el.addEventListener('click',that.menuActive,{once:true}); } }, menuActive(){ this.menuClass.active=false; this.iconClass.rotate=false; }, reset(){ this.selectedItems.length = 0; this.$emit('change', this.selectedItems); this.menuActive(); }, clear(index: number){ this.selectedItems.splice(index,1) } } }) </script> <style lang="scss" scoped> .bar { position:relative; min-width:200px; .text-box{ border:solid 1px rgba(0,0,0,.27); border-radius:5px; padding:5px; position:relative; z-index:1; cursor: pointer; min-height:34px; word-break: break-all; .flex-wrap{ display: flex; flex-wrap: wrap; } .chip{ margin:1px 3px; padding:1px 9px; background-color:black; border-radius:10px; font-size:12px } .placeholder{ color:black; display:flex; justify-content:space-between; } .down-icon{ border-radius: 0px 1px 2px 1px; position:absolute; top:0; bottom:0; margin:auto; right:10px; border-right:solid 3px #644a4a; border-bottom:solid 3px #644a4a; height:12px; width:12px; transform:rotateZ(45deg) translate(-4px); transition: all .5s; } .rotate{ transform:rotateZ(-135deg); transition: all .3s; } } .view { transform-style:preserve-3d; -moz-perspective:100%; perspective:100%; -o-perspective:100%; -ms-perspective:100%; position:absolute; width: 100%; top:0px; .menu{ visibility: hidden; opacity: 0; width:100%; transform: translateY(-25px) rotateX(30deg); transition: all .2s; transition-delay: .1s; transition-timing-function: ease-in; border-radius:5px; box-shadow: 0 0 0 1px rgb(208, 208, 208); label{ display: inline-block; width: 100%; } input[type="checkbox"]{ display: none; } input[type="reset"]{ display: none; } input[type="checkbox"]+label{ display: none; cursor: pointer; display: inline-block; position: relative; padding-left: 25px; padding-right: 25px; } input[type="checkbox"]+label::before{ content: ""; position: absolute; display: block; box-sizing: border-box; width: 12px; height: 12px; margin: auto; left: 0; top: 0; bottom: 0; border-color: #585753; /* 枠の色変更 お好きな色を */ background-color: #FFF; /* 背景の色変更 お好きな色を */ border-radius: 2px; box-shadow: 0 0 1px 1px #3d0076 } input:checked ~ label::before{ background-color: rgb(0, 55, 253); box-shadow: 0 0 1px 1px #004cc5; } input[type="checkbox"]:checked+label::after{ content: ""; position: absolute; display: block; box-sizing: border-box; width: 8px; height: 4px; top: 0; bottom: 0; margin: auto; left: 0px; transform: translate(2px,-1px) rotate(-45deg); border-bottom: 2px solid; border-left: 2px solid; border-color: whitesmoke; /* チェックの色変更 お好きな色を */ } .item{ padding: 9px 15px; color: #FAF5EB; cursor: pointer; transition: all .3s; list-style: none; background-color: indigo; } .item:first-child{ border-radius:5px 5px 0 0 } .item:last-child{ border-radius:0 0 5px 5px } .item:hover{ background-color: rgb(149, 65, 209); transition: all .3s; } .item:active{ background-color: rgb(102, 0, 175); transition: all .3s; } } .active{ visibility: visible; opacity: 1; transform: translateY(0) rotateX(0deg); transition: all .2s; transition-delay: .1s; transition-timing-function: ease-out; z-index:1; } } } .w100{ width:100%; } </style> home.vue <div> <item-select v-model="selectItems" placeholder="鉄道会社名で絞り込む" background-color="white" ripple="true"></item-select> </div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Slidev の基本操作確認

Prologue Vite, Vue 3, Windi CSS を使っている Slidev を触ってみました。 Vue と Vite の部分を詳しく掘り下げたかったのですが、今回はデフォルトのスライドを触りながら基本的な機能を見るのみになります。 公式: https://sli.dev/ 環境 macOS: v10.15.6 node.js: v16.2.0 terminal: iTerm エディタ: VS Code パッケージマネージャ: yarn Slidev とは マークダウンで書ける スライドを単一のファイルに整理できる テーマの拡張ができる コードスニペットを使える(Prism, Shikiをサポート) Vite, Vue 3, Windi CSS を利用しているためスライドに高速で反映できる プロジェクトの作成 **@m** slidev_sample % yarn create slidev yarn create v1.22.4 [1/4] ? Resolving packages... [2/4] ? Fetching packages... error create-slidev@0.15.0: The engine "node" is incompatible with this module. Expected version ">=14.0.0". Got "12.18.2" error Found incompatible module. info Visit https://yarnpkg.com/en/docs/cli/create for documentation about this command. **@m** slidev_sample % node -v v12.18.2 node のバージョンは >=14.0.0 ということでエラーが出たため、 node の最新化を行いました。 nodebrew install-binary latest nodebrew ls-remote nodebrew use v16.2.0 node -v v16.2.0 改めて作成。 yarn create slidev yarn create v1.22.4 [1/4] ? Resolving packages... [2/4] ? Fetching packages... [3/4] ? Linking dependencies... [4/4] ? Building fresh packages... success Installed "create-slidev@0.15.0" with binaries: - create-slidev ●■▲ Slidev Creator v0.15.0 ✔ Project name: … sample-project Scaffolding project in sample-project ... Done. ✔ Install and start it now? … yes ✔ Choose the agent › yarn yarn install v1.22.4 info No lockfile found. [1/4] ? Resolving packages... [2/4] ? Fetching packages... warning theme-vitesse@0.1.11: The engine "vscode" appears to be invalid. [3/4] ? Linking dependencies... warning "@slidev/cli > vite-plugin-icons@0.5.1" has unmet peer dependency "vue-template-compiler@^2.6.12". [4/4] ? Building fresh packages... success Saved lockfile. ✨ Done in 26.16s. yarn run v1.22.4 $ slidev --open ●■▲ Slidev v0.15.0 theme @slidev/theme-seriph entry /Users/**/mi**/slidev/sample-project/slides.md slide show > http://localhost:3030/ presenter mode > http://localhost:3030/presenter remote control > pass --remote to enable [@vue/compiler-sfc] <script setup> is still an experimental proposal. Follow its status at https://github.com/vuejs/rfcs/pull/227. [@vue/compiler-sfc] When using experimental features, it is recommended to pin your vue dependencies to exact versions to avoid breakage. 途中プロジェクト名を入力する欄があります。(デフォルトの設定を書き換える形) 今回は sample-project として進めていきました。 インストールが終わると、初期画面が自動で立ち上がります。 アドレス: http://localhost:3030/1 初期フォルダ構成: スライドの作成 参考: https://sli.dev/guide/syntax.html プロジェクトルート下にある slides.md を読み取ってスライドに変換していきます。 単一のマークダウンファイルで書き込み、スライドのページを区切るには --- を使います。 # page1 here is description about this slides --- # page2 hogehoge レイアウト front matter blocks の中に書き込むことによって、各スライドのレイアウトやメタデータを指定することができます。 --- で囲んで記載しますが、その中のテキストはYAML 形式のデータオブジェクトです。 --- theme: hoge image: https://hoge.sample/image/image01.png --- # page1 スタイリング Markdown 内で <style> タグを使用してスライドのスタイルをオーバーライドできます。 scoped されるため、グローバルスタイルをオーバーライドするには、規約に沿ったフォルダ構成で対応可能となります。 参考: https://sli.dev/custom/directory-structure.html#style windi.css もサポートしています。 # page1 <style> h1 { color: #ddd } </style> --- ノート(メモ) 各スライドの最後のコメントブロックがメモとして扱われます。 # page1 <!-- memo here --> アイコン 一般的なオープンソースのアイコンセットに直接アクセスできます。 参考: https://sli.dev/guide/syntax.html#icons 複数エントリのサポート V0.15.0 から、slides.md を複数のファイルに分割することができるようになりました。 slides.md # page 1 write here hogehoge --- src: ./slides/subpage2.md --- sample-project/slides/subpage2.md # page 2 this is subpage 2 from another directory Epilogue Slidev は Webアプリケーションでできることはなんでもできる、とのことで API リクエストなどもできるらしいです。 1枚のファイルで複数ページのスライドが作成できるのですが、個人的には別ファイルに作成して差し込めるのが Vue ライクだなと感じました。 今回あげた以外にもレコードなど機能があるようなので、今後も追っていきたいと思いました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue3で生のchart.jsを使いグラフを表示する

vue-chartjsのvue3対応について 悲しいことにvue-chartjsは今のところvue3に対応していないようです。(2021年6月時点) 今は時間がたりないとのことです。 https://github.com/apertureless/vue-chartjs/issues/637 https://github.com/apertureless/vue-chartjs/issues/661 前提 Chart.jsのドキュメントのトップぺージにあるサンプルをネタにして動かしていきますー。 バージョン chart.js: 3.3.2 vue: 3.0.0 インストール yarn add chart.js コード Chart.vue <template> <canvas id="chart"></canvas> </template> <script> //記事末尾で補足 import Chart from 'chart.js/auto'; export default { methods: { renderChart() { let ctx = document.getElementById("chart"); new Chart(ctx, { type: 'line', data:{ labels: ["赤", "青", "黄色", "緑", "紫", "橙"], datasets: [{ label: '得票数', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255,99,132,1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }); } }, mounted() { this.renderChart(); } }; </script> こんな感じでuserしてあげれます。 Sample.vue <template> <div> <h2>chart sample</h2> <Chart></Chart> </div> </template> <script> import Chart from '../components/Chart'; export default { components: { Chart, }, } </script> こんな感じの画像になります。 補足 chart.js3では、使用するモジュールを登録する必要があるというように、ドキュメントに記載がありました。 Chart.js 3 is tree-shakeable, so it is necessary to import and register the controllers, elements, scales and plugins you are going to use. 以下のように単にchart.jsだけだとインポートするとコンソールエラーが出てしまいます。 なので登録してあげましょう。 import { Chart } from 'chart.js'; Uncaught (in promise) Error: "linear" is not a registered scale. Uncaught TypeError: Cannot read property 'left' of undefined したがって登録をしてあげます。一個一個必要なものだけを登録方法もいいようですが、ドキュメントに記載してある短い登録フォーマットを使うと動きます。 import { Chart, registerables } from 'chart.js'; Chart.register(...registerables); また上記を1行で実行できる別のパスを用意してくれてると書いてあります。それが楽なので、今回はそちらの書き方を選びました。 vue.js import Chart from 'chart.js/auto';
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む