vue.js - vuetify `v-tabs` 的子组件返回 offsetWidth 为 0

标签 vue.js vuejs2 vue-router vuetify.js

这是重现该场景的代码笔: https://codepen.io/anon/pen/vzqgJB

我在 vuetify 的 v-app 中有一个 router-view

<div id="app">
  <v-app>
    <v-content>
      <v-container>
        {{$route.path}}
        <router-view/>
      </v-container>
    </v-content>
  </v-app>
</div>

路由配置如下:

const routes = [
    { path: '', component: tabsComponent, 
      children:[
        { path: '', component: component1 },
        { path: 'component2', component: component2 }
      ]
    },
]

我使用 Vuetify 的 v-tabs 组件来渲染 2 个选项卡,分别加载 component1component2

var tabsComponent = Vue.component('tabsComponent',{
  components:{
    component2,
    component1
  },
  name:'tabsComponent',
  template: `
     <v-tabs>
        <v-tab to="/">Tab 1</v-tab>
       <v-tab to="/component2">Tab 2</v-tab>
       <v-tabs-items>
          <v-tab-item id="/">
            <component1></component1>
          </v-tab-item>
          <v-tab-item id="/component2">
            <component2></component2>
          </v-tab-item>
        </v-tabs-items>
     </v-tabs>
`,
   mounted(){
    this.$nextTick(()=>{
      console.log("tabs")
      console.log(this.$el.offsetWidth)
    })
  }
})

我面临的问题是,当安装 component1 时,this.$el.offsetWidth 返回为 0

  var component1 = Vue.component('component1',{
    name: 'component1',
      template: `
         <v-container fluid>John </v-container>
      `,
      mounted(){
        this.$nextTick(()=>{
          console.log("component1")
          console.log(this.$el.offsetWidth) // This is printed as 0
        })
      }
    })

即使父组件具有非零 offsetWidth,我也无法弄清楚为什么宽度返回为 0。 任何帮助将不胜感激。

最佳答案

mounted 子组件中的 hook 在父组件中的 Mounted hook 之前触发:在子组件中安装 hook,在父组件中安装 hook,最后渲染到 dom。因此,在子组件中距离渲染还有两个刻度。您可以使用两个折叠的 $nextTick 或使用 setTimeout 执行您想要的操作(setTimeout 回调在 vue 完成所有操作后获得控制权):

mounted(){
  this.$nextTick(()=>{
    this.$nextTick(()=>{
      console.log("component1")
      console.log(this.$el.offsetWidth)
    })
  })
}

mounted(){
  setTimeout(()=> {
    console.log("component1")
    console.log(this.$el.offsetWidth)
  })
}

插图来自Vue Parent and Child lifecycle hooks :

enter image description here


更新您的评论:

是的,您无法使用 display: none 获取非事件选项卡的 offsetWidth。但是所有选项卡的偏移量彼此相等吗?无论如何,您可以动态跟踪事件选项卡。在 tabsComponent 上使用 v-model 并添加 watch 方法,您可以在选项卡可见时获取指标。此外,您还应该将 ref 添加到组件和内部容器中(通过将组件的 ref 名称设置为选项卡路径,您可以使用 activeTab 访问事件组件内部引用)。

在模板中:

<v-container fluid ref="div">John</v-container>
# ...
<div id="component2" ref="div">Jinny</div>
# ...
<v-tabs v-model='activeTab'>
# ...
<component1 ref="/"></component1>
<component2 ref="/jinny"></component2>

在脚本中:

data: function () {
  return {
    activeTab: null
  }
},
watch: {
  activeTab: function () {
    this.$nextTick(()=> {
      console.log(this.$refs[this.activeTab].$refs.div.offsetWidth) 
    })
  }
}

使用 watch 方法更新了 codepen:https://codepen.io/anon/pen/qMeYGZ

关于vue.js - vuetify `v-tabs` 的子组件返回 offsetWidth 为 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52497042/

相关文章:

vue.js - vue组件注册和路由

vuejs2 - Vue-Test-Utils 未知的自定义元素 : <router-link>

javascript - Vue JS 对路由的权限

vue.js - VueJS - 将插槽和作用域插槽传递给子模板中的组件

javascript - 当加 1 时字符串不应该是 01

vue.js - 在 vue.js 中创建可重用组件

javascript - 设计 View /只读表单的任何方式

javascript - 如何在按键时重新评估计算值?

javascript - 在Vue中向axios添加分页参数

vue.js - NUXT JS中丰富断点时动态更改路由