Vue 命名視圖問題記錄

一、問題解析

今天在使用 Vue命名視圖發(fā)現(xiàn)了兩個問題,首先看下代碼

路由部分代碼

   {
     path: Prefix('/device/:id'),
     name: 'Device',
     components: {tabbar: Device},
     meta: {
       title: '',
     },
     props: true,
   },
   {
     path: Prefix('/stop/:deviceId/:goodsId'),
     name: 'Stop',
     component: Stop,
     meta: {
       title: '',
     },
     props: true,
   },

這段代碼包含兩個路由,DeviceStop

  1. 首先當(dāng)進(jìn)入Device時無法到props中的id,這時需要修改成如下方式
      props: {
        tabbar: true,
      },

官方解釋是 對于包含命名視圖的路由,你必須分別為每個命名視圖添加 props 選項

  1. 第二個問題是當(dāng)從路由Device的組件跳轉(zhuǎn)到Stop路由的組件的時候,不能正確跳轉(zhuǎn)

當(dāng)把1的問題解決好以后,2的問題也解決好了,至于原理,應(yīng)該是vue-router內(nèi)部的實現(xiàn)機(jī)制,具體的原理還不清楚。

二、命名視圖的簡單用法

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

這樣就可以正常使用了,如果有布局的需求,就要自己進(jìn)行布局。

三、我什么會引入命名視圖

    <template v-if="showTabBar">
      <div class="p-app-body">
        <router-view name="tabbar"></router-view>
      </div>
      <div class="p-app-tabbar">
        <tab-bar v-model="routerName"></tab-bar>
      </div>
    </template>
    <template v-if="hideTabBar">
      <router-view></router-view>
    </template>

上面這段代碼是我現(xiàn)在可以正常運行的代碼

我部分頁面是有tabBar的,這時候就需要用到全屏,沒有用到tabBar的頁面正常顯示就好。

有問題的代碼

    <template v-if="showTabBar">
      <div class="p-app-body">
        <router-view></router-view>
      </div>
      <div class="p-app-tabbar">
        <tab-bar v-model="routerName"></tab-bar>
      </div>
    </template>
    <template v-else>
      <router-view></router-view>
    </template>

問題主要是當(dāng)我路由切換的時候可能導(dǎo)致我的組件加載兩次,何為兩次呢。

有一個Me路由(需要顯示tabBar)和一個Order路由(不需要顯示tabBar)時,當(dāng)有Me跳轉(zhuǎn)至Order時,showTabBar會由true變?yōu)?code>false,因為異步的原因,值改變的時候vue路由還沒有切換,因為都是路由的默認(rèn)組件,所以Me路由對應(yīng)的組件還會要再加載一次,再馬上切換到Order路由,正常情況下是沒有感官上的感受的,如果Me組件在created階段刪除掉了Order組件需要用的的CookielocalStorage、sessionStorage等,將導(dǎo)致頁面不能正確顯示,所以才會引入最上面說到的問題,同時還會引起下面這個問題。

說一下為什么要用兩個v-if而不是使用v-ifv-else。

假設(shè)我們使用v-ifv-else,當(dāng)首次加載的時候頁面已經(jīng)加載完畢,但是路由還沒有完全加載,頁面就會使用v-else進(jìn)行加載(或者因為異步的原因路由已經(jīng)加載完畢,但是我showTabBar是false),當(dāng)路由加載完成以后發(fā)現(xiàn)showTabBartrue,這時就需要使用v-if加載,導(dǎo)致路由對應(yīng)的組件加載兩次,解決的方法就是增加一個v-if,而且每個都要有去空判斷。

    showTabBar() {
      return this.routerName && listTabBar.indexOf(this.routerName) >= 0
    },
    hideTabBar() {
      return this.routerName && listTabBar.indexOf(this.routerName) < 0
    },

增加這一段之后因為有了去空解決了首次重復(fù)加載問題,那是否可以解決我最開始的問題(切換路由組件加載兩次)呢。

當(dāng)然是否定的。還是回到了出現(xiàn)這個問題的原因,因為異步導(dǎo)致v-if切換和路由切換不是同步的,所有是不可以的。

總結(jié)

如果Vue根節(jié)點是要根據(jù)v-if顯示不同的內(nèi)容并且每個內(nèi)容快都包含路由視圖時就需要考慮兩個方面
1、是否能容忍組件加載兩次,不能的話就要使用命名視圖。
2、是否能容忍首次重復(fù)加載,不能的話就要給每個單獨寫v-if并去掉空。

異議

其實解決這個問題也可以根據(jù)路由進(jìn)行區(qū)分,再加一個上級路由,需要用到tabBar的就統(tǒng)一有一個上級路由,把tabBar和全屏都寫在這個上級路由里面。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容