简体   繁体   English

Vue.js对象代理:道具未显示在Object.keys中

[英]Vue.js object proxies: props not showing in Object.keys

Vue.js proxies its objects to catch property accesses. Vue.js代理其对象以捕获属性访问。 I seem to have found a leak in the abstraction: Object.keys doesn't return props in the list of keys. 我似乎在抽象中发现了一个漏洞: Object.keys不在键列表中返回props。

With the following Vue component: 具有以下Vue组件:

 function callMe() { var comp = Vue.component("comp", { template: "<button @click='clickMe()'>xxx</button>", props: { label: String, cardId: String, collapsible: { type: Boolean, default: true, }, collapsed: Boolean, }, data() { console.log(Object.keys(this)) console.log(this.collapsible) console.log(Object.keys(this).includes("collapsible")) return { isCollapsed: this.collapsed } }, methods: { clickMe(){ console.log(this) } } }) var vm = new Vue({ el: '#root', template: "<comp></comp>", }) } callMe(); 
 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.11/dist/vue.js"></script> <div id='root'> <button @click="clickMe()" >Click Me</button> </div> 

The console output is: 控制台输出为:

(29) ["_uid", "_isVue", "$options", "_renderProxy", "_self", "$parent", "$root", "$children", "$refs", "_watcher", "_inactive", "_directInactive", "_isMounted", "_isDestroyed", "_isBeingDestroyed", "_events", "_hasHookEvent", "_vnode", "_staticTrees", "$vnode", "$slots", "$scopedSlots", "_c", "$createElement", "$attrs", "$listeners", "_watchers", "_props", "toggleThis"]
true
false

(Interestingly, when I call the check later, the isCollapsed item is in the list. You'll also notice that clickMe method is also present. It seems that only props are left out.) (有趣的是,当我稍后调用检查时, isCollapsed项在列表中。您还将注意到,还存在clickMe方法。似乎只保留了道具。)

Why is this happening? 为什么会这样呢?

More generally, how does Vue's Proxy object emit a different set of keys than it can then access? 更一般而言,Vue的Proxy对象如何发出与之后无法访问的密钥集不同的密钥?

This is a problem for me because I'm trying something fancy with pug-vdom and that internally uses Object.keys to enumerate the variables to inject into the Pug template. 这对我来说是个问题,因为我正在尝试使用pug-vdom并且在内部使用Object.keys枚举要注入Pug模板的变量。

Is this a Vue bug? 这是Vue的错误吗? Alternately, is it possible to access a list of props keys from the this object, and export an object whose keys contain the props as well? 或者,是否有可能从接入道具键列表this对象,并导出一个对象,它的键包含的道具呢?

edit: added a runnable code snippet that demonstrates the problem. 编辑:添加了一个可运行的代码片段来演示该问题。

Object.keys() does not iterate over prototype properties. Object.keys()不会迭代原型属性。
Also child component is inherited from root component. 子组件也从根组件inherited This means props & data fields must be inside __proto__ of child components. 这意味着props和data字段必须在子组件的__proto__之内。

Hence if we do Object.keys(this__proto__).includes("collapsible") , it returns true in child component. 因此,如果我们执行Object.keys(this__proto__).includes("collapsible") ,则它在子组件中返回true

If you want to access those fields from child components then use this.$props and this.$data . 如果要从子组件访问这些字段,请使用this.$propsthis.$data

 function callMe() { var comp = Vue.component("comp", { template: "<button @click='clickMe()'>xxx</button>", props: { label: String, cardId: String, collapsible: { type: Boolean, default: true, }, collapsed: Boolean, }, data() { console.log('Inside Child:',Object.keys(this)) console.log(this.collapsible) console.log(Object.keys(this.__proto__).includes("collapsible")) console.log(Object.keys(this).includes("collapsible")) return { isCollapsed: this.collapsed } }, methods: { clickMe(){ console.log(this) } } }) var vm = new Vue({ el: '#root', template: "<comp></comp>", props:{ jack:{ type: Boolean, default: true } }, data(){ console.log('Inside parent:', this.jack) return {} } }) } callMe(); 
 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.11/dist/vue.js"></script> <div id='root'> <button @click="clickMe()" >Click Me</button> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM