20210508のvue.jsに関する記事は23件です。

Vue.jsの基本的なこと

ディレクティブ ディレクティブとは接頭辞 v- が付いた属性のこと 今回は基本的なディレクティブについてまとめます。 v-text index.html <body> <div id="text"> <div v-text="message"></div> </div> </body> <script> var text_hello = new Vue({ el: '#text', data: { message: 'Hello World!' } }) </script> 上記のソースのスクリプトでtext要素にmessageデータを定義し、 html内でv-textを使用しmessageを呼び出すことで定義したmessageの内容が表示されます。 v-for index.html <body> <div id="text"> <li v-for="(msg, key) in message"> {{ key }}:{{msg}} </li> </div> </body> <script> var text_hello = new Vue({ el: '#text', data: { message: { sample1:'hello', sample2:'world', sample3:'hello_world' } } }) </script> v-forで配列の内容をループします。 今回keyとvalue両方を出そうと思い <li v-for="(msg, key) in message"> とすると想定の結果とは逆でしたので今後気を付けたいところ v-if index.html <body> <div id="text"> <input type="checkbox" @click="change" checked> <span v-if="seen"> <li v-for="(msg, key) in message"> {{ key }}:{{msg}} </li> </span> </div> </body> <script> var text_hello = new Vue({ el: '#text', data: { message: { sample1:'hello', sample2:'world', sample3:'hello_world' }, seen: true }, methods: { change: function(e) { this.seen = e.target.checked } } }) </script> 上記ではチェックボックスの値でtrue,falseを認識し、messageを表示するかを制御します。 チェックあり チェックなし 参考 Vue.js入門
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js 勉強メモ】v-ifとv-showの違い

