20211127のvue.jsに関する記事は10件です。

【React】【Vue】 など流行りのフレームワークを使うもののためのJS基礎

流行りのフレームワークを使っていると忘れがち(意識しなくてよい)JSの基礎を学び直してみた。 関数とメソッドの違い 結論:オブジェクトに入っているのかどうか 関数→複数の箇所から共通で呼び出せるプログラムの塊 メソッド→オブジェクトがプロパティとして持っている関数 例 ・関数 const sample = () => { console.log("hello") } sample() ・メソッド const person = { name:"菅田将暉", age:28, sample:()=>{ console.log("結婚おめでとう!") } } person.sample() クラス・インスタンス ・クラス 設計図をイメージ クラス名は基本的に大文字から始める 例 class Car{ } ・インスタンス  オブジェクトを生成するための設計図(class)が用意できたので、  その設計図から実際にオブジェクトを生成する為には、「new クラス名()」とする。  クラスから生成したオブジェクトはインスタンスと呼ぶ。 例 class Car{ } // Carクラスのインスタンスを定数carに代入 const car = new Car(); ・コンストラクタ  クラスにはコンストラクタと呼ばれる機能が用意されている。  コンストラクタはインスタンスを生成するときに実行したい処理や設定を追加するための機能。  クラスの中括弧 { } 内に 「constructor() { }」と記述する。 例 class Car{ // クラスの中に追加 constructor() { } } コンストラクタの処理  コンストラクタの中に処理を記述することで、ここに書いた処理は  インスタンスが生成された直後に実行される。  そして、大切なのは、インスタンスごとに毎回実行されるという事。 例 class Car{ constructor() { console.log("新車が発売されます!"); } } const car1 = new Car(); const car2 = new Car(); 出力結果 // インスタンスごとに実行される 新車が発売されます! 新車が発売されます! プロパティと値を追加  コンストラクタの中で、生成したインスタンスに関する情報を追加するには、  コンストラクタの中で「this.プロパティ = 値」とする事で、  生成されたインスタンスにプロパティと値を追加する事が出来る。 例 class Car{ constructor() { this.プロパティ名 = 値; } }  コンストラクタの中で追加した値は、  「インスタンス.プロパティ」とする事でクラスの外で使用出来る。 例 class Car{ constructor() { this.name = "トラック"; } } const car = new Car(); // 「名前: 〇〇」となるように出力 console.log(`名前: ${car.name}`); 出力結果 名前: トラック 引数ごとに値を変える  コンストラクタでは、関数と同じように、引数を受け取ることが可能。  「constructor」の後の括弧「( )」内に引数名を記述することで、  その引数をコンストラクタの処理内で使用出来る。  コンストラクタに引数として値を渡すには、  「new クラス名( )」の括弧「( )」内に値を追加する。 例 class Car{ constructor(name, color) { this.name = name; this.color = color; } } // 引数に「"トラック"」と「黒」を渡す const car = new Car("トラック", "黒"); // 「名前: 〇〇」となるように出力 console.log(`名前: ${car.name}`); // 「色: 〇〇」となるように出力 console.log(`色: ${car.color}`); 出力結果 名前: トラック 色: 黒 メソッド  メソッドとはそのインスタンスの「動作」のようなもの。  「名前」や「年齢」などの情報はプロパティで追加したのに対して、  メソッドは「挨拶をする」「値を計算する」などの処理のまとまりを表す。 メソッドの定義  メソッドはクラスの中で定義します。  「メソッド名() { }」とすることでメソッドは定義出来る。  メソッドは関数と似たようなもので、中括弧「{ }」の中にそのメソッドで行いたい処理を記述する。 例 class Car{ メソッド名() { // 行いたい処理 } } メソッドの呼び出し方  「インスタンス.メソッド名()」とする事でそのメソッドを呼び出し、  処理を実行することが出来る。 例 class Car{ constructor(name, color) { this.name = name; this.color = color; } // actionメソッドを追加 action() { console.log("走る"); } } const car = new Car("トラック", "黒"); // carに対してactionメソッドを呼び出す car.action(); 出力結果 走る メソッド内で値を使う  メソッド内でインスタンスの値を使用するには、「this」という特殊な値を用いて、  「this.プロパティ名」とします。 例 class Car{ constructor(name, color) { this.name = name; this.color = color; } action() { console.log(`${this.name}は、走る`); } } const car = new Car("トラック", "黒"); // carに対してactionメソッドを呼び出す car.action(); 出力結果 トラックは、走る メソッド内でのメソッド呼び出し  メソッド内で他のメソッドを呼び出すことも可能。  メソッド内で「this.メソッド名()」とすることで、同じクラスの他のメソッドを使うことが出来る。 例 class Car{ constructor(name, color) { this.name = name; this.color = color; } // actionメソッド action() { console.log(`${this.name}は、走る`); } // infoメソッド info() { // actionメソッドを呼び出す this.action(); console.log(`この車は${this.name}です`); console.log(`${this.color}色です`); } } const car = new Car("トラック", "黒"); car.info(); 出力結果 トラックは、走る この車はトラックです 黒色です 実際の使用方法 実際クラスを作ってインスタンス化して使うことはあまりしないと思います。 元から用意されて物を使うのが一般的かなと思います。 //インスタンス化(初期化) let today = new Date() //引数を渡してインスタンス化 let newYear = new Date(2021,1,1) //インスタンスに元から入っているメソッドを使う today.getDate() newYear.getFullYear()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js】ハンバーガーメニュー開閉時にスクロール制御する方法

