2017-07-18 373 views
1

我有“上下文菜单”组件。计算属性topleft使用$event属性定义菜单位置。但是,当我试图打开上下文菜单,菜单元素尚未呈现,没有菜单的offsetHeight无法计算top,所以我想通了,使用一些“nextTick黑客”计算属性里面:Vue.js nextTick里面的计算属性

top() { 
    if (!this.menuIsRendered) { // by default, menuIsRendered is false 
    this.$nextTick(() => { 
     this.menuIsRendered = true 
    }) 

    return 0 
    } 

    ... // menu element is rendered, calculate top value 
}, 

这是好吗?我认为必须有更好的方式来做到这一点。

另外,充满组件的代码:

<template> 
    <div ref="menu" :style="{top: `${top}px`, left: `${left}px`}" 
    v-click-outside="close" @contextmenu.prevent v-if="show"> 
    <slot></slot> 
    </div> 
</template> 

<script> 
export default { 
    props: [ 
    'show', 
    'event' 
    ], 
    data() { 
    return { 
     menuIsRendered: null, 
    } 
    }, 
    computed: { 
    top() { 
     if (!this.menuIsRendered) { 
     this.$nextTick(() => { 
      this.menuIsRendered = true 
     }) 

     return 0 
     } 

     let top = this.event.y 
     let largestHeight = window.innerHeight - this.$refs.menu.offsetHeight - 25 

     return top > largestHeight ? largestHeight : top + 1 
    }, 
    left() { 
     if (!this.menuIsRendered) { 
     return 0 
     } 

     let left = this.event.x 
     let largestWidth = window.innerWidth - this.$refs.menu.offsetWidth - 25 

     return left > largestWidth ? largestWidth : left + 1 
    }, 
    }, 
    methods: { 
    close() { 
     this.$emit('close') 
    }, 
    } 
} 
</script> 

部件使用情况:

<context-menu @close="close" :event="event" :show="show"> 
    <div @click="doAction">Action</div> 
    <div @click="doAnotherAction">Another action</div> 
</context-menu> 

回答

-1

通常,计算的属性必须是同步的。如果你想使这个属性异步,你应该使用这个插件:https://github.com/foxbenjaminfox/vue-async-computed

有了这个插件,你可以在Vue中计算异步计算的属性。没有使用这个插件,你不能这样做。

现在,您可以设置asynchrone computeds与asyncComputed属性:

asyncComputed: { 
    username() { 
    return Vue.http.get('/get-username-by-id/' + this.userId) 
     .then(response => response.data.username) 
    } 
} 
+0

什么 “你不能这样做” 是什么意思?我的组件工作正常。另外,'nextTick'不会返回一个promise,所以,我真的可以使用这个插件吗? – Captain

+0

哦,实际上,'nextTick'返回一个Promise“2.1.0版新增功能:如果没有提供回调,并且在执行环境中支持Promise,则返回Promise。” – Captain

+0

我只是复制插件的介绍。在这种情况下,它回应你的问题;) – throrin19