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的代理对象如何发出一组不同于它随后可以访问的密钥?
这对我来说是个问题,因为我正在尝试使用pug-vdom
进行一些奇妙的尝试,在内部使用Object.keys
来枚举要注入到Pug模板中的变量。
这是Vue虫吗?或者,是否可以从this
对象访问支持键列表,并导出其键也包含道具的对象?
编辑:添加了一个可运行的代码片段来演示这个问题。
发布于 2018-08-21 11:15:17
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>
https://stackoverflow.com/questions/51955055
复制