はじめに こんにちは。 こちらの記事では、クリックイベント発生時にスクロールの制御を行う方法を記しています。 誤っている点がございましたらコメントいただけると幸いです。 実装手順 1. スマホのときに表示するハンバーガーボタンを作成する レスポンシブ対応時に、ヘッダーにボタンを配置する。 isOpenの初期値にfalseを設定しているので、クリックされてtoggleScrollイベントが発火すると、真偽値が反転する処理を記述する。 template <header> <button @click="toggleScroll"> </header> script data: function () { return { isOpen: false, }; }, methods: { toggleScroll() { this.isOpen = !this.isOpen; } } 2. イベントの発生を制御する関数を定義 この後使用するスクロールを制御を実装するために、preventDefault()メソッドを定義します。 script function scroll_control(event) { event.preventDefault(); } export default { } 3. 真偽値を判別してスクロールの制御を行う isOpenがtrueのときは、PCでのスクロール(mousewheel)とスマホでのタッチスクロール(touchmove)を無効にし、falseのときは無効にしたイベントを解除する処理を実装します。 script methods: { toggleScroll() { this.isOpen = !this.isOpen; if (this.isOpen === true) { document.addEventListener("mousewheel", scroll_control, { passive: false, }); document.addEventListener("touchmove", scroll_control, { passive: false, }); } else { document.removeEventListener("mousewheel", scroll_control, { passive: false, }); document.removeEventListener("touchmove", scroll_control, { passive: false, }); } }, } 2.で定義したscroll_control()の中でpreventDefault()が実行されています。また、preventDefault()でスマホでのタッチスクロール(touchmove)を無効にする場合は、passive:falseを設定しないと正常な挙動にならないので注意が必要です。 参考 Event.preventDefault() 【javaScript】でスクロールを禁止にする(PC、スマホ対応) マウスによるスクロールやスマホのスワイプを制御するjs(passive: false) おわりに ここまでクリックイベント発生時にスクロールの制御を行う方法についてまとめました。 Vue.jsでの実装されている記事がなかったので、このように実装してみましたが、こんな方法もあるよ!などがあればコメントいただけると助かります! 以上、最後まで読んでいただきありがとうございました! よければLGTMを押してくれると嬉しいです!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue + ros 基本の通信

