【问题标题】:Vue.js object proxies: props not showing in Object.keysVue.js 对象代理:道具未显示在 Object.keys 中
【发布时间】:2019-01-28 00:26:28
【问题描述】:

Vue.js 代理它的对象来捕获属性访问。我似乎在抽象中发现了一个漏洞:Object.keys doesn't return props in the list of keys。

使用以下 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>

控制台输出为:

(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

(有趣的是,当我稍后调用检查时,isCollapsed 项在列表中。您还会注意到clickMe 方法也存在。似乎只省略了道具。)

为什么会这样?

更一般地说,Vue 的 Proxy 对象如何发出一组与其可以访问的键不同的键?

这对我来说是个问题,因为我正在尝试使用 pug-vdom 做一些花哨的事情,并且在内部使用 Object.keys 枚举要注入 Pug 模板的变量。

这是一个 Vue 错误吗? 或者,是否可以从 this 对象访问道具键列表,并导出其键也包含道具的对象?

编辑: 添加了一个可运行的代码 sn-p 来演示该问题。

【问题讨论】:

  • 一种 pug-vdom 错误。不可枚举的属性是一个东西,它们不需要代理,并且它们不包含在Object.keys 中。与对象原型上的属性相同。
  • 我的意思是,我不认为 pug-vdom 处于可以处理任何有人传递给它们的随机对象的阶段,我将承担将奇怪的东西传递给渲染方法的责任.不过,为什么 Vue 会让 props 不可枚举? (感谢您搜索的好关键字)

标签: javascript vue.js


【解决方案1】:

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>

【讨论】:

  • 返回true,但是,在问题中......
  • 你为什么这么认为?你能看到sn-p吗?
  • 因为它说“控制台输出是……真假”,整个问题就是为什么会这样。
  • 我复制了他的代码,但它没有显示真假,因为this 对象中存在可折叠键。你可以看到我的sn-p
  • 你可以检查this.$propsthis._props是否包含prop字段
猜你喜欢
  • 2019-03-27
  • 2023-04-05
  • 2020-03-22
  • 2020-03-24
  • 2020-09-15
  • 1970-01-01
  • 2020-06-09
  • 2016-05-09
  • 2023-04-08
相关资源
最近更新 更多