首页 > 解决方案 > Vue.js object proxies: props not showing in Object.keys

问题描述

Vue.js proxies its objects to catch property accesses. I seem to have found a leak in the abstraction: Object.keys doesn't return props in the list of keys.

With the following Vue component:

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.)

Why is this happening?

More generally, how does Vue's Proxy object emit a different set of keys than it can then access?

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.

Is this a Vue bug? 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?

edit: added a runnable code snippet that demonstrates the problem.

标签: javascriptvue.js

解决方案


Object.keys()不迭代原型属性。
子组件也inherited来自根组件。这意味着道具和数据字段必须在__proto__子组件内。

因此,如果我们这样做Object.keys(this__proto__).includes("collapsible"),它会true在子组件中返回。

如果您想从子组件访问这些字段,请使用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>


推荐阅读