はじめに 仕事で使う事になったので1からVue.jsについて学んだ(元々Angularでプロダクト開発をやっていた事はあるがAngularはだめか・・・)。 ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。 v-ifとv-showの違い これまた見た目の動きは同じ(真偽値の条件で表示・非表示を切り替える)だが、動きには大きな違いがあるのでちゃんと使い分けないといけない。 それぞれの違いは以下の表のとおりで、使い所も違っている。 # 内部の動き デメリット 使い所 v-if HTMLに要素を描画する・しないで表示・非表示を切り替える 表示・非表示が変わるたびに再描画されるのでレンダリングのコストが高くなる 初期時の表示制御など頻繁でない表示切替に用いる v-show 常にHTMLには描画されるが、styleに"display: none;"を付与する・しないで表示・非表示を切り替える ・初期時に必ず描画されるので初期時のレンダリングのコストが高くなる・template構文が使えない・elseに相当するものがないので自前で真偽値の逆バージョンを用意する必要がある 高頻度な表示切替に用いる ※レンダリングのコストが高くなる=Webサイト動作が遅くなる 実際の動きは以下の通り。 動画のソースコードは以下。 sample.html <body> <div id="app"> <button @click="ok = !ok">ボタン</button> <p v-if="ok">If</p> <p v-show="ok">Show</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> new Vue({ el: '#app', data: { ok: true } }) </script> </body> ※v-showのデメリット「template構文が使えない」について、実際にtemplate構文を使うと以下のようにtemplateタグがdisplay: none;になるだけで、template内部は表示されてしまうので使えない。(templateタグは実際には描画されないので見えないが)。 sample.html <body> <div id="app"> <template v-show="ok"> <p>隠したい</p> </template> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> new Vue({ el: '#app', data: { ok: false } }) </script> </body> Vue.jsの勉強メモ一覧記事へのリンク Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。 https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue -Vでバージョンがちゃんと確認できるまでの苦悩

 背景 この記事はvueのcliを入れたものの、vueのコマンドが使えなくて調べた内容を記録しておくための備忘録となっています。 順を追っていきましょう。 流れ まず、vueのcliを使用するために以下のコマンドを実施 <実行コマンド> npm install -g @vue/cli その後、手順に沿ってvueのコマンドが使用できるか確認 <実行コマンド> vue -V zsh: command not found: vue なんでや!!!!! 言われた通りにやってますやん!まあ、こんなことは開発環境設定においてはあるある。 西川くんとこの子が毎回気絶しちゃうくらいあるある。 そんな戯言は置いておいて、調べてみると、PATHが通ってないと。 ふむふむ よく聞くやつですね。 調べてみると、色々と出てくるんですね。そんな中、.bash_profileなるものにPATHの設定をしていないからvueのコマンドが使用できない!みたいな記事を見つけたんです。 でも、考えてみると、わたし、bashじゃないんですよね。 とはいえ、その記事だと、.bash_profileに記述してやればできたっていうので、真似してやってみることに。 terminal export PATH="/Users/***/.npm-global/lib/node_modules/vue-cli/bin:$PATH" $ source ~/.bash_profile まず❗️.bash_profileがないので、(色々と省きますが)できませんでした。 (少し寄り道) そこで一旦、確認する。vueはあるんか。この記事通りで確認するとvue自体は確認できました <実行コマンド> terminal npm list -g vue /Users/[name]/.npm-global/lib └── vue@2.6.12 本筋へ戻ります 調べた結果、自分はzshに設定がなっているのでzshに基づいたpathの設定をしないといけないみたいなんですね。 ふむふむ。 とすると、「.zshrc vue」で調べてみるか、ということに。 なかなか良さそうな記事があったのでそれを真似してみる事に。 .zshrc export PATH=$PATH:/Users/[username]/.npm-global/bin 上記一文を.zshrcの最後の1行に追記してみました。 ([username]のところを自分の登録されている名前に変更してください) そして、ファイルを編集した後は下記コマンドで設定の際読み込みを実施。(これ忘れないでください) <実行コマンド> terminal source .zshrc そしてついに,,, そしてもう一度、vueのコマンドが使えるかバージョンの確認からテストです。 terminal vue -V @vue/cli 4.5.13 ついに通りました!歓喜です!! ついこの間までなら自分一人で解決って難しかったと思うんですけど、ちょっとずつ経験値を積んできて、『多分こういうパターンだろうから、pathをこうしてこうやったら,,,』みたいなのができる様になったのかなと思います。 皆様の中にも、自分はbashじゃないんだけど(自分も気づいたらzshだったんです。怖いですねw)、どうやって解決すればいいんだ??みたいな方が少なからずいらっしゃると思います。そんな方の解決のヒントになれば幸いです。 参考記事はこちらです: How to fix “zsh: command not found: vue”?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue -Vでzsh: command not found: vue からバージョンがちゃんと確認できるまでの苦悩

 背景 この記事はvueのcliを入れたものの、vueのコマンドが使えなくて調べた内容を記録しておくための備忘録となっています。 順を追っていきましょう。 流れ まず、vueのcliを使用するために以下のコマンドを実施 <実行コマンド> npm install -g @vue/cli その後、手順に沿ってvueのコマンドが使用できるか確認 <実行コマンド> vue -V zsh: command not found: vue なんでや!!!!! 言われた通りにやってますやん!まあ、こんなことは開発環境設定においてはあるある。 西川くんとこの子が毎回気絶しちゃうくらいあるある。 そんな戯言は置いておいて、調べてみると、PATHが通ってないと。 ふむふむ よく聞くやつですね。 調べてみると、色々と出てくるんですね。そんな中、.bash_profileなるものにPATHの設定をしていないからvueのコマンドが使用できない!みたいな記事を見つけたんです。 でも、考えてみると、わたし、bashじゃないんですよね。 とはいえ、その記事だと、.bash_profileに記述してやればできたっていうので、真似してやってみることに。 terminal export PATH="/Users/***/.npm-global/lib/node_modules/vue-cli/bin:$PATH" $ source ~/.bash_profile まず❗️.bash_profileがないので、(色々と省きますが)できませんでした。 (少し寄り道) そこで一旦、確認する。vueはあるんか。この記事通りで確認するとvue自体は確認できました <実行コマンド> terminal npm list -g vue /Users/[name]/.npm-global/lib └── vue@2.6.12 本筋へ戻ります 調べた結果、自分はzshに設定がなっているのでzshに基づいたpathの設定をしないといけないみたいなんですね。 ふむふむ。 とすると、「.zshrc vue」で調べてみるか、ということに。 なかなか良さそうな記事があったのでそれを真似してみる事に。 .zshrc export PATH=$PATH:/Users/[username]/.npm-global/bin 上記一文を.zshrcの最後の1行に追記してみました。 ([username]のところを自分の登録されている名前に変更してください) そして、ファイルを編集した後は下記コマンドで設定の際読み込みを実施。(これ忘れないでください) <実行コマンド> terminal source .zshrc そしてついに,,, そしてもう一度、vueのコマンドが使えるかバージョンの確認からテストです。 terminal vue -V @vue/cli 4.5.13 ついに通りました!歓喜です!! ついこの間までなら自分一人で解決って難しかったと思うんですけど、ちょっとずつ経験値を積んできて、『多分こういうパターンだろうから、pathをこうしてこうやったら,,,』みたいなのができる様になったのかなと思います。 皆様の中にも、自分はbashじゃないんだけど(自分も気づいたらzshだったんです。怖いですねw)、どうやって解決すればいいんだ??みたいな方が少なからずいらっしゃると思います。そんな方の解決のヒントになれば幸いです。 参考記事はこちらです: How to fix “zsh: command not found: vue”?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js】Vuetify導入でfiber.nodeがないって言われた

