[ Vue ]データバインディング・双方向データバインディングとは

Vueを形成している超重要な概念であるデータバインディング・双方向データバインディングについて理解されているでしょうか。理解せずとも、感覚的に使っていらっしゃる方もいるかと思います。

データバインディングは様々な記事でも紹介されいています。
今回は、データバインディングのデータの流れをVue.js Devtoolsを用いながら確認していきます。

Q.データバインディングとは

データ操作 → データ描画を同期的に処理してくれる機能のことです。

データバインディングでは無い状態とは。例えば、jQueryでのDOM操作は基本的にはデータバインディングとは言えません。

 var word = "Hello"
 var wordEl = $("#word")
 var buttonEl = $("button")
 wordEl.text(word)
 buttonEl.on("click", function(){
   word = "クリックされた"
   wordEl.text(word) // ①
 })

①:wordEl.text(word) // ここで、反映処理実行することによって描画を実行しています。

この様にデータ変更と描画処理が同期していない場合はデータバインディングとは言いません。

Q.Vueのデータバインディングする処理を実行

では、Vue.jsにてデータバインディングを実施していきます。

v-bindを利用します。

<template>
  <div>
    <div>
      <p>Label:</p>
      {{ bind1 }}
      <p>Input:</p>
      <p>
        <input type="text" v-bind:value="bind1">
      </p>
    </div>
  </div>
</template>

<script>

export default {
  data () {
    return {
      bind1: "データバインディング",
    }
  },
}
</script>

変数:bind1のデータが → 描画されいているのが分かるかと思います。

Q.同期処理されている?

データバインディングが同期処理されていることを体感していきます。

Devtoolsからbind1 の変数を操作してみます。

するとbind1の変更に応じて同期的に描画されました。

Q.双方向データバインディングとは.

データバインディングとは、
・データ操作 → データ描画を同期的処理してくれる機能

対して、
双方向データバインディングとは、
・データ操作 → データ描画を同期的処理してくれる機能

・データ描画 → データ操作を同期的処理してくれる機能

というデータ描画とデータ操作が両方向で同期処理を実現してくれる機能です。

Q.Vueの双方向データバインディングする処理を実行

v-modelにて、双方向 データバインディングを確認していきます。

<template>
  <div>
    <div>
      <p>Label:</p>
      {{ bind1 }}
      <p>Input:</p>
      <p>
        <input type="text" v-bind:value="bind1">
      </p>
      <p>Label:</p>
      {{ bind2 }}
      <p>Input:</p>
      <p>
      <input type="text" v-model="bind2">
      </p>
    </div>
  </div>
</template>

<script>

export default {
  data () {
    return {
      bind1: "データバインディング",
      bind2: "双方向data-bind",
    }
  },
}
</script>

ここまででは、データバインディングとの違いは分からないかと思います。

input:データ内を変更していきます。
bind1のinput、bind2のinput両方変更することによってデータバインディング、双方向データバインディングの違いが鮮明になります。

bind1
inputを変更しましたが、data -> bind1は変更されていません。よって、Labelの値も「データバインディング」のままです。

対して

bind2
inputの変更をしたとろこ、data -> bind2 も同期的に変更されています。 よって、Labelの値も同期的に変更されています。

このように、Vue の dataをViewから同期的に変更できるのが双方向データバインディングの特徴です。

※リロードすると、data()で設定している値に戻ります。

Vue.js学び始めのエンジニアがStoreへの理解を共有

今回の投稿に関しては、誤りも含まれている可能性があります。
Vueを学び初めて間もないため、理解不足な点があると思います。それでも、あえて記述しておきたいのは、理解が浅いからこそ湧いてくる疑問が結構あると思ったからです。 もしかすると、他の初学者の方も似た疑問にぶつかっている可能性もあるかな?と思います。理解を深めていく一助になればと思い残しておきます。

Q:Storeとは.

Vueアプリケーションのどこからでもアクセス出来るデータ保管/データ処理できる仕組み.

正式な解説はこちら

Q:何のためにStoreが存在するのか.

アプリケーション全体で管理するほうが効率的なデータを管理するため.例えば、ユーザーの認証情報など.

正式な解説はこちら

Q:Storeのもつ機能

state, getters, mutations, actionsというメソッドがある。

state:Storeで保持したいデータ

getters:stateの算出プロパティ

mutations:stateを変更可能なメソッド

actions:非同期処理に対応したメソッド ※多くの場合非同期処理実行後に、mutationsのメソッドを実行

Q:Storeの使い方

正式な解説は

https://vuex.vuejs.org/ja/guide/state.html

適当で簡素なStoreを用いた処理

coming soon

[Vue.js/Nuxt] Storeを複数作成した場合のデータアクセス方法

分かりにくい標題で申し訳ありません。
Storeを利用する場合は、
Storeディレクトリにindex.jsファイルを作成して、state, getters, mutations, actionsを記述していくかと思います。

しかし、index.js以外の情報をStoreで保持したい場合はどうでしょうか。Storeで複数ファイルを利用する方法と、データアクセス方法について解説していきます。

Storeディレクトリの配下を下記とします。 
※me.jsは認証ユーザーの情報を保持するStoreとします。

/* 省略 */
Store
  L index.js
  L me.js

①:stateへのアクセス

まずは、stateへのアクセスについて見ていきたいと思います。

index.jsのstate
export const state = () => ({
    txt: 'texttext',
  })
// state以外省略
me.jsのstate
export const state = () => ({
  id: 0,
  name: 'taro',
  email: 'taro@gmail.com',
  })
// state以外省略

consoleで確認していきます。

任意のComponent内で、下記consoleを実施して下さい。

console.log(store.state);

