Vue.js代理其对象以捕获属性访问。我似乎在抽象中发现了一个漏洞:Object.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
对象访问道具键列表,并导出一个也包含道具的对象?
编辑:添加了一个可运行的代码段,以演示该问题。
答案 0 :(得分:1)
Object.keys()
不会迭代原型属性。
子组件也是来自根组件的inherited
。
这意味着道具和数据字段必须在子组件的__proto__
内。
因此,如果我们执行Object.keys(this__proto__).includes("collapsible")
,它将在子组件中返回true
。
如果要从子组件访问这些字段,请使用this.$props
和this.$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>