- 投稿日:2020-06-28T20:14:43+09:00
【Vue Rails】Vue + Railsで"Hello Vue!"表示
Vue + Railsアプリ作成
◆ Railsアプリ作成
// "-webpack=vue"オプションでVue.js使用可能 $ rails new <アプリケーション名> -webpack=vue◆ model作成
// カラム名:name データ型:text $ rails g model sample name:text◆ migrationファイル編集(Hello.Vue!表示には不要)
db/migrate/20200627045139_create_sample.rbclass CreateSample < ActiveRecord::Migration[6.0] def change create_table :sample do |t| t.text :name, null: false, default: "" end end end◆ マイグレーション
$ rails db:create //データベース作成 $ rails db:migrate //マイグレーション実施◆ controller作成
app/controllers/home_controller.rbclass HomeController < ApplicationController def index end end◆ routes.rb編集
config/routes.rbRails.application.routes.draw do root to: 'home#index' end◆ index.html.erb編集
app/views/home/index.html.erb<%= javascript_pack_tag 'hello_vue' %> <%= stylesheet_pack_tag 'hello_vue' %>◆ hello.vue.js(デフォルトで設定済)
app/javascript/packs/hello_vue.jsimport Vue from 'vue' import App from '../app.vue' document.addEventListener('DOMContentLoaded', () => { const el = document.body.appendChild(document.createElement('hello')) const app = new Vue({ el, render: h => h(App) }) console.log(app) })◆ app.vue(デフォルトで設定済)
app/javascript/app.vue<template> <div id="app"> <p>{{ message }}</p> </div> </template> <script> export default { data: function () { return { message: "Hello Vue!" } } } </script> <style scoped> p { font-size: 2em; text-align: center; } </style>備忘録
◆ before_action
- メソッドを定義して、
before_action
にセットするlogin_controller.rbclass LoginController < ApplicationController before_action :set_answer def set_answer @sample = "Hello World!" end end◆ rescue_from
例外処理
。エラー処理を行う画面を設定するapp/controller/application_controller.rb
に記述するapp/controller/application_controller.rbclass ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, with: :rescue404 end遭遇したエラー
◆ エラー内容①
Webpacker::Manifest::MissingEntryError in Home#index解決策:Webpackインストール
$ yarn $ bin/yarn $ webpack $ webpack◆ エラー内容②
Error: vue-loader requires @vue/compiler-sfc to be present in the dependency tree.解決策:vue-loaderダウングレード
$ npm remove vue-loader $ npm install --save vue-loader@15.9.2 $ yarn add vue-loader@15.9.2◆ エラー内容③
Sprockets::Rails::Helper::AssetNotFound in Home#index <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>解決策:app/views/layouts/application.html.erb編集
app/views/layouts/application.html.erb<!-- javascript_include_tagの行を削除 --> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>参考文献
- 投稿日:2020-06-28T17:45:41+09:00
【Vue.js】Scoped CSSのscoped具合を検証してみた
Vue.jsのScoped CSSは完全にはscopedじゃない、という話を聞いたので検証してみました。
結果、コンポーネント最上位の要素と、slotについては気をつける必要があることが分かりました。参考記事
親コンポーネントのstyleが子コンポーネントに影響を与える仕組みは、以下が詳しいです。
- https://qiita.com/wintyo/items/dfc232255ad45fdf376f
- https://www.dkrk-blog.net/javascript/vue_scopedcss
検証環境
- OS: macOS Catalina 10.15.5
- ブラウザ: Google Chrome 83.0.4103.116(Official Build)(64bit)
- Vue.js: 2.6.11
検証1: 素朴にstyleを当てた場合
親、子、孫コンポーネントにそれぞれ違った色を割り当てました。
すると、各コンポーネントの最上位の要素には親コンポーネントのスタイルが適用されてしまいました。
Parent.vue<template> <div class="root-div"> this is root div of parent <h1 class="my-title">this is h1 of parent</h1> <div class="h2-container"> <h2>this is h2 of parent</h2> </div> <Child /> </div> </template> <script lang="ts"> import Vue from "vue"; import Child from "@/components/Child.vue"; export default Vue.extend({ name: "Parent", components: { Child, }, }); </script> <style scoped lang="scss"> .root-div { color: red; } .my-title { color: red; } h2 { color: red; } </style>Child.vue<template> <div class="root-div"> this is root div of child <h1 class="my-title">this is h1 of child</h1> <div class="h2-container"> <h2>this is h2 of child</h2> </div> <GrandChild /> </div> </template> <script lang="ts"> import Vue from "vue"; import GrandChild from "@/components/GrandChild.vue"; export default Vue.extend({ name: "Child", components: { GrandChild, }, }); </script> <style scoped lang="scss"> .root-div { color: blue; // こいつが効いていない } .my-title { color: blue; } h2 { color: blue; } </style>GrandChild.vue<template> <div class="root-div"> this is root div of grandchild <h1 class="my-title">this is h1 of grandchild</h1> <div class="h2-container"> <h2>this is h2 of grandchild</h2> </div> </div> </template> <script lang="ts"> import Vue from "vue"; export default Vue.extend({ name: "GrandChild", }); </script> <style scoped lang="scss"> .root-div { color: green; } .my-title { color: green; } h2 { color: green; } </style>
検証2: 全称セレクタ(*)を使った場合
*
を使って乱暴にstyleを指定した場合どうなるかを見てみました。
結果、検証1と同じく、各コンポーネント最上位の要素だけは親コンポーネントのstyleの影響が出ました。
※検証1のコードから、Child.vueだけ変更しました。
Child.vue<template> <div class="root-div"> this is root div of child <h1 class="my-title">this is h1 of child</h1> <div class="h2-container"> <h2>this is h2 of child</h2> </div> <GrandChild /> </div> </template> <script lang="ts"> import Vue from "vue"; import GrandChild from "@/components/GrandChild.vue"; export default Vue.extend({ name: "Child", components: { GrandChild, }, }); </script> <style scoped lang="scss"> .root-div * { color: blue; } * { color: blue; } * * { color: blue; } </style>
検証3: globalのcssがある場合
当たり前ですが、ページ全体に適用されているcssがある場合、競合します。
例えば、ページ全体に* { color: black!important }
を当てたら、すべて黒になります。
App.vue<style lang="scss"> * { color: black!important; // プロダクトコードで書いたら殴られるやつ } </style>
もちろん、!important
を付けなければ、コンポーネント内のcssが優先的に適用されます。
(この辺はScoped CSSというよりはCSSそのものの話)
App.vue<style lang="scss"> * { color: black; } </style>
検証4: slotを使った場合
slotを使って、親から子へタグを渡した場合、渡したタグには親コンポーネントのstyleが適用されました。
Parent.vue<template> <div class="root-div"> this is root div of parent <h1 class="my-title">this is h1 of parent</h1> <div class="h2-container"> <h2>this is h2 of parent</h2> </div> <Child> <!-- 親からタグごとslotを挟むと、親のstyleが適用される --> <template #my-slot> <p>slot: this is p of parent</p> <div> <h2>slot: this is h2 of parent</h2> </div> </template> </Child> </div> </template> <script lang="ts"> import Vue from "vue"; import Child from "@/components/Child.vue"; export default Vue.extend({ name: "Parent", components: { Child, }, }); </script> <style scoped lang="scss"> .root-div { color: red; } .my-title { color: red; } h2 { color: red; } p { color: red; } </style>Child.vue<template> <div class="root-div"> this is root div of child <h1 class="my-title">this is h1 of child</h1> <div class="h2-container"> <h2>this is h2 of child</h2> </div> <slot name="my-slot"> <p>slot: this is p of child</p> <div> <h2>slot: this is h2 of child</h2> </div> </slot> <GrandChild /> </div> </template> <script lang="ts"> import Vue from "vue"; import GrandChild from "@/components/GrandChild.vue"; export default Vue.extend({ name: "Child", components: { GrandChild, }, }); </script> <style scoped lang="scss"> .root-div { color: blue; } .my-title { color: blue; } h2 { color: blue; } p { color: blue; } </style>
一方、親から子へ文字列だけを渡した場合、子のstyleが適用されました。
Parent.vue<template> <div class="root-div"> this is root div of parent <h1 class="my-title">this is h1 of parent</h1> <div class="h2-container"> <h2>this is h2 of parent</h2> </div> <Child> <!-- 親から文字列だけを渡すようにすれば、親のstyleは適用されない --> <template #my-slot-p>slot: this is p of parent</template> <template #my-slot-h2>slot: this is h2 of parent</template> </Child> </div> </template> <script lang="ts"> import Vue from "vue"; import Child from "@/components/Child.vue"; export default Vue.extend({ name: "Parent", components: { Child, }, }); </script> <style scoped lang="scss"> .root-div { color: red; } .my-title { color: red; } h2 { color: red; } p { color: red; } </style>Child.vue<template> <div class="root-div"> this is root div of child <h1 class="my-title">this is h1 of child</h1> <div class="h2-container"> <h2>this is h2 of child</h2> </div> <p><slot name="my-slot-p">slot: this is p of child</slot></p> <div> <h2><slot name="my-slot-h2">slot: this is h2 of child</slot></h2> </div> <GrandChild /> </div> </template> <script lang="ts"> import Vue from "vue"; import GrandChild from "@/components/GrandChild.vue"; export default Vue.extend({ name: "Child", components: { GrandChild, }, }); </script> <style scoped lang="scss"> .root-div { color: blue; } .my-title { color: blue; } h2 { color: blue; } p { color: blue; } </style>
で、結局何に気をつければいいのか
- コンポーネント最上位の要素になるべくstyleを当てない
- 当てざるを得ない場合、
.component-name-root { display: flex }
のように、重複しないクラス名を付けて、styleを指定する- 自前でslotを作る場合、極力DOM構造は子コンポーネント側で定義する
- デザインフレームワーク(vuetifyとか)の制約上slotにDOMを渡さざるを得ない場合は、予期せぬstyleが適用されないよう気をつける
所感
完全でないとはいえ、知らずに使っていてもそんなに気にならない程度にはscopedにできていると感じました。
個人的にはslotを使わないため、各コンポーネントの最上位のクラス名だけ気をつければ問題なし! という印象です。
Scoped CSS便利。
- 投稿日:2020-06-28T17:23:00+09:00
Rails+vue+Parcel環境でSFCのスタイルが効かなかった件
単一コンポーネントで定義したスタイルが反映されない件
Rails+vue+Parcel環境で開発をやっていた時vueのSFCで書いたスタイルが適用されない
いろいろ調べても記事はあまりなかった。
コードをしっかり確認したら解決したのでまとめてみました。解決法
CSSを読み込むヘルパーメソッドを自作する
app/helpers/application_helper.rbmodule ApplicationHelper ・・・ def javascript_pack_tag(name) javascript_include_tag(manifest["#{name}.js"]) end + def stylesheet_pack_tag(name) + stylesheet_link_tag(manifest["#{name}.vue"]) + end ・・・あとは読み込みたいスタイルがあるvueファイルを下記のように指定するだけ。
app/views/static_pages/home.html.erb<% if logged_in? %> ・・・ <div id="app"></div> <%= javascript_pack_tag 'index' %> <%= stylesheet_pack_tag '読み込みたいSFCの名前' %> ・・・なぜこれで解決するの?
npm run watch
でやっている内容は以下の通り
parcel watch app/javascripts/packs/index.html -d public/packs --public-url /packs/ --hmr-port 50000
トランスパイルしたものはpublic/packs
に入ってくる。
ここで作成されるmanifestファイルの内容は以下の通り。{ "index.html": "/packs/index.html", "index.js": "/packs/packs.e31bb0bc.js", "FeedList.vue": "/packs/packs.e31bb0bc.css", "FeedItem.vue": "/packs/packs.e31bb0bc.css" }この内容をさっきのヘルパーでは読み込んでいる。
app/helpers/application_helper.rbmodule ApplicationHelper ・・・ private def manifest @manifest ||= load end def load manifest_path = Rails.root.join('public', 'packs', 'parcel-manifest.json') if manifest_path.exist? JSON.parse manifest_path.read else {} end end endこれでマニフェストに書かれていることが読み込まれるので、先ほど作ったヘルパーメソッド(stylesheet_pack_tag)内で
stylesheet_link_tag
を使うことでrailsにCSSを読み込む!後書き
ドキュメントに沿ってコピペだけしてた部分でこうした問題があったので、しっかりコードをよもうと思いました。
- 投稿日:2020-06-28T17:01:56+09:00
File , Blob で、ファイルのエクスポート/ インポート機能とIndexedDB登録, Vue CLI版
概要
前と同様、IndexedDB + Vue CLIで
Dexie.js ライブラリを使用した構成となり。
json ファイルのエクポート、インポートの調査してみました
File API , Blob等で実現できそうでした。・インポートした jsonファイルを IndexedDB
登録まで。可能でした構成
Chrome 83
Vue CLI
dexie : 3.0.1
vue: 2.6.11
vue-router参考
File
https://developer.mozilla.org/ja/docs/Web/API/FileBlob:
https://developer.mozilla.org/ja/docs/Web/API/Blobhttp://www.tohoho-web.com/html5/file_api.html
https://qiita.com/wadahiro/items/eb50ac6bbe2e18cf8813
package.json
https://github.com/kuc-arc-f/vue_spa3b_3files/blob/master/package.json
Vue components
・json生成、エクスポート
test.vue
https://github.com/kuc-arc-f/vue_spa3b_3files/blob/master/src/components/Files/test.vuevar arr = [ {id: 1 , name: "n1"}, {id: 2 , name: "n2"}, {id: 3 , name: "n3"}, {id: 4 , name: "n4"}, {id: 5 , name: "n5"}, ]; var content = JSON.stringify( arr ); var blob = new Blob([ content ], { "type" : "application/json" });・jsonアップロード, db登録
test2.vue
https://github.com/kuc-arc-f/vue_spa3b_3files/blob/master/src/components/Files/test2.vuechange_proc: function(){ console.log("#-change_proc") var self = this var files = window.document.getElementById('file1').files; for (var i = 0; i < files.length; i++) { var file = files[i]; console.log("i: " + i ); console.log("Name: " + file.name); console.log("Size: " + file.size); console.log("Type: " + file.type); console.log("Date: " + file.lastModified); console.log("Date: " + file.lastModifiedDate); var reader = new FileReader(); reader.onload = function(evt) { console.log("State: " + evt.target.readyState); console.log("Result: " + evt.target.result); var result =evt.target.result; var dat = JSON.parse(result || '[]') self.add_item(dat) self.items = dat console.log(dat) //document.getElementById("output1").innerHTML = evt.target.result; }; reader.onerror = function(evt) { console.log(evt.target.error.name); }; reader.readAsText(file, "utf-8"); } },
- 投稿日:2020-06-28T10:46:39+09:00
Vueを複数人で開発する環境を試してみた
背景
Vue開発してると、色々ライブラリインストールとかが発生する。そんな事をしていると、複数人で開発していると、人によってインストールタイミングが違うので、結果モジュールのバージョン違ったりして将来的なトラブルの種になりそうと感じていた。なにより、production環境と開発環境が違ってくる状況になるのが一番まずい。
調べていると、Qiitaに良記事が色々あり、その問題を解消できそうだったので実際に試してみた。実現したい事
- ソースコード管理はgit
- gitに存在する設定ファイルなどの情報で、複数人が同構成環境でVueの開発が出来るように
- モジュールの変更も簡単に複数人の環境へ再現したい
- 各種モジュールのバージョンは全指定(後にインストールした人とのバージョンが違うとか無い様に)
- ホスト側で行ったソース編集をすぐに反映したい(開発モード使用したい)
ベースとなるのはこちらの記事。Dockerはこの手の環境に関する検討を1から簡単にやり直せるので、本当にすごく良いです。※最初は別記事参考にしたりしたので、細かい所で違う部分あります。
ローカルを汚さずdockerを使ってvue.jsの開発環境を作る[vuecli4]前準備
docker/docker-compose インストール
さすがにdockerはホスト側にインストールしなければいけないので、以下サイトを参考にインストール
Ubuntu 18.04にDockerをインストールする(+docker-composeも)
もちろん、OSがWinでもMacでもDockerは使えるので、開発者のOSが違っても対応できるのもDockerの良い点ですね。gitリポジトリ準備
- githubでテスト用プロジェクト作成(vueprj-test01)
- ホストでクローン(git clone https://github.com/silverbox/vueprj-test01.git)
- developブランチ準備(vueprj-test01 に移動して、
git checkout -b develop origin/master
)初期構築
docker-compose.yml, Dockerfile 準備
- ホスト側のgitリポジトリフォルダ(vueprj-test01)以下に app フォルダを準備
- コンテナ側は /app 以下に実プロジェクト作成
- nodejs用のDockerイメージは(公式サイト)、現時点でのLTSの最新版っぽい12.18.1を使う
- vue/cliとvue/cli-initは公式サイトで、現時点でのリリース最新版っぽい4.4.1を使う
vueprj-test01/docker-compose-vueini.ymlversion: '3.7' services: frontvue: build: context: . dockerfile: Dockerfile-vue ports: - 8080:8080 volumes: - ./context:/app - /app/node_modules container_name: vueprj-test01 tty: trueDockerfile-vueFROM node:12.18.1-alpine WORKDIR /app RUN apk update RUN npm install -g @vue/cli@4.4.1 RUN npm install -g @vue/cli-init@4.4.1ビルドして起動
vueprj-test01配下sudo docker-compose -f docker-compose-vueini.yml build sudo docker-compose -f docker-compose-vueini.yml up Creating network "vueprj-test01_default" with the default driver Creating vueprj-test01 ... done Attaching to vueprj-test01起動状態になった。
Vueプロジェクト作成
コンテナにログイン
bashは使えなかったのでshを使用。docker exec -it vueprj-test01 shバージョン確認。指定はちゃんと反映されてる。
コンテナ内/app # vue --version @vue/cli 4.4.1 /app # node -v v12.18.1vueプロジェクト作成(選択肢はパッケージにnpm選択した事以外はデフォルトを選択)
コンテナ内/app # vue create .
コンテナ内で開発モードで実行。/app # npm run serve
ホスト側vueprj-test01配下。変更できるように権限変更sudo chown -R ubuntu:ubuntu .この状態でホスト側コードエディタで、
vueprj-test01/app/src/App.vue
の<HelloWorld msg="Welcome to Your Vue.js App"/>
部分の文言を変更して自動的に更新される事確認。gitにpush
既に.gitignoreが作成されているので、node_modulesとか除外されてる。git add . git commit -m "base project" [develop 4ce861d] base project 13 files changed, 11687 insertions(+) create mode 100755 Dockerfile-vue create mode 100644 app/.gitignore create mode 100644 app/README.md create mode 100644 app/babel.config.js create mode 100644 app/package-lock.json create mode 100644 app/package.json create mode 100644 app/public/favicon.ico create mode 100644 app/public/index.html create mode 100644 app/src/App.vue create mode 100644 app/src/assets/logo.png create mode 100644 app/src/components/HelloWorld.vue create mode 100644 app/src/main.js create mode 100755 docker-compose-vueini.yml別の開発者を想定して環境構築
このgitリポジトリを元に別フォルダにcloneして、構築を行う。
本来は別サーバーでやりたいところだけど、dockerなのでコンテナを一回削除すればほぼ別サーバーと同じ条件になるのでそれで実験。一応再ビルドして、Dockerコンテナ起動。
コンテナ削除して、新フォルダ作成。そしてそのフォルダ以下で構築。
~/vueprjtest/vueprj-test01$ sudo docker-compose -f docker-compose-vueini.yml rm ~/vueprjtest/vueprj-test01$ mkdir ~/vueprjtest2 ~/vueprjtest/vueprj-test01$ cd ~/vueprjtest2 ~/vueprjtest2/vueprj-test01$ git clone https://github.com/silverbox/vueprj-test01.git ~/vueprjtest2/vueprj-test01$ cd vueprj-test01 ~/vueprjtest2/vueprj-test01$ sudo docker-compose -f docker-compose-vueini.yml build ~/vueprjtest2/vueprj-test01$ sudo docker-compose -f docker-compose-vueini.yml up再度コンテナ内に入る。この状態では、コンテナに標準にインストールされている部分以外は無い状態。ただ、gitにはpackage.json,package-lock.jsonが上がっているので、コンテナ内から見える状態になっている。npm install でそれを反映。そして開発モードで実行。
コンテナ内npm install npm run serve
同様に、ホスト側の新フォルダ配下、
vueprj-test01/app/src/App.vue
の<HelloWorld msg="Welcome to Your Vue.js App Test"/>
部分の文言を変更して自動的に更新される事確認。ライブラリ追加
別開発者がライブラリを追加した事想定。ついでに、先は手動で行った処理を加える(本来は最初のgit push時に反映しておくべき)。
Dockerfile-vue:element-uiとaxios追加FROM node:12.18.1-alpine WORKDIR /app COPY app/package.json . COPY app/package-lock.json . RUN apk update RUN npm install -g @vue/cli@4.4.1 RUN npm install -g @vue/cli-init@4.4.1 RUN npm install RUN npm install --save element-ui@2.13.2 RUN npm install --save axios@0.19.2main.jsでaxiosを宣言して代入してみる。import Vue from 'vue' import App from './App.vue' import axios from 'axios' Vue.config.productionTip = false Vue.prototype.$axios = axios; new Vue({ render: h => h(App), }).$mount('#app')再ビルドsudo docker-compose -f docker-compose-vueini.yml rm sudo docker-compose -f docker-compose-vueini.yml build sudo docker-compose -f docker-compose-vueini.yml upそして、
http://localhost:8080
でページが動く事確認。結論
.gitignore
とかはちゃんとvue create
で作ってくれる。- ライブラリ管理も
package.json,package-lock.json
で管理されて、それがnpm install
で再現される。- なのでpackage.jsonが作られるまでの準備のDockerfileと、それ以後のDockerfileは分ける。
- ライブラリ変わったら別開発者はコンテナ再作成か、コンテナ内でnpm installすればよさそう。
はまったポイント
最初、
vue init webpack .
でvueプロジェクト作成をしていた。
しかし、http://localhost:8080/
でアクセス出来る事を確認する時にどうもうまく行かない。そんな事を色々調べていたら、以下の神ページを発見。
vue-cli のテンプレートを Docker で動かす時の注意
config/index.js を変えなくてはいけない、というか、vue init webpack .
は古い形式らしい事も知る。
書かれている通り、localhost部分を0.0.0.0にしたらホストからアクセスできるようになった。動作したとはいえ、きれいな環境を目指しているのでvueプロジェクト作成やり直し。
ホスト側vueprj-test01配下。Ctrl+Cでdocker-composeを止める。sudo docker-compose -f docker-compose-vueini.yml rm rm -r app mkdir app sudo docker-compose -f docker-compose-vueini.yml up
環境構築も簡単にやり直せるのがDockerの良い所ですね。
ちなみにこの変更で開発モード実行コマンドも
npm run dev
からnpm run serve
変わったらしい。configがdevとproで分かれたりもしてない?取り急ぎ今回は、目的とは違う部分なので気にしない事に。参考にさせて頂いたサイト
Ubuntu 18.04にDockerをインストールする(+docker-composeも)
ローカルを汚さずdockerを使ってvue.jsの開発環境を作る[vuecli4]
Vue.jsの開発環境をDockerで構築する手順
vue-cli バージョン指定してインストールする
vue-cli のテンプレートを Docker で動かす時の注意
- 投稿日:2020-06-28T03:38:09+09:00
【Vue】オブジェクトを変更したい時どうするか?
Vueのオブジェクトの変更方法をまとめ
Vueの
data()
にあるオブジェクトについての話。取得は通常のJSのオブジェクトの操作と同様にキーを使えば問題なかったが、
追加と削除で嵌ったので備忘録として残しておく。以下、参考にしたページ
次のようなVueインスタンスの
data()
にcharObj
という空のオブジェクトがセットしてあるとする。export default { data () { return { charaObj: {} } } }プロパティを追加する
プロパティを追加したい時、通常のJSのオブジェクト同様
obj.anyKey = anyVal
とやってしまいたくなるがこれだとリアクティブにデータが反映されない(=データ更新してもテンプレート(画面)上に反映されない)ので、ダメということらしい。// リアクティブにデータが反映されないのでこの書き方はダメ this.charaObj.hero = '範馬刃牙'プロパティを追加したい時は
$set
を使う。
慣れない書き方だが、これでリアクティブにプロパティを追加できる。
第1引数にオブジェクトを、第2引数にキー、第3引数に値を渡す。// リアクティブになるやつ this.$set(this.charaObj, 'hero', '範馬刃牙')プロパティをまとめて追加したい
スプレッド演算子
...
を使って追加したいプロパティを含むオブジェクト内で展開すればいい。this.charObj = {...this.charObj, parent: '範馬勇次郎', friend: '烈海王'}または
Object.assign()
を使って新しいオブジェクトを作って代入する方法でもできるらしい。this.charaObj = Object.assign({}, this.charaObj, {parent: '範馬勇次郎', friend: '烈海王'})プロパティを削除する
追加の時と同じで、いつも通りに削除しようとするとリアクティブにならない。
// リアクティブにデータが反映されないのでこの書き方はダメ delete this.charaObj.heroプロパティを削除したい時は
$delete
を使う。第1引数に対象のオブジェクトを、第2引数に削除したいプロパティのキーを渡す。// リアクティブになるやつ this.$delete(this.charaObj, 'hero')全削除したい
最初、空のオブジェクトを再代入で初期化できないかと考えたが、うまくいかなかった。
// 再代入はうまくいかない this.obj = {}この場合は、キーの配列を
Object.keys()
で取得してループでdelete
を使って削除したところうまくいった。// プロパティを全削除 Object.keys(this.charObj).forEach(key => { this.$delete(this.charObj, key) })リアクティブにVueインスタンスのデータを削除するには先に書いた
$delete
を使う。プロパティを全て入れ替えたい
オブジェクトを一度空にしてからまとめて追加すればよい
オブジェクト自体を削除したい
あまり使うケースは無さそうだが、プロパティではなくオブジェクト自体(Vueインスタンスのトップレベルのプロパティ)を削除したい場合はどうするか?
$delete
を使いたくなるところだが、トップレベルのを削除する時は
$delete
を使おうとすると警告が出るので使っちゃダメっぽい。// トップレベルのプロパティを削除しようとエラーが出る this.$delete(this, 'charObj')この場合は
null
を入れればよいみたい。// charObjを削除する this.charObj = null