結果は下記が出力されます。

me: (...)
txt: "texttext"

これは何が出力されたのでしょうか。
ドリルダウンしてme: (…)の中身をクリックしてみると。下記が表示されます。

me: Object
id: 1
name: "taro"
email: 'taro@gmail.com',

つまり、console.log(store.state);はStoreに保持している全てのstateを出力しました。しかし、index.jsファイルと、me.jsファイルではアクセス方法が少し異なります。

①-1;me.jsのstateをダイレクトにアクセス

次に、me.jsのstateをダイレクトにアクセスしてみます。下記のconsoleを呼び出して下さい。

console.log(store.state.me);

結果は下記です。 単純ですね。

id: 1
name: "taro"
email: 'taro@gmail.com',

②:actions, mutationsへのアクセス

それでは、他のメソッドについても見ていきます。

me.jsにてactions, mutationsを定義していきます。

  export const mutations = {
    setMe(state, payload) {
      state.id = payload.id
      state.name = payload.name
    },
  }
  
  export const actions = {
    async setMeActions({ commit, state }, payload ) {
        // console.log(state);
        commit('setMe', payload)
    },
  }

任意のComponent内から、me.js内のactions, mutationsへアクセスする方法は下記です。

store.dispatch('me/setMe' ,payload )
store.commit('me/setMeActions' ,payload )

Vue.jsのemitで複数のデータを送受信する方法

メモ書きになってしまいます。

複数データを送る:子 Componet の<script>

<script>
export default {
  data() {
    return {
      email: "",
      password: "",      
    };
  },  
  methods: {
    onSubmit() {      
      this.$emit('formSubmit', 
                  {
              email: this.email,
              password: this.password,
            });
    },
    onInputEmail(e) {
      this.email = e.target.value;
    },
    onInputPassword(e) {
      this.password = e.target.value;
    },
  },
</script>

複数データ受け取る:親

<template>
//省略
      <SimpleForm @formSubmit="onSubmit"/>
//省略
</template>


<script>
import SimpleForm from "./components/SimpleForm.vue"

export default {
  name: 'App',
  components: {
    SimpleForm,
  },
  methods: {
    onSubmit({email, password}) {

      console.log(email)
      console.log(password)

//dataでemail, passwordを作る必要なし.
      this.msg = "//email:" + email + "//password:" + password;
    }
  },
  data() {
    return {
      msg: 'Emai/Passwordを反映',
    }
  },
}
</script>

【超初学者向け】Vue.jsでデータを親子で送受信

Vue.jsを触り初めて2日目です。 結構苦戦しています。
データのやり取りがイメージが曖昧なことが影響しているかと思います。

formデータを 子 Component → 親Component 渡す方法を紹介します。
ただし、記述方法としては、ベストなものではないです。 それでも、無理矢理にでもデータを受け渡すことで、Vue.jsの肌触り感に慣れていける方が重要かなと思っています。

①: emitの理解

②:子のComponet<Input>データを親に渡す

最初のSTEPとして、Componet<Input>データを親に渡してみます。

App.vue
<template>
  <div id="app">

       <!-- Componetの呼び出し && parentMethodでComponentのemitからのデータを受け取る -->
      <InputData class="input-data" @input-data="parentMethod"/>

       <!-- Inputで入力されたデータがリアルタイムで反映 -->
      <div>
        {{ this.input_data_single }}        
      </div>

  </div>
</template>

<script>
import InputData from "./components/InputData.vue"

export default {
  name: 'App',
  components: {
    InputData,
  },
  methods: {
    parentMethod(e){
      console.log(e);
      this.input_data_single = e;
    },
  },
  data() {
    return {
      input_data_single: '',
    }
  },

}
</script>

<style>
/* 省略 */
</style>

InputData.vue ( 子 Componet )
<template>
  <div>
    <input type="text" :value="value" @input="childMethod">
  </div>
</template>

<script>
export default {
  methods: {
    childMethod(e) {
      console.log(e.target.value);
      this.$emit('input-data', e.target.value);
    },
  },
  data() {
    return {
      value: "",      
    };
  },
};
</script>

<style>
/* 省略 */
</style>

Docker環境構築 / Vue.jsをさくっと起動させるまで.

ディレクトリ構成

/Vue-Test
 L Dockerfile
 L docker-compose.yml

①:Dockerfile/docker-compose ファイルを準備

①-1:Dockerfile
FROM node:17-alpine3.14

WORKDIR /work

RUN apk update && \
    npm install -g npm && \
    npm install -g @vue/cli

EXPOSE 8080
ENV HOST 0.0.0.0
①-2:docker-compose.yml
version: '3'
services:
  vue:
    container_name: vue
    build: 
      context: .    
      dockerfile: ./Dockerfile
    ports:
      - "8080:8080"
    volumes:
      - ./server:/work:delegated      
    tty: true

②:docker コンテナの起動

②-1:ディレクトリに移動

cd Vue-Test

②-2:コンテナ起動

docker-compose up -d

③:コンテナに入り、Vueプロジェクトを作成

③-1:コンテナへ移動

docker-compose vue exec vue sh

③-2:Vueプロジェクトを作成

first-app 名称でプロジェクトを作成

vue create first-app

③-3:Vueのバージョンを選択

Default ([Vue 3] babel, eslint) 
❯ Default ([Vue 2] babel, eslint) 

③-4:package manageを選択

Use Yarn 
❯ Use NPM

これでインストールが開始します。

④:プロジェクトの起動

④-1:プロジェクトへ移動

cd first-app

④-2:serve

npm run serve

⑤:ブラウザで確認

下記へアクセスして、確認して下さい。

http://localhost:8080/