代码之家  ›  专栏  ›  技术社区  ›  Ankit Kante

vuetify'v-tabs'的子组件将offsetwidth返回为0

  •  1
  • Ankit Kante  · 技术社区  · 6 年前

    下面是复制场景的代码笔: https://codepen.io/anon/pen/vzqgJB

    我有一个 router-view 在Vuetify的内部 v-app .

    <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 }
          ]
        },
    ]
    

    我正在使用 v-tabs Vuetify的组件,用于呈现加载的2个选项卡 component1 component2 分别。

    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)
        })
      }
    })
    

    我面临的问题是, 组件1 安装在 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。 任何帮助都将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  1
  •   ndpu    6 年前

    mounted hook-in-child component fired before mounted hook-in parent :mount hook-in-child,mount hook-in parent and at last render to dom.因此,在child component 中,离render有两个刻度。您可以使用两个折叠的 >$nextick->code>或使用 setTimeout->code>(setTimeout callback gets control after vue do all his stufactures):。

    mounted()。{
    此。$NextTick(()=>){
    此。$NextTick(()=>){
    console.log(“组件1”)
    console.log(这个$el.offsetwidth)
    })
    })
    }
    < /代码> 
    
    

    mounted()。{
    设置超时(()=>){
    console.log(“组件1”)
    console.log(这个$el.offsetwidth)
    })
    }
    < /代码> 
    
    

    图来自vue parent and child lifecycle hooks:。


    更新到您的评论:

    是的,您不能使用display:none>code>获得非活动选项卡的offsetwidth。但是所有标签的偏移量是相等的吗?无论如何,您可以动态跟踪活动选项卡。在您的tabscomponent>code>上使用v-modeland add watch method which you can get your metrics when tab is visible.此外,还应向组件和内部容器添加ref(通过设置ref name of component等于tab path,可以使用active tab访问活动组件内部refs)。

    在模板中:

    <v-container fluid ref=“div”>john</v-container>
    ……
    <div id=“component2”ref=“div”>金尼</div>
    ……
    <v-tabs v-model='activetab'>
    ……
    <component1 ref=“/”></component1>
    <component2 ref=“/jinny”></component2>
    < /代码> 
    
    

    在脚本中:

    data:function()。{
    返回{
    ActuaTab:空
    }
    }
    观察:{
    activetab:函数()。{
    此。$NextTick(()=>){
    console.log(this.$refs[this.activetab]。$refs.div.offsetwidth)
    })
    }
    }
    < /代码> 
    
    

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

    渲染到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


    更新您的评论:

    是的,你得不到offsetWidth非活动选项卡的display: none. 但是所有标签的偏移量是相等的吗?无论如何,您可以动态跟踪活动选项卡。使用v-model对你tabsComponent并添加监视方法,在该方法中,当选项卡可见时,您可以获取度量。你也应该加上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方法更新的代码笔:https://codepen.io/anon/pen/qMeYGZ