Phát hiện chặn quảng cáo

Xin lỗi bạn, mình có đặt quảng cáo để lấy kinh phí duy trì trang, nếu bạn không thấy phiền có thể tắt chức năng chặn quảng cáo và tải lại trang.

Tiếp tục xem
Tải lại

[VueJS] Kỹ thuật Sync Between Tabs trong VueJS cơ bản

Bạn đã bao giờ phải gặp một bài toàn yêu cầu phải đồng bộ các action, giá trị giữa các tab trên cùng một trình duyệt với nhau. Hay các bài toán xử lý 2 màn hình như một màn hình máy bán hàng cho nhân viên – một màn hình cho khách hàng,…Hãy cùng mình theo dõi cách giải quyết bài toán này ra sao bằng cách sử dụng kỹ thuật Sync Between Tabs trong VueJS nhé

Thực hành Sync Between Tabs

Bài toán của chúng ta ở đây là việc hiển thị 2 màn hình cho 2 đối tượng khác nhau. Một là nhân viên và hai là khách hàng. Với màn hình của nhân viên sẽ là thêm các sản phẩm, còn khách hàng sẽ nhìn thấy sản phẩm được thêm. Cụ thể mình giả lập kết quả như dưới:

Đó chính là kết quả mà chúng ta sẽ tạo ra, còn ý tưởng thì sao? Ở đây, key chính để giải quyết bài toán này chính là localstorage. Chúng ta sẽ lưu giá trị là danh sách các sản phẩm được thêm vào trong localstorage, đồng thời bắt sự thay đổi của localstorage khi sản phẩm được thêm và xử lý ở màn hình mà khách hàng nhìn thấy. Cụ thể ở đây mình đã dùng addEventListener để làm kỹ thuật này:

 window.addEventListener('storage', () => {
    // Xử lý logic
  });

Về ý tưởng đã có, vậy code thì như nào? Ở đây mình sẽ có 3 file chính là EmployeeScreen.vue, CustomerBuy.vueuseSharedState.js

  • EmployeeScreen.vue: Dùng để xử lý màn hình của nhân viên. Bao gồm tính năng thêm sản phẩm và hiển thị danh sách đã thêm
  • CustomerSceen.vue: Dùng để xử lý màn hình khách hàng. Hiển thị các sản phẩm đã được thêm.
  • useSharedState.js: Áp dụng Composable để quản lý xử lý logic chung việc thêm sản phẩm và lấy sản phẩm. Nếu bạn chưa biết về kỹ thuật về Composable thì hãy tham khảo bài viết Hãy ứng dụng ngay Composable vào dự án của bạn

useSharedState.js – phần xử lý logic chính của chương trình, mình đã có mô tả chi tiết trong code:

import { ref, watch } from 'vue';

export default function useSharedState(key, defaultValue) {
  // Khởi tạo state với giá trị mặc định là giá trị được lấy từ localStorage
  const state = ref(JSON.parse(localStorage.getItem(key)) || defaultValue);

  // Lưu giá trị mới vào localStorage khi state thay đổi
  // Khi màn hình nhân viên thêm sản phẩm, thì sẽ tự động thêm vào localstorage
  watch(state, (newValue) => {
    localStorage.setItem(key, JSON.stringify(newValue));
  }, { deep: true });

  // Lắng nghe sự kiện storage để cập nhật giá trị mới cho state
  // Khi sản phẩm được lưu vào localstorage thì màn hình khách hàng cũng lắng nghe sự thay đổi và lấy lại dữ liệu của state
  window.addEventListener('storage', () => {
    state.value = JSON.parse(localStorage.getItem(key));
  });

  return state;
}

EmployeeScreen.vue – chúng ta sẽ phần xử lý thêm sản phẩm và hiển thị danh sách các sản phẩm:

<template>
    <div class="main">
        <div class="box-add">
            Sản phẩm: <input type="text" v-model="product">
            <br>
            <button @click="addProduct">Thêm sản phẩm</button>
        </div>

        <div class="list-buy">
            <table>
                <tr>
                    <th>Danh sách sản phẩm cho nhân viên</th>
                </tr>
                <tr v-for="(cost, index) in products" :key="index">
                    <td>{{ cost }}</td>
                </tr>
            </table>
        </div>
    </div>
</template>
  
<script>
import { ref } from 'vue';
import useSharedState from './composables/useSharedState';

export default {
    name: 'EmployeeScreen',
    setup() {
        // Sản phẩm được thêm vào
        const product = ref('');

        // Lưu trữ danh sách sản phẩm
        const products = useSharedState('listproduct', []);

        // Chức năng thêm sản phẩm
        const addProduct = () => {
            products.value.push(product.value);
            product.value = '';
        };

        // Khởi tạo
        const init = () => {
            // Xóa danh sách sản phẩm
            products.value = [];
        };

        init();

        return {
            product,
            products,
            addProduct,
        };
    },
};
</script>

CustomerScreen.vue – xử lý lấy ra danh sách các sản phẩm:

<template>
    <div>
        <table>
            <tr>
                <th>Danh sách sản phẩm cho khách hàng</th>
            </tr>
            <tr v-for="(cost, index) in products" :key="index">
                <td>{{ cost }}</td>
            </tr>
        </table>
    </div>
</template>

<script>
import { defineComponent } from 'vue';
import useSharedState from './composables/useSharedState';

export default defineComponent({
    name: 'CustomerScreen',
    setup() {
        const products = useSharedState('listproduct', []);

        return {
            products
        };
    },
});
</script>

Vậy là mình đã hoàn thành kỹ thuật Sync Between Tabs trong VueJS một cách cơ bản cho bài toán nêu trên. Tất nhiên là bài toán chỉ là một ví dụ để các bạn hiểu hơn về kỹ thuật này. Còn thực tế nếu hiển thị ở 2 máy khác nhau sẽ không được do phần lưu trữ là localstorage. Chúc các bạn thành công áp dụng!

Về Đặng Thắng

Chào mọi người, mình là Thắng. Sở thích của mình là lập trình và chia sẻ mọi thứ mình học được cho tất cả mọi người. Rất mong mọi người ủng hộ Blog của mình.

Đề xuất

[VueJS] Tối ưu hiệu năng VueJS với Async Components

Xin chào các bạn, hôm nay sẽ là một bài viết liên quan tới VueJS …

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *