ethers.js 与 vue3 共同使用时报错 TypeError: 'get' on proxy: property '_network' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<Object>' but got '#<Object>')
类似错误复现路径:
// 0. 定义对象obj
const obj = {
b: '456'
}
// 1. 将属性b定义为 configurable false, writable false
Object.defineProperty(obj, 'b', {
configurable: false,
writable: false,
value: '777'
})
// 2. proxy 对象返回的 属性b的值 与原对象不符
// 注:步骤1和2可以颠倒顺序
const proxy = new Proxy(obj, {
get() {
return 'biubiubiu'
}
})
// 3. 报错: Uncaught TypeError: 'get' on proxy: property 'b' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '777' but got 'biubiubiu')
console.log(proxy.b)
报错原因
- 在初始化Provider实例时,_network属性被定义为 readonly.
defineReadOnly(this, "_network", knownNetwork);
defineReadOnly 定义如下:
function defineReadOnly(object, name, value) {
// configurable 属性默认为false
Object.defineProperty(object, name, {
enumerable: true,
value,
writable: false
});
}
- 把Provider实例赋值给Ref时,Provider实例被转换成一个Proxy实例,它修改了get方法,使_network属性返回的是一个改造后的Proxy实例,而不是原_network,所以报错。
const address = 'xxxx' // omitted
const provider = ref<ethers.providers.Web3Provider>()
provider.value = new ethers.providers.Web3Provider((window as any).ethereum, chainId)
// 报错,getBalance内部会访问_network属性
provider.value.getBalance(address)
修复方案
替换 Ref
为 ShallowRef