Tạo hệ thống phản ứng hoàn chỉnh với JavaScript

Dữ liệu phản ứng

Dữ liệu tự động thay đổi và cập nhật giao diện

Hàm phản ứng

Các hàm hoạt động tương tác với dữ liệu phản ứng

Yêu cầu 1: Liên kết hàm với dữ liệu

// Hàm phản ứng
function thayDoi() {
  document.body.textContent = doiTuong.giaTri
}

// Nhóm chứa các hàm phản ứng
const hanhDong = new Set()

// Dữ liệu gốc
const nguon = { giaTri: "Xin chào" }

// Đối tượng ủy quyền
const doiTuong = new Proxy(nguon, {
  // Đọc dữ liệu
  get(tr, thuocTinh) {
    hanhDong.add(thayDoi)
    return tr[thuocTinh]
  },
  
  // Ghi dữ liệu
  set(tr, thuocTinh, giatriMoi) {
    tr[thuocTinh] = giatriMoi
    hanhDong.forEach(fn => fn())
    return true
  }
})

thayDoi()

setTimeout(() => {
  doiTuong.giaTri = "Xin chào Vue3"
}, 1000)

Yêu cầu 2: Theo dõi phụ thuộc

let hieuUngHienTai = null

function tacDong(fn) {
  hieuUngHienTai = fn
  fn()
}

const hanhDong = new Set()

const nguon = { giaTri: "Xin chào" }
const doiTuong = new Proxy(nguon, {
  get(tr, thuocTinh) {
    if (hieuUngHienTai) {
      hanhDong.add(hieuUngHienTai)
    }
    return tr[thuocTinh]
  },
  set(tr, thuocTinh, gtMoi) {
    tr[thuocTinh] = gtMoi
    hanhDong.forEach(fn => fn())
    return true
  }
})

tacDong(function() {
  document.body.textContent = doiTuong.giaTri
})

setTimeout(() => {
  doiTuong.giaTri = "Xin chào Vue3"
}, 1000)

Yêu cầu 3: Liên kết trường dữ liệu

const hanhDong = new WeakMap()
let hieuUngHienTai = null

function tacDong(fn) {
  hieuUngHienTai = fn
  fn()
}

function theoDoi(tr, thuocTinh) {
  if (!hieuUngHienTai) return
  let bangDoiTuong = hanhDong.get(tr)
  
  if (!bangDoiTuong) {
    bangDoiTuong = new Map()
    hanhDong.set(tr, bangDoiTuong)
  }
  
  let duLieuPhu = bangDoiTuong.get(thuocTinh)
  if (!duLieuPhu) {
    duLieuPhu = new Set()
    bangDoiTuong.set(thuocTinh, duLieuPhu)
  }
  
  duLieuPhu.add(hieuUngHienTai)
}

function kichHoat(tr, thuocTinh) {
  const bangDoiTuong = hanhDong.get(tr)
  if (!bangDoiTuong) return
  const duLieuPhu = bangDoiTuong.get(thuocTinh)
  if (duLieuPhu) {
    duLieuPhu.forEach(fn => fn())
  }
}

const nguon = { giaTri: "Xin chào" }
const doiTuong = new Proxy(nguon, {
  get(tr, thuocTinh) {
    theoDoi(tr, thuocTinh)
    return tr[thuocTinh]
  },
  set(tr, thuocTinh, gtMoi) {
    tr[thuocTinh] = gtMoi
    kichHoat(tr, thuocTinh)
    return true
  }
})

tacDong(function() {
  document.body.textContent = doiTuong.giaTri
})

setTimeout(() => {
  doiTuong.giaTri = "Xin chào Vue3"
  doiTuong.loiChao = "Chào Vue3"
}, 1000)

Thẻ: Reactive System Side Effects proxy Dependency Collection

Đăng vào ngày 31 tháng 7 lúc 22:25