vuetify `v-tabs` 的子组件 returns offsetWidth 为 0
Child Component of vuetify `v-tabs` returns offsetWidth as 0
这是重现该场景的代码笔:
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 个分别加载 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)
})
}
})
我面临的问题是,当安装 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
})
}
})
我无法弄清楚为什么宽度返回为 0,即使父组件具有非零 offsetWidth。
任何帮助将不胜感激。
mounted
子组件中的挂钩在父组件中挂载挂钩之前触发:子组件挂载挂钩,父组件挂载挂钩,最后渲染到 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 的插图:
更新您的评论:
是的,您无法使用 display: none
获得 offsetWidth
个非活动选项卡。但是所有选项卡的偏移量是否彼此相等?无论如何,您可以动态跟踪活动选项卡。在 tabsComponent
上使用 v-model
并添加 watch 方法,在该方法中您可以在选项卡可见时获取指标。您还应该将 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
这是重现该场景的代码笔: 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 个分别加载 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)
})
}
})
我面临的问题是,当安装 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
})
}
})
我无法弄清楚为什么宽度返回为 0,即使父组件具有非零 offsetWidth。 任何帮助将不胜感激。
mounted
子组件中的挂钩在父组件中挂载挂钩之前触发:子组件挂载挂钩,父组件挂载挂钩,最后渲染到 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 的插图:
更新您的评论:
是的,您无法使用 display: none
获得 offsetWidth
个非活动选项卡。但是所有选项卡的偏移量是否彼此相等?无论如何,您可以动态跟踪活动选项卡。在 tabsComponent
上使用 v-model
并添加 watch 方法,在该方法中您可以在选项卡可见时获取指标。您还应该将 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