はじめに Vueとは何かというとJavaScriptのフレームワークでHTML,JavaScript,CSSのプログラムを1つのコンポーネントとして扱いそれを組み合わせWebアプリを作成することができます。 そのため1つ1つの機能のプログラムを小さく保つことができWebアプリ開発が楽になります。ロボットのWebアプリ開発でも規模が大きい場合は使うと良いかも知れません。 ここでは,Vueの最初のサンプルにrosと通信する部分を追加する方法について記載させていただきます。 また、Vueのインストール方法や立ち上げ方法などは以下など他の人の記事を参考にしてください。 環境 Ubuntu 20.04 ROS noetic Vue 3.0 準備 vueプロジェクトを作成したら,まずROSとの通信に使用するroslibをインストールします npm install roslib あとはsrc/App.vueを以下に記載しているサンプルに変更し, roslaunch rosbridge_server rosbridge_websocket.launchとともに実行することでROSとの通信を色々試すことができます。 サンプル 1.ベースプログラム rosbridgeとのコネクションをするだけのコードです.今後記載するサンプルのベースプログラムとなります. src/App.vue <template> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </template> <script> import ROSLIB from "roslib" // 追加 import HelloWorld from './components/HelloWorld.vue' // *** 追加 ここから *** // const ros = new ROSLIB.Ros({ url: 'ws://localhost:9090' }); // *** 追加 ここまで *** // export default { name: 'App', components: { HelloWorld }, // *** 追加 ここから *** // mounted() { this.init(); }, methods: { init: function () { ros.on("connection", function() { console.log("connected to websocket server."); }); ros.on("error", function(error) { console.log("error connecting to websocket server: ", error); }); ros.on("close", function() { console.log("connection to websocket server closed."); }); }, // *** 追加 ここまで *** // } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 2.Publisher ブラウザからPublishするサンプルプログラムです。 src/App.vue <template> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> <p><button v-on:click="publish()">publish</button></p> <!-- 追加 --> </template> <script> import ROSLIB from "roslib" import HelloWorld from './components/HelloWorld.vue' const ros = new ROSLIB.Ros({ url: 'ws://localhost:9090' }); // *** 追加 ここから *** // var cmdVel = new ROSLIB.Topic({ ros : ros, name : '/cmd_vel', messageType : 'geometry_msgs/Twist' }); var twist = new ROSLIB.Message({ linear : { x : 0.1, y : 0.2, z : 0.3 }, angular : { x : -0.1, y : -0.2, z : -0.3 } }); // *** 追加 ここまで *** // export default { name: 'App', components: { HelloWorld }, mounted() { this.init(); }, methods: { init: function () { ros.on("connection", function() { console.log("connected to websocket server."); }); ros.on("error", function(error) { console.log("error connecting to websocket server: ", error); }); ros.on("close", function() { console.log("connection to websocket server closed."); }); }, // *** 追加 ここから *** // publish: function () { cmdVel.publish(twist); }, // *** 追加 ここまで *** // } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 実行の結果以下のようになり、ブラウザのボタンを押すと,/cmd_velがpublishされます 3.Subscriber 次はSubscriberのサンプルプログラムです。 src/App.vue <template> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> <p>sub msg: {{ msg }} </p> <!-- 追加 --> </template> <script> import ROSLIB from "roslib" import HelloWorld from './components/HelloWorld.vue' const ros = new ROSLIB.Ros({ url: 'ws://localhost:9090' }); // *** 追加 ここから *** // var sub = new ROSLIB.Topic({ ros: ros, name: "/listener", messageType: "std_msgs/String" }); // *** 追加 ここまで *** // export default { name: 'App', components: { HelloWorld }, // *** 追加 ここから *** // data: function () { return { msg: "", }; }, // *** 追加 ここまで *** // mounted() { this.init(); }, methods: { init: function () { ros.on("connection", function() { console.log("connected to websocket server."); }); ros.on("error", function(error) { console.log("error connecting to websocket server: ", error); }); ros.on("close", function() { console.log("connection to websocket server closed."); }); // *** 追加 ここから *** // var self = this; sub.subscribe(function(message) { //console.log("callback",message); self.msg = message; }); // *** 追加 ここまで *** // }, } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 実行の結果以下のようになり、/listenerにデータを送るとブラウザに表示されます 4.Service Client Service Clientのサンプルです。 src/Add.vue <template> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> <p><button v-on:click="call()">service call</button></p> <!-- 追加 --> </template> <script> import ROSLIB from "roslib" import HelloWorld from './components/HelloWorld.vue' const ros = new ROSLIB.Ros({ url: 'ws://localhost:9090' }); // *** 追加 ここから *** // var addTwoIntsClient = new ROSLIB.Service({ ros : ros, name : '/add_two_ints', serviceType : 'rospy_tutorials/AddTwoInts' }); var request = new ROSLIB.ServiceRequest({ a : 1, b : 2 }); // *** 追加 ここまで *** // export default { name: 'App', components: { HelloWorld }, mounted() { this.init(); }, methods: { init: function () { ros.on("connection", function() { console.log("connected to websocket server."); }); ros.on("error", function(error) { console.log("error connecting to websocket server: ", error); }); ros.on("close", function() { console.log("connection to websocket server closed."); }); }, // *** 追加 ここから *** // call: function () { addTwoIntsClient.callService(request, function(result) { console.log('Result for service call on ' + addTwoIntsClient.name + ': ' + result.sum); }); }, // *** 追加 ここまで *** // } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> rospy_tutorialsのadd_two_serverを実行するとサービスのコールを確認できます。標準では入っていないと思うので別途インストールしてください。 4.最後に vueでrosトピックのpublish,subscribeとサービスのコール方法を記載しました。 興味のある方はお試しください。 5.参考 スマホアプリでROSのUIを作る場合はFlutterがおすすめらしい(ロボットにスマホ乗せる場合とか良さそう) roslib JavaScriptでの使用方法
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.js よく使うディレクティブとコンポーネント 簡単