概要 既存のVueCLIプロジェクトにVuetifyをインストールしたら下記のエラーがでた。 terminal ・・・ (project_path)/node_modules/fibers/bin/darwin-x64-79/fibers.node` is missing. ・・・ その時のエラー回避方法を残す。 環境 OS: macOS Catalina Version: 10.15.6 @vue/cli: 4.5.4 解決方法 fiber.nodeの再インストールで回避。作業場所はpackage.jsonが置いてあるVueCLIプロジェクト terminal $ npm uninstall fibers $ npm install fibers
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nuxt.jsでasync/asyncData/awaitがわからなかったのでまとめた

はじめに Rails+Nuxt.jsをやっていてわからなかったので頭の整理も兼ねてまとめます。 今回わからなかったコード async asyncData ({ $axios }) { let users = [] //空配列 await $axios.$get('/api/v1/users') //nuxt axiosの記述でデータを取得する .then(res => (users = res)) //返ってきたデータをusers配列に格納 return { users } //usersの配列をtemplateで使用できるように返す async asyncData ({$axios}) { async Promiseを返してくれる。 Promiseとは外部からデータを取得した際に成功した処理と失敗した処理を返してくれるクラス asyncData() コンポーネントの作成前に実行させる。axiosは読み込みに時間がかかるため最初に読み込みたいのでここで記載する。Nuxt.js作成の際にaxiosを選択した為、今回の場合はNuxtのmoduleからaxiosを持ってきている。 await $axios.$get('/api/v1/users') await Promiseを返すまでJavaScriptを待機させる。 axiosの通信は時間がかかるため、確実に処理を実行するためにawaitをつける \$axios.$get(取得先) axiosで取得先を指定しています。$がつくのはNuxt.jsの書き方。 .then(res => (users = res)) .then(res => (users = res)) 先ほどPromiseは成功した時の処理と失敗した時の処理を返すと書いたが、.then(処理)では成功した時の処理を書くことができる 最後returnをしてtemplate内で使えるようにしてあげる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

猿でも分かる!Vueのリアクティブシステム

Vueのリアクティブシステムを理解する (Zennにも同じ記事を書いています。そちらにはcodesandboxを貼ってあります) 皆さん、Vue.jsを使っていますか?個人的には結構好きでよく使っているのですが、あのリアクティブ性はどうやって実現しているのか気になりませんか?本記事ではVue2系のリアクティブシステムの原理を簡単に説明していきます。 フロントは流行り廃りの激しい分野だからこそ、主要技術がどうやって実現しているのかを知ることが今後にも生きるはずです。 今回使用したコード(sandbox)を記事最下部に貼っておきます。 今回の設定 itemオブジェクトには価格priceと量quantityプロパティがあります。 それらの総額に相当するtotalプロパティをitemオブジェクトの変更を検知して自動的に自動的に再計算されて欲しい。 vue.js的に書くとこんな感じ。 example.vue <script> export default { data() { item: { price: 100, quantity: 3, } }, computed: { total() { return this.item.price * this.item.quantity; // -> 300 } } } </script> (vueの原理を解説するので以降はバニラjsで説明します。やりたいことは変わりません。) もしリアクティブ性がないと... item.quantityに5を代入しても、totalが再計算されないので300のままになってしまいます。 これが自動的に500になるようにしたい。 level1.ts const item = { price: 100, quantity: 3 }; let total: number = 0; const calcTotal = () => (total = item.price * item.quantity); calcTotal(); console.log(total); // -> 300 item.quantity = 5; console.log(total); // -> 300(これが500になって欲しい) どんな機能が必要か 上の例から、リアクティブ性というのは、 プロパティが変更されたらそれを検知してそのプロパティが使用されている関数を自動的に再計算すること と言い換えることができます。つまり、これを実現するには プロパティ毎にそのプロパティがどんな関数で使われているかを保存しておく そのプロパティの更新時に関連する関数を全て再計算する 機能があれば良いわけです。どうですか?なんだかできそうな気がしてきませんか? quantityに対してこれを実装してみる level2.ts const item = { price: 100, quantity: 3 }; let total: number = 0; const storageForQuantity: Function[] = []; const record = (func: Function) => { storageForQuantity.push(func); }; const reCalculate = () => { storageForQuantity.forEach((func) => func()); }; const calcTotal = () => (total = item.price * item.quantity); calcTotal(); // 初期totalの計算 record(calcTotal); // calcTotalはquantityに依存しているのでこの関数をstorageに保存 console.log(total); // -> 300 item.quantity = 5; reCalculate(); // quantityを変更したのでstorage内部の関数を全て再実行 console.log(total); // -> 500 まだ手動で再計算をしていますが、なんとなく処理の流れは掴めたでしょうか。 1. item.quantityに対して、依存関数を入れておく 2. item.quantityが変更されたら、依存関数を全て再計算する では、上の機能をDepというクラスにまとめてみましょう!(Dep: Dependancy) Depクラスの導入 vueの内部で使われている命名と合わせるために、先程とは名前を変えていますが、機能は変わりません! storageForQuantity -> subscribers: 依存関数を保存する配列 record -> depend: 依存関数を追加するメソッド reCalculate -> notify: 依存関数を再計算するメソッド また、targetという変数を導入しました。dependする時にtargetの中に入っている関数を依存関数として追加します。 (これによってdependが副作用のある関数になってしまうのですが、こうしないと後々困るので甘んじて受け入れてください...本家vueもこのやり方です...) level3.ts let target: Function = () => {}; // 依存関数を保存する際の対象関数を入れておく変数 interface Dep { subscribers: Function[]; } class Dep { constructor() { this.subscribers = []; } depend() { if (target && !this.subscribers.includes(target)) { this.subscribers.push(target); } } notify() { this.subscribers.forEach((func) => func()); } } const item = { price: 100, quantity: 3 }; let total: number = 0; const calcTotal = () => (total = item.price * item.quantity); target = calcTotal; // quantityの依存先をtargetに入れておくことで後でdependできる calcTotal(); // 初期totalの計算 const dep = new Dep(); dep.depend(); console.log(total); // -> 300 item.quantity = 5; dep.notify(); console.log(total); // -> 500 そろそろ手動で依存関数を追加したり再実行するのに飽きてきましたね...次のセクションではこの部分を自動化したいと思います。 Object.definePropertyの導入 Object.definePropertyというメソッドを使います。 詳細はMDNドキュメントを見ていただきたいですが、このメソッドはオブジェクトのプロパティを宣言する際にgetter, setterを定義できるというものです。 詳しくはこちら これを用いて、 get() { depend(`プロパティを呼び出した関数`) // 依存関数を保存 return `プロパティの値` } set(value) { `value`をセット notify() // 依存関数を再計算 } のように書けば、 値を参照した(item.quantity)時にgetterが呼ばれて関数をsubscribesに保存 値を変更した(item.quantity = 5)時にsetterが呼ばれて依存関数を全て再計算 することができます。これを実装すればほぼ完成です!! level4.ts let target: Function = () => {}; // 依存関数を保存する際の対象関数を入れておく変数 interface Dep { subscribers: Function[]; } class Dep { constructor() { this.subscribers = []; } depend() { if (target && !this.subscribers.includes(target)) { this.subscribers.push(target); } } notify() { this.subscribers.forEach((func) => func()); } } const item = { price: 100, quantity: 3 }; let total: number = 0; const calcTotal = () => (total = item.price * item.quantity); // itemのそれぞれのプロパティに対してDepを作成し、getterではdepend, setterではnotifyをする Object.keys(item).forEach(key => { let _value = item[key]; const dep = new Dep(); Object.defineProperty(item, key, { get() { dep.depend(); return _value; }, set(value) { _value = value dep.notify() } }) }) target = calcTotal; // quantityの依存先をtargetに入れておくことで後でdependできる calcTotal(); // 初期totalの計算 console.log(total); // -> 300 item.quantity = 5; console.log(total); // -> 500 (quantityを書き換えただけなのに!!!!) 最後を見てください!!! item.quantityを書き換えただけなのにも関わらず自動的にtotalが更新されました? これにてリアクティブ性の獲得を達成することができました。 最後はもう少し処理を抽象化します。 watcherの追加(おまけ) 前回まではtargetに依存関数を入れてから関数を実行して...という処理を行なっていました。しかし、これは関数が複数になった場合に大変なことになってしまいます。 そこで、関数群をまとめて上記の処理を行なってくれるwatcher関数を作成します。 今回はitem.taxRateを追加し、税込みの総額を入れておくtotalWithTaxもリアクティブな変数にしてあります。 おまけ程度に、オブジェクトを渡すとリアクティブにしてくれるinitData関数も作成しました。 level5.ts let target: Function | null = null; // 依存関数を保存する際の対象関数を入れておく変数 interface Dep { subscribers: Function[]; } class Dep { constructor() { this.subscribers = []; } depend() { if (target && !this.subscribers.includes(target)) { this.subscribers.push(target); } } notify() { this.subscribers.forEach((func) => func()); } } const watcher = (funcObj: Record<string, Function>) => { Object.values(funcObj).forEach((func) => { target = func; func(); target = null; }); }; const initData = (dataObj: Object) => { Object.keys(dataObj).forEach((key) => { let _value = dataObj[key]; const dep = new Dep(); Object.defineProperty(dataObj, key, { get() { dep.depend(); return _value; }, set(value) { _value = value; dep.notify(); } }); }); } const item = { price: 100, quantity: 3, taxRate: 1.1, }; let total = 0; let totalWithTax = 0; const calcTotal = () => (total = item.price * item.quantity); const calcTotalWithTax = () => (totalWithTax = item.price * item.quantity * item.taxRate); // itemをリアクティブに initData(item) // vueで言うところのcomputedのような関数をwatcherに渡す。 watcher({ calcTotal, calcTotalWithTax, }) console.log(`total: ${total}, totalWithTax:${totalWithTax}`); // -> 300 // -> total: 300, totalWithTax:330 item.quantity = 5; console.log(`total: ${total}, totalWithTax:${totalWithTax}`); // -> 300 // -> total: 500, totalWithTax:550 おわりに ここまで読んでくださりありがとうございます! Vueのリアクティブシステムがどのように実現されているかを説明しました。実際のvueもこのような実装になっているので興味がある方は覗いてみると面白いと思います!(vueのレポジトリ内でdepend()やnotify()で検索すると出てくると思います) Vue3系のリアクティブシステムはProxyを使っているらしく、こちらも勉強したら記事を書こうと思います。 少しでも参考になったという方はいいね!お願いします! 今回使ったコード
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

<style>でCSSを設定する

src/App.vue <style> div{ border:1px solid blue; } </style> src/LikeNumber.vue <style> div{ border:1px solid red; } </style> 基本: (1)divと設定した時点で全てのdivに適応される。 (2)赤になっているのはCSSはあとから設定したものが指定され前のものは打ち消される。 src/App.vue <style scoped> div{ border:1px solid red; } </style> 表示させたいファイルを限定するには「style scoped」とする。 *その属性を持ったセレクターのあるものに対して色をつける。つまり指定された属性を持ったタグを指定してCSSを効かせていく。 <参考> div外側のものと内側のものがあり 内側のdiv属性がdata-v-276663f0 外側のdiv属性がdata-v-7ba5bd90 それぞれ選んで色をつけることができます。 ただし2つ目divについてはdata-v-276663f0とdata-v-7ba5bd90が指定されている。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンポーネント登録(共通):命名のケース (Name Casing)

コンポーネント登録(共通):命名のケース (Name Casing) ケバブケース(kebab-case) my-component-name パスカルケース(PascalCase) MyComponentName *DOMだけはケバブケースで書くように求められる。 *ブラウザは大文字小文字の判別ができないため。 *コンポーネントではパスカルケースにしましょうと決まっています
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LikeHeaderでローカル登録したコンポーネントをAppで表示する

(1)LikeHeader.vueファイルを作る (2)importしてコンポーネント登録する src/App.vue <template> <div> <LikeHeader></LikeHeader> <LikeNumber></LikeNumber> </div> </template> <script> import LikeHeader from "./LikeHeader.vue"; export default { components: { LikeHeader: LikeHeader } }; </script> *ES6では src/App.vue components: { LikeHeader } キーとバリューが同じ場合は省略してかける まずLikeHeaderファイルをコードディング src/LikeHeader.vue <template> <h1>いいね</h1> </template>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

エラー: The template root requires exactly one element

複数の要素を入れる場合は divタグなどで1つに括ってあげる。 <template> <p>いいね({{ number }})</p> <button @click="increment">+1</button> </template> <script> export default { data() { return { number: 7 }; }, methods: { increment(){ this.number += 1; } } }; </script> Failed to compile. ./src/LikeNumber.vue Module Error (from ./node_modules/eslint-loader/index.js): /Users/maedatakuo/projects/udemy-vuejs/src/LikeNumber.vue 3:3 error The template root requires exactly one element vue/valid-template-root ✖ 1 problem (1 error, 0 warnings) <template> <div> <p>いいね({{ number }})</p> <button @click="increment">+1</button> </div> </template> <script> export default { data() { return { number: 7 }; }, methods: { increment(){ this.number += 1; } } }; </script>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue】v-selectで選んだ値を取得する方法

はじめに v-selectで開発をしている際に、メソッド経由でイベントの値をどのように取得するかを少し戸惑ったのでメモします。 経緯 v-selectで表示される値(本のタイトル)を選択した際に、選択時の値(本のタイトルid)を取得したい時に、どのようにするのがベストプラクティスなのかを少し悩みました。 具体的には以下のようなv-selectの時です。 Trouble.vue <template> ... <v-select v-model="title" :item="titleText" @change="fetchTitle" item="text" item-value="value" label="本のタイトルを選択" dense /> ... </template> 方法 結論:イベントハンドラ関数の使用をすること Example1.vue <template> ... <v-select v-model="title" :item="titleText" @change="fetchTitle" item="text" item-value="value" label="本のタイトルを選択" dense /> ... </template> <script> ... fetchTitle (event) { // eventに選択した値が含まれている } ... </script> 上記のv-selectのv-onでfetchTitle()イベントメソッドを実行する際にfetchTitleのように括弧を省きます。 省くことでイベントオブジェクトにアクセスできることで、v-selectで選択した値を取得することができます。 Example2.vue <template> ... <v-select v-model="title" :item="titleText" @change="fetchTitle(titleText, $event)" item="text" item-value="value" label="本のタイトルを選択" dense /> ... </template> <script> ... fetchTitle (titleText, event) { // eventに選択した値が含まれている } ... </script> 上記のようにイベントメソッドに$eventのオブジェクトを渡すことで他の引数も渡すことができます。 例題 Example.vue <template> <div id="app"> <ul> <li v-for="example in examples"> <input type="text" @change="onChange(example.id, $event)"> </li> </ul> </div> </template> <script> new Vue({ el: '#app', data() { return { examples: [ { id: 1, name: 'A' }, { id: 2, name: 'B' }, { id: 3, name: 'C' } ] } }, methods: { onChange(id, event) { console.log(id) console.log(event) } } }) </script> 参照
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

グローバル登録でmain.jsで表示させてみる

(1)templateに表示用HTMLを書く (2)scriputにデータを入れる (3)main.jsにファイルをimportする (4)グローバル登録する src/App.Aue <template> <LikeNumber></LikeNumber>         #グローバル登録を別ファイルで表示 </template> src/LikeNumber.Aue <template> <p>いいね({{ number }})</p> </template> <script> export default { data() { return { number: 7 #データはここ }; } }; </script> src/main.js import Vue from 'vue'; import App from './App.vue'; import LikeNumber from './LikeNumber.vue'; //import Vue.config.productionTip = false; Vue.component("LikeNumber", LikeNumber); //グローバル登録 new Vue({ render: h => h(App) }).$mount("#app"); ちなみに今までと違ってフレームワークを使っているのでエラーをちゃんと表示してくれます。 参考 returnをretenと入力すると Failed to compile. ./src/LikeNumber.vue Module Error (from ./node_modules/eslint-loader/index.js): /Users/maedatakuo/projects/udemy-vuejs/src/LikeNumber.vue 8:11 error Parsing error: Missing semicolon. 2 | export default { 3 | date() { > 4 | retuen { | ^ 5 | number: 7 6 | }; 7 | } ✖ 1 problem (1 error, 0 warnings) やっとRuby on Railsのようなエラー表示が出て嬉しいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

いいね{{number}}をvue CLIで表示してみる

APP.vue(ES5) <template> <p>いいね{{ number }}</p> </template> <script> export default{ data: function() { return { number: 12 } } } </script> <style> </style> http://localhost:8080/ APP.vue(ES6) <template> <p>いいね{{ number }}</p> </template> <script> export default{ data() { return { number: 6 } } } </script> <style> </style>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

import App from './App.vue'とは

Vue CLIのsrcフォルダにあるmain.jsの記述をvs.codeで開いて見てみます。 import App from './App.vue'ってなんでしょう? 上に設置してある「App.vue」のことだそうです。 中身はtemplate,script,styleの3つの要素からできています。 import App from './App.vue'とはApp.vue(単一ファイルコンポーネント)を読み込んで(import)オブジェクトを作っていますということだそうです。 以下は参考オブジェクトの中身です。 Object beforeCreate: Array(1) 0: ƒ () length: 1 __proto__: Array(0) beforeDestroy: Array(1) 0: ƒ () length: 1 __proto__: Array(0) components: HelloWorld: beforeCreate: [ƒ] beforeDestroy: [ƒ] name: "HelloWorld" props: {msg: {…}} render: ƒ () staticRenderFns: (4) [ƒ, ƒ, ƒ, ƒ] _Ctor: {0: ƒ} __file: "src/components/HelloWorld.vue" _compiled: true _scopeId: "data-v-469af010" __proto__: Object __proto__: Object name: "App" render: ƒ () _withStripped: true arguments: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.r (<anonymous>:1:83)] caller: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.r (<anonymous>:1:83)] length: 0 name: "render" prototype: {constructor: ƒ} __proto__: ƒ () apply: ƒ apply() arguments: (...) bind: ƒ bind() call: ƒ call() caller: (...) constructor: ƒ Function() length: 0 name: "" toString: ƒ toString() Symbol(Symbol.hasInstance): ƒ [Symbol.hasInstance]() get arguments: ƒ () set arguments: ƒ () get caller: ƒ () set caller: ƒ () __proto__: Object [[FunctionLocation]]: ​ [[Scopes]]: Scopes[0] [[FunctionLocation]]: App.vue?42e3:1 [[Scopes]]: Scopes[3] staticRenderFns: Array(0) length: 0 __proto__: Array(0) concat: ƒ concat() constructor: ƒ Array() copyWithin: ƒ copyWithin() entries: ƒ entries() every: ƒ every() fill: ƒ fill() filter: ƒ filter() find: ƒ find() findIndex: ƒ findIndex() flat: ƒ flat() flatMap: ƒ flatMap() forEach: ƒ forEach() includes: ƒ includes() indexOf: ƒ indexOf() join: ƒ join() keys: ƒ keys() lastIndexOf: ƒ lastIndexOf() length: 0 map: ƒ map() pop: ƒ pop() push: ƒ push() reduce: ƒ reduce() reduceRight: ƒ reduceRight() reverse: ƒ reverse() shift: ƒ shift() slice: ƒ slice() some: ƒ some() sort: ƒ sort() splice: ƒ splice() toLocaleString: ƒ toLocaleString() toString: ƒ toString() unshift: ƒ unshift() values: ƒ values() Symbol(Symbol.iterator): ƒ values() Symbol(Symbol.unscopables): {copyWithin: true, entries: true, fill: true, find: true, findIndex: true, …} __proto__: Object _Ctor: 0: ƒ VueComponent(options) __proto__: Object __file: "src/App.vue" _compiled: true __proto__: constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンポーネントのグローバル登録とローカル登録

グローバル登録の場合いずれのvueのidにも適用されている。 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> <div id="app2"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> var data = { number: 12 } Vue.component('my-component', { data: function() { return data }, template: '<p>いいね({{number}})<button @click="increment">+1</button></p>', methods: { increment: function() { this.number += 1; } } }) new Vue({ el: '#app', }) new Vue({ el: '#app2', }) ローカル登録 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> <div id="app2"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> var component = { data: function() { return { number: 12 } }, template: '<p>いいね({{number}})<button @click="increment">+1</button></p>', methods: { increment: function() { this.number += 1; } } } new Vue({ el: '#app', components:{ 'my-component':component } }) new Vue({ el: '#app2', }) *appにだけコンポーネントが適用されています。 コンポーネント「ローカル」登録:コンポーネント名 Vue.component('my-component-name', 変数名) *コンポーネント名は Vue.component の第一引数です。' 'の部分です。 *適用するVueインスタンスにだけコードを書きます。 コンポーネント登録(共通):命名のケース (Name Casing) ケバブケース (kebab-case) my-component-name パスカルケース (PascalCase) MyComponentName *グローバル登録では全てのnew Vueに適用されます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンポーネントの際は関数にする必要がある

関数にした場合 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> Vue.component('my-component',{ data: function(){ return { number: 12 } }, template: '<p>いいね({{number}})<button @click="increment">+1</button></p>', methods: { increment: function(){ this.number+= 1; } } }) new Vue({ el: '#app', }) それぞれの表示した項目が別のメモリを使っているためにそれぞれ個別に保存できる。 オブジェクトで無理やりコンポーネントに設定した場合。(return内の外部オブジェクトにする) <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> var data = { number: 12 } Vue.component('my-component', { data: function() { return data }, template: '<p>いいね({{number}})<button @click="increment">+1</button></p>', methods: { increment: function() { this.number += 1; } } }) new Vue({ el: '#app', }) これで+1ボタンを押すと オブジェクトの場合は1つのメモリを共有することになるので+1を押しても3つとも同時に1づつ増加して同じ数字で表示されてしまう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンポーネントの際はdataは関数にする必要がある

関数にした場合 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> Vue.component('my-component',{ data: function(){ return { number: 12 } }, template: '<p>いいね({{number}})<button @click="increment">+1</button></p>', methods: { increment: function(){ this.number+= 1; } } }) new Vue({ el: '#app', }) それぞれの表示した項目が別のメモリを使っているためにそれぞれ個別に保存できる。 オブジェクトで無理やりコンポーネントに設定した場合。(return内の外部オブジェクトにする) <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> var data = { number: 12 } Vue.component('my-component', { data: function() { return data }, template: '<p>いいね({{number}})<button @click="increment">+1</button></p>', methods: { increment: function() { this.number += 1; } } }) new Vue({ el: '#app', }) これで+1ボタンを押すと オブジェクトの場合は1つのメモリを共有することになるので+1を押しても3つとも同時に1づつ増加して同じ数字で表示されてしまう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンポーネントについて

コンポーネントとは再利用できるvueのインスタンスである。 間違った使い方から <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> </div> <div id="app"> </div> new Vue({ el: '#app', data: { number: 12 }, template: '<p>いいね{{number}}</p>' }) こちらの意図としては同じdivタグを2つ用意して「いいね12」が2連続表示されるかと思っていたが、その意図には反して最初に示したものと同じものは無視するというvuejsの仕様で無視されている。 ここでコンポーネントの設定をして2回連続表示します。 Vue component('コンポーネントの名前',{コンポーネントの情報=データなど}) (1)vue.componentを設定します。 (2)vueファイルにコンポーネント名のタグを設置します。 *今回は (3)Dataがある場合は関数を使ってreturnとオブジェクトで表現する。 今回はプロパティがnumberで値が12です。 ⇨data: function(){return {number: 12}} <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <my-component></my-component> </div> <div id="app"> </div> Vue.component('my-component',{ data: function(){ return { number: 12 } }, template: '<p>いいね({{number}})</p>' }) new Vue({ el: '#app', }) <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> 繰り返し処理 うまくいきました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vuw CLIを導入する

(1)node.js https://nodejs.org/ja/ こちらのサイトへ行って 以下を展開してインストールします。 次にターミナルを開きます。 MacBook-Air projects % vue create udemy-vuejs 今回はこちらを選択 Vue CLI v4.5.12 ? Please pick a preset: Default ([Vue 2] babel, eslint) ? Successfully created project udemy-vuejs. ? Get started with the following commands: $ cd udemy-vuejs $ npm run serve 終了したら終わりです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Nuxt.js】assets/ と static/ はどう使い分ける�?

結論 → 基本はassetsで! 基本的には assets を用い、 webpack を通さなくていいファイルや webpack で不都合が生じるファイルがあった場合に static の使用を検討すればいいようです。 また、データ容量の小さな画像は「assets」、データ容量の大きな画像は「static」に格納する。 assetsディレクトリ assets の場合は下記2点が static と違う点であるとわかりました。 特徴1 assets/ に配置した画像は、 npm run generate コマンド実行時に、 ハッシュ付きの特別なファイル名に変更された上で、 dist/ に展開されます。この処理がコマンド実行の度に行われることで、同じファイル名で画像が変更された際のキャッシュ管理に役立ちます。 <!-- このように変換(base64の部分が実際のデータ) --> <img src="data:image/png;base64,iVBORw0KGgoAAAANSU ... 5ErkJggg=="> これにより、過去のキャッシュの影響を受けないことがメリットです。 つまり、ブラウザが過去に訪問したWebサイトに変更があり画像が変わっていたとしても、ファイル名が自動で変えられているため、過去のキャッシュではなく変更後の画像を表示してくれます。 特徴2 自動エンコードされ配信されるので高速化。 assetsから読み込んだ画像フォルダが1KB未満の小さな容量であったとき、 自動的にbase64エンコードされたデータがhtml上で展開されるため、 小さなアイコンファイル等を複数利用しているケースの画像配信が高速化されます。 Nuxt.js で始める Webサイト制作 HTML側からassets配下のファイルを参照 assers/ 配下にファイルがある場合、assets/img/my.jpg のパスで作成した画像ファイルの参照は、 以下のように記述します。 <template> <div> ... <img src="~assets/img/my.jpg" alt=""> ... </div> </template> CSS側からassets配下のファイルを参照 css ファイルの中で assets ディレクトリにリンクする必要がある場合は、下記のように記述します。 background: url('~assets/img/my.jpg'); staticディレクトリ static/ 配下のファイルは、 webpack でコンパイルされません。 これらの画像は npm run generate コマンドで、そのまま dist/ に展開されます。 つまり、直接サーバーのルート配下に配置されます。 static配下のファイルを参照 static 直下に favicon を配置した場合、 static/favicon.ico のパスで作成した画像ファイルの参照は、 以下のように static/ を省いて記述します。 <template> <div> ... <img src="/favicon.ico" alt=""> ... </div> </template> static配下に置くべきなのは? 加工した画像などの容量の大きいもの favicon.icoなど外部から読み込む可能性のあるもの 名前を変更されたくないファイル (assetsの場合、webpackにより名前を変えられてしまうので) 基本は CSS/JS は assets だけど、外部ライブラリの CSS/JS など、自分で編集しないファイルは static が良い? 参考文献 Nuxt.js公式 - ディレクトリ構成 Nuxt.js で始める Webサイト制作
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.js CDNとCLIで勝手が違う

4月から仕事でVue.js + Vuetify環境でシステム開発をやってます。 業務に入る前からVue.jsを使うよ、と言うことで、当初はCDNによる開発を勉強していました。 しかし実際には、サーバ側にVue CLIを導入して開発するということで、環境構築から改めて始めてみたところ、開発方法自体もCDNとは別物だと気付きました。 たぶん、突っ込みどころ満載だと思いますが、突っ込んだら大人として負けだと、生暖かい目で見て下さい。 Vue.jsの開発環境 Vue.jsを使って開発する場合、2つの方法があります。 一つはCDN(Contents Delivery Network)を使う方法。これはHTML上で<script>要素を使って、CDN上にあるVue.jsのパッケージをインポートして利用する方法です。 入力例 <script src="https://cdn.jsdelivr.net/npm/vue@(任意のバージョン)"></script> もう一つは、CLI(Command Line Interface)を利用する方法。これはコマンドを入力することでVue.jsの開発に必要な機能を取得して利用する方法です。 例えば、仮想のWebサーバを起動した上で、Vue.jsで記述された複数のソースコードを1つのHTML+JavaScriptで記述されたページとしてビルドを行い、ブラウザにそのページを送る、あるいはビルドを行ったページソースをデプロイ(出力)することが出来ます。 それぞれの特徴 CDN クライアントだけで開発環境を完結できる(インターネット接続は必須) 開発環境の構築が不要 コンポーネント化する際に、HTML、CSS、Vue.js部分を別ファイルで記述する必要がある http-vue-loader.jsを読み込むことでvueファイルの利用が可能 SPA(Single Page Application)としての構築が難しく、ページごとの内容、ソースコードがブラウザから閲覧できてしまう。 上記方法でSPAも一応は可能。 CLI VueファイルにすることでHTML、CSS、Vue.jsをまとめることが出来る。 SPAとしての構築が比較的容易(ページ内容、ソースコードがバレにくい) デプロイすることで、静的サーバ上でも運用可能 サーバ側にNode.js、npmをあらかじめインストールする必要がある @vue/cliなどのパッケージをインストールする必要がある(追加パッケージがなければ随時インストール) リロード設定を入れることで、ソースの更新に併せて表示ページの更新が可能 vue.config.js 等の設定ファイルを更新した場合は、サーバの再起動が必要 気軽に始めるならCDNでもかまいませんが、セキュリティ面を考えて、厳密なSPAとして構築するなら、サーバを用意してCLIで構築する方がいいと思います。 職場に於いては、WindowsマシンにWSL2(Ubuntu)とDocker + Docker Composeを導入し、Vue CLI用のコンテナを構築して開発しています。 こうすることで、vue.config.jsを更新して再起動する必要があっても、コンテナ自体を再起動させるだけで、システムやサービスに影響を与えることなく開発を進められます。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

render関数

Hello World テキストHello Worldをrender関数を利用してブラウザ上に表示させるためには以下のような記述が必要となります。createElementでは第一引数に要素名、第二引数に要素の中に入る文字列を記述しています。 render関数の基本 render関数はと同じく、Vueコンポーネントにテンプレートを定義するためのものです。 render関数は引数にcreateElementを受けるので、それをhという名前にして使うのが一般的な作法です。 render: function (createElement) { return createElement(App) } こうなって... render (createElement) { return createElement(App) } 短くなって... render (h) { return h(App) } こうなる。 render: h => h(App) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> </div> <script> var app = new Vue({ el: '#app', data: { message: 'Hello World' }, render: function(createElement){ return createElement('h1',this.message) } }) </script> </body> </html> styleの設定もする <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> </div> <script> var app = new Vue({ el: '#app', data: { message: 'Hello World' }, render: function(createElement){ return createElement('h1',{ style: 'background-color:red;color:white;' },this.message) } }) </script> </body> </html> 第1引数はタグ・第2引数はタグの開始タグ終了タグに挟まれた「テキスト情報」もしくは「値」が入ります。 これでわかるvue.jsのrender関数 https://reffect.co.jp/vue/vue-js-render
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む