---@param model table{__reactive: boolean | nil} ---@ metatable {__index, __newindex, pairs, ipairs, __len} localfunctionnewProxy(model, metatable) -- 不是table就没啥好说的了 iftype(model) ~= "table"then return model end -- 给proxy做proxy除了浪费没有任何意义 if model.__reactive then return model end
-- 存储原来的数据到__raw方便后续处理,也可以用闭包方式 localself = { __raw = model } setmetatable(self, metatable) returnself end
-- 返回处理过的返回结果 -- 当key对应在raw里面的结果是table,返回proxy对象 __index = function(t, key) if key == "__reactive"then -- 标记当前对象是否已经是proxy了,给proxy做proxy除了浪费没有任何意义 returntrue end
if key == 'raw'then return t.__raw end -- do something print("try get ".. key) -- 考虑嵌套的问题,避免返回嵌套的proxy local value = rawget(t.__raw, key) iftype(value) ~= "table"then return value end -- 使用proxyMap缓存数据,避免同一个key出现多个proxy代理 return proxyMap[value] or proxy(value, metatable) end
---@param model table functionisArray(model) -- 连续数据区长度大于0 return #model > 0 end ---@param model table{__reactive: boolean | nil} ---@ metatable {__index, __newindex, pairs, ipairs, __len} localfunctionnewProxy(model, metatable) -- 不是table就没啥好说的了 iftype(model) ~= "table"then return model end -- 给proxy做proxy除了浪费没有任何意义 if model.__reactive then return model end
-- 存储原来的数据到__raw方便后续处理,也可以用闭包方式 localself = { __raw = model } setmetatable(self, metatable) returnself end
local metatable = { -- 返回处理过的返回结果 -- 当key对应在raw里面的结果是table,返回proxy对象 __index = function(t, key) if key == "__reactive"then -- 标记当前对象是否已经是proxy了,给proxy做proxy除了浪费没有任何意义 returntrue end
if key == 'raw'then return t.__raw end -- do something print("try get " .. key) -- 考虑嵌套的问题,避免返回嵌套的proxy local value = rawget(t.__raw, key) iftype(value) ~= "table"then return value end -- 使用proxyMap缓存数据,避免同一个key出现多个proxy代理 return proxyMap[value] or newProxy(value, metatable) end, __newindex = function(t, key, value) local oldValue = rawget(t.__raw, key) rawset(t.__raw, key, value) -- 当数据发生变化的时候do something if (oldValue ~= value) then -- 数组的插入和删除会对后续的元素产生影响,需要单独处理 -- 如t ={1,2,3,4}, table.remove(t, 1)之后t={1,3,4} 对元素而言t[2] 从2变成了3 if isArray(t) andtonumber(key) <= #t.__raw then -- 区分删除还是增加 if oldValue == nilthen print("add a key to array") end
if value == nilthen print("remove a key to array") end else print("set a key to map") end end returntrue end, __pairs = function(t) -- do something print("pairs") returnpairs(t.__raw) end, __ipairs = function(t) -- do something print("ipairs") returnipairs(t.__raw) end, __len = function(t) -- do something print("length") return #t.__raw end }
local model = newProxy({ name = "testname", age = 13, info = { familyNum = 10, brother = 20, sonName = "testSon" } }, metatable)
print(model.name) model.info.familyNum = 13 local info = model.info info.sonName = "newSonName"
table.insert(model, 1)
table.insert(model, 2) model[2] = nil table.remove(model, 1) ----- 输出 -- try get name -- testname -- try get info -- try get info -- length -- length -- add a key to array -- length -- length -- add a key to array -- length -- set a key to map -- length -- try get 1 -- length -- set a key to map