Vue.js [3]の学習備忘録 Vue.jsをインストール ディレクティブを学ぶ v- で始まる特別な属性のこと derective(司令)という名前の通り、Vue.jsに何らかの指示を行う仕組み (ディレクティブ例) v-bind(属性のデータバインディング) v-if(条件分岐) v-for(オブジェクトの繰り返し描画) v-on(イベント処理) v-model(双方向データバインディング) コンポーネント 名前付きの再利用可能なインスタンス ページを構成するUI部品 テンプレートとそのロジックから構成 よく使うコンポーネント化 →再利用性が高くなる →コードの見通しが良くなる ===> 開発効率UP!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue serve しようと思ったら digital envelope routines::unsupported が出た

はじめに エラーメッセージ Error: error:0308010C:digital envelope routines::unsupported at new Hash (node:internal/crypto/hash:67:19) at Object.createHash (node:crypto:130:10) at module.exports (/Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/webpack/lib/util/createHash.js:135:53) at NormalModule._initBuildHash (/Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/webpack/lib/NormalModule.js:417:16) at handleParseError (/Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/webpack/lib/NormalModule.js:471:10) at /Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/webpack/lib/NormalModule.js:503:5 at /Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/webpack/lib/NormalModule.js:358:12 at /Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/loader-runner/lib/LoaderRunner.js:373:3 at iterateNormalLoaders (/Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/loader-runner/lib/LoaderRunner.js:214:10) at Array.<anonymous> (/Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/loader-runner/lib/LoaderRunner.js:205:4) at Storage.finished (/Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:55:16) at /Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:91:9 at /Users/~~~~~~~/.nvm/versions/node/v17.1.0/lib/node_modules/@vue/cli-service-global/node_modules/graceful-fs/graceful-fs.js:123:16 at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3) { opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ], library: 'digital envelope routines', reason: 'unsupported', code: 'ERR_OSSL_EVP_UNSUPPORTED' } Node.js v17.1.0 調査 Node を v17.0.1 にアップデートし、cliでプロジェクトを作って、vue serveをしたら出てきてしまうらしい。 https://github.com/vuejs/vue-cli/issues/6770 https://github.com/webpack/webpack/issues/14532 OpenSSLのバージョンが3.0になったことに起因している問題みたいですね。 https://medium.com/the-node-js-collection/node-js-17-is-here-8dba1e14e382 対策 If you hit an ERR_OSSL_EVP_UNSUPPORTED error in your application with Node.js 17, it’s likely that your application or a module you’re using is attempting to use an algorithm or key size which is no longer allowed by default with OpenSSL 3.0. A new command-line option, --openssl-legacy-provider, has been added to revert to the legacy provider as a temporary workaround for these tightened restrictions. OpenSSL3.0が使われる前に用いられていたもの(プロバイダー?)に戻すオプションがあるので、一時的にはこれを使うのがいい。 export NODE_OPTIONS=--openssl-legacy-provider いけたぁ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

親コンポーネントからv-imgへsrc属性を渡すための書き方

Vuetifyに限らず、propsや属性等をいろいろ書く場合、一度ラップした上でそのラッパーの方を使い回すのが効率的だと考えられます。 それをv-imgでもやろうとしたときの記録です。 コンポーネント構造 components └── Common └── Img.vue // v-imgをラップしている └── Example └── Parts └── Img.vue // Common/Img.vueをラップしている └── Icon.vue // Example/Parts/Img.vueをラップしている 方法 /Common/Img.vue <template> <v-img aspect-ratio="1" v-bind="$attrs" > <template v-slot:placeholder> <v-row class="fill-height ma-0" align="center" justify="center" > <v-progress-circular indeterminate color="grey lighten-5" ></v-progress-circular> </v-row> </template> </v-img> </template> /Example/Parts/Img.vue <template> <CommonImg :src="$attrs" /> </template> /Example/Icon.vue <template> <ExamplePartsImg :src="image_src" /> </template> <script> export default { data() { return { image_src: require("@/assets/img/tagicons/nuxt.js.svg"), } } } </script> 大元でv-bind="$attrs"とし、ラッパーではv-bind:src="$attrs"として値を受ける。ラッパーのラッパーではrequireで読み込んだパスをv-bind:src="$attrs"として渡す。 これを複数の属性で行う srcに加えてlazy-srcも渡したい。そういうときは、ラッパーとラッパーのラッパーをこのように編集。 /Example/Parts/Img.vue <template> <CommonImg v-bind="$attrs" /> </template> /Example/Icon.vue <template> <ExamplePartsImg v-bind="attributes" /> </template> <script> export default { data() { return { attributes: { src: require("@/assets/img/tagicons/nuxt.js.svg"), lazySrc: require("@/assets/img/tagicons/nuxt.js.svg") } } } } </script> 学んだことまとめ $attrsというプロパティは、オブジェクト形式で書いた属性をバインドさせられる。 v-imgに画像のパスを渡す場合、値としてrequireで読み込んだパスを記述することで実現できる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

