October 23, 2021

Data flow VueJS ( Phần 1)

Hi các bạn,
Như ở bài trước của VueJS, ta đã tìm hiểu về component của VueJS rồi nhé 😀
Hôm nay chúng ta sẽ qua cách trao đổi data giữa các component của VueJS – Data flow trong VueJS Component.

Props và emit

Một application chúng ta sẽ chia ra làm nhiều component cha và con khác nhau. Trường hợp không có quá nhiều component thì props và emit sẽ là trợ thủ đắc lực của chúng ta.

Vậy thì khi nào chúng ta nên sử dụng props và emit:

  • Khi truyền dữ liệu từ parent xuống child, chúng ta sẽ sử dụng props, và ngược lại thì sẽ là emit.
  • Không sử dụng với các ứng dụng lớn, có quan hệ giữa các component rối rắm.
  • Và đặc biệt là dễ hiểu, và dễ sử dụng.

Bên cạnh đó chúng ta còn có cách khác, nhưng mình không khuyến khích sử dụng. Thay vì dùng props chúng ta sẽ dùng Reference, và với emit thì sẽ là Parent property.

Sau đây chúng ta sẽ có một demo đơn giản như sau

//Đầu tiên chúng ta sẽ truyền dữ liệu name từ parent tới child là "Dat Nguyen" bằng phương thức props
<template>
  <div>
    <userName :userName="data.name" @userWasUpdated="data.name = $event"/>
  </div>
</template>

<script>
import userName from "./components/userName.vue";

export default {
 components: {
   userName
 },
 data() {
   return {
     data: {
       name: 'Dat Nguyen'
     }
   }
 },
}
</script>
//Sau khi đã có dữ liệu name là "Dat Nguyen", chúng ta cần cập nhật lại name mới là "Cloud Ace" với dữ liệu từ child
//Chúng ta sẽ sử dụng phương thức emit để gửi dữ liệu từ trong child tới parent

<template>
 <div>
   {{userName}}
   <button @click="changeUserName">Update Name</button>
 </div>
</template>
 
<script>
export default {
 props: ['userName'],
 data() {
   return {
     newUserName: "Cloud Ace"
   }
 },
 methods: {
   changeUserName() {
      this.$emit('userWasUpdated', this.newUserName );
    }
 },
}
</script>
Hình vẽ mô tả quá trình chuyển dữ liệu parent và child
Hình vẽ mô tả quá trình chuyển dữ liệu parent và child

EventBus

Vậy EventBus  là gì? EventBus là cách để truyền dữ liệu giữa các component không có mối liên hệ với nhau.
Vậy khi nào thì chúng ta nên sử dụng EventBus:

Chỉ nên sử dụng khi có nhiều component không có quan hệ hoặc quan hệ giữa parent và child phức tạp. VD như ta cần truyền dữ liệu từ D -> A, thì theo đúng flow thì sẽ truyền từ D-> C-> B-> A.

Sau đây chúng ta sẽ có một demo đơn giản như sau

//Đầu tiên ta sẽ tạo một file eventbus.js và đăng ký sử dụng eventbus
import Vue from 'vue';
export const EventBus = new Vue();
//Chúng ta sẽ tạo 2 component riêng biệt và gọi vào trong App.vue
<template>
    <div id="app">
        <componentInput />
        <componentResult />
    </div>
</template>

<script>
import componentInput from './components/componentInput';
import componentResult from './components/componentResult';

export default {
    name: 'App',
    components: {
        componentInput,
        componentResult
    },
}
</script>
//Ở đây chúng ta sẽ truyền dữ liệu tới service event bus
<template>
    <div>
        <input
            placeholder="Type your text"
            v-model="input"
        />
        <div>
            <button @click="sendMessage">EventBus</button>
        </div>
    </div>
</template>

<script>
import {EventBus} from './eventbus';

export default {
    data() {
        return {
            input: ''
        }
    },
    methods: {
        sendMessage() {
            EventBus.$emit('inputData', this.input);
            this.input = '';
        }
    }
};
</script>
//Ở đây chúng ta sử dụng hàm mounted on listen sự kiện từ event bus
<template>
    <div>Result: {{msg}}</div>
</template>

<script>
import {EventBus} from './eventbus';

export default {
    data() {
        return {
            msg: ''
        }
    },
    mounted() {
        EventBus.$on('inputData' , val => {
            this.msg = val;
        });
    }
};
</script>

Hôm nay chúng ta chỉ đi qua về 3 cách giao tiếp dữ liệu giữa các component với nhau, tuỳ vào từng trường hợp mà ta sẽ xem xét sẽ sử dụng cách nào.
Ở bài tiếp theo mình sẽ cùng tìm hiểu về cách còn lại, và cách sử dụng nó. Mong các bạn hãy cùng theo dõi nhé. 😀

Leave a Reply

Your email address will not be published. Required fields are marked *