2017-07-18 81 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