npm を使用したインストールで「permission denied, access」が出た

はじまり npmでのインストールができない。 npm install -g @vue/cli  以下のようなエラーが出た npm ERR! code EACCES npm ERR! syscall access npm ERR! path /usr/local/lib/node_modules npm ERR! errno -13 npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules' npm ERR! [Error: EACCES: permission denied, access '/usr/local/lib/node_modules'] { npm ERR! errno: -13, npm ERR! code: 'EACCES', npm ERR! syscall: 'access', npm ERR! path: '/usr/local/lib/node_modules' npm ERR! } npm ERR! npm ERR! The operation was rejected by your operating system. npm ERR! It is likely you do not have the permissions to access this file as the current user npm ERR! npm ERR! If you believe this might be a permissions issue, please double-check the npm ERR! permissions of the file and its containing directories, or try running npm ERR! the command again as root/Administrator. npm ERR! A complete log of this run can be found in: npm ERR! /Users/〜〜〜〜〜〜〜/.npm/_logs/2021-11-27T03_37_32_265Z-debug.log 対策 同じような問題に遭遇した記事を発見 https://qiita.com/okohs/items/ced3c3de30af1035242d 公式ドキュメントにもエラーの対処法がある https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally どうやらさnodejsを再度インストールするのが推奨らしい 再インストールする しっかり記事を読まずに再インストールしたらうまくいかなかった この記事参考にしてアンインストールし、普通にインストールし直した。 https://qiita.com/nanbuwks/items/7d1baa3b06b7af169330 もう一度試す node:internal/bootstrap/switches/does_own_process_state:126 cachedCwd = rawMethods.cwd(); ^ Error: ENOENT: no such file or directory, uv_cwd at process.wrappedCwd (node:internal/bootstrap/switches/does_own_process_state:126:28) at process.cwd (/usr/local/lib/node_modules/npm/node_modules/graceful-fs/polyfills.js:10:19) at new Config (/usr/local/lib/node_modules/npm/node_modules/@npmcli/config/lib/index.js:92:19) at new <anonymous> (/usr/local/lib/node_modules/npm/lib/npm.js:83:19) at Object.<anonymous> (/usr/local/lib/node_modules/npm/lib/npm.js:71:30) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) { errno: -2, code: 'ENOENT', syscall: 'uv_cwd' } なんだこれ... ターミナル再起動してもう一度実行 とりあえずエラーメッセージ貼り付けてググってみたら、npmではないけれど、似たようなエラーの出てきている人がいた。ターミナル立ち上げ直したら動いたらしいのでやってみる。 https://teratail.com/questions/67522 npm notice npm notice New patch version of npm available! 8.1.0 -> 8.1.4 npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.1.4 npm notice Run npm install -g npm@8.1.4 to update! npm notice npm ERR! code EACCES npm ERR! syscall mkdir npm ERR! path /usr/local/lib/node_modules/@vue npm ERR! errno -13 npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/@vue' npm ERR! [Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/@vue'] { npm ERR! errno: -13, npm ERR! code: 'EACCES', npm ERR! syscall: 'mkdir', npm ERR! path: '/usr/local/lib/node_modules/@vue' npm ERR! } npm ERR! npm ERR! The operation was rejected by your operating system. npm ERR! It is likely you do not have the permissions to access this file as the current user npm ERR! npm ERR! If you believe this might be a permissions issue, please double-check the npm ERR! permissions of the file and its containing directories, or try running npm ERR! the command again as root/Administrator. npm ERR! A complete log of this run can be found in: npm ERR! /Users/matsuokahikaru/.npm/_logs/2021-11-27T03_53_56_693Z-debug.log また似たようなエラーが。ここで、安直にインストールし直してもダメなのだと痛感し、ちゃんと調べることにした。 公式ドキュメント読んでインストールし直す どうやらnvmを使ってnodeとnpmをインストールすると、permissionの問題は回避できるらしいので、nvmをインストールする。 ソース https://github.com/nvm-sh/nvm#installing-and-updating Readmeに書いてあるコマンドを実行 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash nvm -v command not foundが出ました。以下のコマンドを実行したら無事動きました。 source ~/.bash_profile npmをインストールする nvm install stable --latest-npm npm install -g @vue/cli  いけたぁ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

yarn installでエラーが出た件

今回、個人開発している方のお手伝いでVueを使用することになり、環境構築時のyarn installでエラーとなってしまいました。 その際に解決策として行ったことを記録として残しておこうと思います。 開発環境 PC:MacBook エディター:VSCode 以前一度Reactの環境構築を行っているので、Nodeはインストールされていました。 エラー発生時の状況 GitHubからダウンロードしたソースコードを開く。 下記のコマンドを実行 $yarn install しかし下記のエラーとなり失敗しました。 The engine "node" is incompatible with this module. Expected version "^10.13.0 || ^12.13.0 || ^14.17.0 || >=15.0.0". Got "14.16.1" 02 error Found incompatible module. 03 info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command. nodeのバージョンが非互換であるので、互換性のあるnodeをインストールしてくださいとのこと。 対処 互換性のあるNodeのインストール 下記のコマンドを実行して互換性のあるnodeをインストールしました。 $node install 14.17.0 Nodeのバージョンを確認 $node -v v14.16.1 あれ?バージョンが変わっていない・・・ 使用するNodeの切り替えコマンド実施 $nodebrew use 14.17.0 その後、バージョンを確認 $node -v 14.17.0 バージョンが切り替わったことを確認しました。 しかしyarn installでのエラーの状況は変わらず下記のまま・・・ The engine "node" is incompatible with this module. Expected version "^10.13.0 || ^12.13.0 || ^14.17.0 || >=15.0.0". Got "14.16.1" 02 error Found incompatible module. 03 info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command. 3.パスを通す ググったところ、パスを通す処理をしていませんでしたので下記を実行。 ~/.zshrcに下記の記載を追記し手保存します。 ~/.zshrc export PATH=$HOME/.nodebrew/current/bin:$PATH 下記のコマンド実行 source ~/.zshrc これでyarn install 実行 インストールが出来たことを確認! yarn serveコマンドを実行し、デバッグ環境が出来たことを確認しました。 参考サイト 参考qiita yarn実行時に「 The engine “node” is incompatible with this module.」エラーが発生した場合の対処方法
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TypeScriptでHTMLElementのstyleプロパティの型を指定する方法

結論 DOMのstyleを動的に変えたい時に let someElementStyle:Partial<CSSStyleDeclaration>; と指定することで、エディタによる補完や型チェックの恩恵を得ることができる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-forにkey属性をバインディングしないとどうなるのかやってみた

下記のコードでコメントアウトしている部分、 :key="hoge"のバインディングはなぜ必要なのか調べてみました。 (てか、そんなの無くても良いのでは?と思ってた) <table class="table table-bordered text-center"> <thead class="thead-dark"> <tr> <th>No.</th> <th>項目</th> <th>入力欄</th> </tr> </thead> <tbody> <tr v-for="profile in profiles" :key="profile.id"> //←このkey要る?? <td>{{ profile.id }}</td> <td>{{ profile.question }}</td> <td><input type="text"> <button class="btn btn-danger" @click="deleteRow(index)">項目削除</td> </tr> </tbody> 結論 keyをバインディングせずにinputタグと削除処理が組み合わさると意図しない挙動になる。 どういった挙動になるのか。 例えば、出会い系アプリの登録画面があったとして(ちなみにやったことない) よっしゃ入力終わった〜。 あ、でも出身バレたくないから項目ごと削除しよう〜。 でカチっと押すと、こうなる↓ 一言で自分を表すと「ボンキュボン」..!! え、おわた。。ってなります。 削除処理が終わって再度レンダリングするときに:key属性を一意の値にしておかないと Vueは一番コストが低い方法で再描画しようとして、input要素を消してくれないようです。スピードを求めておかしなことなっとるやん。 Vue.jsの公式もこう言ってるので素直に、key属性はつけましょう。 https://jp.vuejs.org/v2/guide/list.html#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%A8-v-for
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む