我有一种获取div样式的方法
<div v-for="(frame, frameIndex) in frames" :key="frameIndex">
<div :styles="getStylesForNode(node, frameIndex)"></div>
</div>
methods: {
getStylesForNode(node, frameIndex) {
this.$nextTick(() => {
const frame = this.$refs[`frame${frameIndex}`][0]
const framePosition = frame.getBoundingClientRect()
return {
width: node.width - framePosition.width
}
})
}
}
它返回空对象,是否有某种方法可以使它工作? 我找到了这个way,但不适合我的问题。
答案 0 :(得分:0)
很有可能,您的问题是this.$refs['frame${index}'][0]
在安装组件之前引发了错误(因为在安装之前无法使用$refs
)。
防止错误,直到$refs
存在:
methods: {
getStylesForNode(node, frameIndex) {
// guard against $refs not yet being defined
if (this.$refs[`frame${index}`]) {
const frame = this.$refs[`frame${index}`][0];
if (frame && typeof frame.getBoundingClientRect === 'function') {
return {
width: `${node.width - frame.getBoundingClientRect().width}px`
}
}
}
// return a safe, empty style, if you haven't returned on happy path
return {};
}
},
然后使用mounted()
重新计算this.$forceUpdate()
中的方法。
mounted() {
this.$forceUpdate();
}
看到它正常工作:
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: '#hook',
template: '#template',
data: () => ({ data: [...Array(5).keys()] }),
methods: {
getStyle(el) {
const span = this.$refs[`el-${el}`];
return span ? {
top: `${span[0].getBoundingClientRect().left}px`,
borderTop: '1px solid red'
} : {};
}
},
beforeMount() {
console.log('in beforeMount() $refs count is', Object.keys(this.$refs).length);
},
mounted() {
console.log('in mounted() $refs count is', Object.keys(this.$refs).length);
// we can now trigger an update to recalculate method...
this.$forceUpdate();
}
})
#app span {
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script type="text/template" id="template">
<div id="app">
<span
v-for="el in data"
v-text="el"
:key="el"
:ref="`el-${el}`"
:style="getStyle(el)"></span>
</div>
</script>
<div id="hook"></div>