鍍金池/ 問答/HTML/ vue 預(yù)渲染的問題

vue 預(yù)渲染的問題

我想實(shí)現(xiàn)讓我的vue項目 首頁加載得很更快點(diǎn) 網(wǎng)上了查找了一些關(guān)于vue首屏優(yōu)化的問題 好像一般是兩種解決方案 一個是SSR服務(wù)端渲染 還有一個是利用prerender spa plugin插件進(jìn)行預(yù)渲染 感覺SSR那種方式我的項目應(yīng)該用不到這么復(fù)雜的 就看了下預(yù)渲染
但是看了一天的預(yù)渲還是沒太明白怎么用的
官方文檔里有這么一段代碼
module.exports = {
// ...
plugins: [

new PrerenderSpaPlugin(
  // Absolute path to compiled SPA
  path.join(__dirname, '../dist'),
  // List of routes to prerender
  [ '/', '/about', '/contact' ]
)

]
}
我是想讓首頁渲染加載得更快一點(diǎn) 不明白它里面為什么會有一個路由的設(shè)置 如果在路由的話就路由到其它組件了 這還跟首頁渲染有什么關(guān)系呢
我的首頁里主要就是頭部 中間內(nèi)容部分 以及底部 主要是中間內(nèi)容部分的輪播圖 產(chǎn)品列表的數(shù)據(jù)是通過axios調(diào)取后臺接口獲取的數(shù)據(jù)
我是應(yīng)該把首頁的路由路徑放到那個配置里面去嗎 好蒙
這是我的首頁代碼
<template>
<div class="home">

  <qc-banner :imgUrl="imgUrl"></qc-banner>
<qc-notice :notices="notices"></qc-notice>
<div class="main">
  <ul class="data clearfix" id="shortcut">
    <li v-for="item in shortcuts">
      <img :src="item.imageURL">
      <router-link :to="item.url"></router-link>
      <h2>{{item.title}}</h2>
    </li>
  </ul>
  <div class="floor">
    <div class="floorA" v-show="item.lists.length" v-for="item in productCategories">
      <div class="title clearfix">
        <p class="prTitle">{{item.prTitle}}</p>
        <router-link :to="{path:'/invest',query: {productCategoryId: item.productCategoryId}}">更多 &gt; &gt;</router-link>
      </div>
      <ul class="bidList clearfix">
        <li 
          v-for="(list, index) in item.lists" 
          :class="{btwo: index % 3 === 1}"
          v-if="index < 3"
          >
          <h2>{{list.name}}</h2>
          <div ref="box" class="circle" :per="list.percent">
            <p class="p1">{{list.repayRate.toFixed(2)}}<span>%</span></p>
            <p class="p2">預(yù)期年化收益率</p>
          </div>
          <!-- <circle-load class="circle"
            :percent="list|proguressPercent" 
            :size="190"
            :trail-width="3"
            :stroke-width="3"
            stroke-linecap="square"
            stroke-color="rgb(255, 114, 29)">
            <p class="p1">{{list.repayRate.toFixed(2)}}<span>%</span></p>
            <p class="p2">預(yù)期年化收益率</p>
          </circle-load> -->
          <div class="deadline clearfix">
            <p class="p1" v-if="list.periodUnit==1" ><i>{{list.period}}</i>個月<span>投資期限</span></p>
            <p class="p1" v-if="list.periodUnit==0"><i>{{list.period}}</i>天<span>投資期限</span></p>

            <p class="p2">{{list.releaseAmount}}元<span>產(chǎn)品總額</span></p>
          </div>
          <router-link 
            v-if="list.status == 2"
            :to="{path:'invest/scattered',query: {productId: list.id}}">
            立即購買
          </router-link>
          <router-link 
            v-if="list.status == 3"
            :to="{path:'invest/scattered',query: {productId: list.id}}" class="btn">
            已滿標(biāo)
          </router-link>
          <router-link 
            v-if="list.status == 4"
            :to="{path:'invest/scattered',query: {productId: list.id}}" class="btn">
            還款中
          </router-link>
          <router-link 
            v-if="list.status == 5"
            :to="{path:'invest/scattered',query: {productId: list.id}}" class="btn">
            已完成
          </router-link>
        </li>
      </ul>
    </div>
  </div>
  <div class="media clearfix">
    <div class="mediaLf">
      <div class="title clearfix">
        <p class="prTitle">媒體報道</p>
      </div>
      <div class="detail clearfix">
        <img :src="report.imageURL" alt="">
        <div class="mediaTxt">
          <a :href="report.url" class="cl" target="_blank" style=" float:none;"><h2>{{report.title}}</h2>
          </a>
          <div v-html="report.content"></div>
          <a :href="report.url" class="detl cl" target="_blank">查看詳情 &gt; &gt;
          </a>
        </div>
      </div>
    </div>
    <div class="mediaRt">
      <div class="title clearfix">
          <a class="prTitle" href="#">網(wǎng)站公告</a>
      </div>
      <ul id="notice_footer"> 
        <li v-for="item in notices">
          <router-link :to="{path:'/information/notice/noticeDetail',query:{id: item.id}}">
           <p>{{item.title}}</p><span>2017-08-16</span>
          </router-link> 
        </li> 
      </ul>
    </div>
  </div>
</div>

</div>
</template>

<script>
import qcBanner from 'components/uiView/Banner/Banner'
import qcNotice from 'components/uiView/HomeNotice/HomeNotice'
import Circle from 'iview/src/components/circle'
import system from 'service/system'
import product from 'service/product'
import article from 'service/article'
import ProgressBar from 'progressbar.js'
export default {

  data() {
      return {
          imgUrl: [],
    notices: [],
    shortcuts: [],
    productCategories: [],
    report: {},
    lists: []
      }
},
created() {
  system.getCarousel().then((res) => {
    this.imgUrl = res.data.carousel
  });
  system.getNotice().then((res) => {
    this.notices = res.data.list
  })
  system.getShortcut().then((res) => {
    this.shortcuts = res.data
  })
  product.getProductCategory().then((res) => {
    this._getProductList(res.data)
  })
  article.getReportList().then((res) => {
    this.report = res.data.list[0]
  })
},
mounted() {
  window.addEventListener('scroll', () => {
      var top = document.documentElement.scrollTop || document.body.scrollTop
  })
  setTimeout(() => {
    var box = this.$refs.box
    box.forEach((item) => {
        var bar = new ProgressBar.Circle(item, {
        color: '#EAEEF2',
        strokeWidth: 3,
        trailWidth: 3,
        easing: 'easeInOut',
        duration: 1400,
        text: {
          autoStyleContainer: false
        },
        from: { color: '#FF721D', width: 3 },
        to: { color: '#FF721D', width: 3 },
        // Set default step function for all animate calls
        step: function(state, circle) {
          circle.path.setAttribute('stroke', state.color);
          circle.path.setAttribute('stroke-width', state.width);

          var value = Math.round(circle.value() * 100);
          if (value === 0) {
            circle.setText('');
          } else {
            circle.setText(value);
          }
        }
      });
      bar.animate( item.getAttribute('per') );
    })
  },800)
  
},
methods: {
  _getProductList(data) {
    for(let i = 0; i < data.length; i++) {
      product.getIndexCategoryProductList( data[i].id ).then((res) => {
        let lists = res.data.list.map( item => Object.assign(item,{
              percent: item.amountNow / item.releaseAmount
        }))
      this.productCategories.push({
          prTitle: data[i].name,
          lists: lists,
          productCategoryId: data[i].id
        })
      })
    }
  }
},
components: {
    qcBanner,
  qcNotice/*,
  CircleLoad: Circle*/
}

}
</script>

<style lang="less" scoped>
@import '~assets/less/index.less';
.home {

  width: 100%;
.main {
  width: @pages-width;
  margin: 0 auto;
  .data {
    font-size: 14px;
    & > li {
      color: @french-grey;
      margin: 40px 0;
      width: 25%;
      .fl(left);
      text-align: center;
      position: relative;
      & > img {
        width: 56px;
        height: 56px;
        margin: 0 auto;
        position: absolute;
        left: 119px;
        top: 23px;
        border: 0;
        vertical-align: middle;
        & + a {
          margin: 0 auto;
          display: block;
          width: 100px;
          height: 100px;
          background: url(../../../assets/images/rect.png);
          background-repeat: no-repeat;
          transition: transform 0.6s ease-out;
          &:hover {
            transform: rotateZ(360deg);
          }
          & + h2 {
            font-size: 24px;
            color: @french-grey;
            margin: 20px 0;
            font-weight: normal;
          }
        }
      }
    }
  }
  .floor {
    & > div {
      margin-bottom: 20px;
      .title {
        height: 64px;
        line-height: 60px;
        font-size: 12px;
        color: #9a9a9a;
        background-color: @white-color;
        & > p {
          .fl(left);
          color: @orange-color;
          font-size: 22px;
          font-weight: bold;
          & + a {
            .fr(right);
            color: @black-color;
            &:hover {
              color: @orange-color;
            }
          }
        }
      }
      .bidList {
        & > li {
          box-sizing: border-box;
          padding: 30px 0 10px 0;
          text-align: center;
          float: left;
          width: 369px;
          margin-bottom: 20px;
          border: 1px solid #dedede;
          &.btwo {
            margin: 0 31px;
          }
          h2 {
            font-size: 18px;
            color: @french-grey;
            font-weight: normal;
            padding-bottom: 30px;
          }
          .circle {
             width: 190px;
             height: 190px;
             position: relative;
             margin: 0 auto;
             .p1 {
               position: absolute;
               top: 66px;
               left: 40px;
               font-size: 36px;
               color: @orange-color;
               font-weight: bolder;
               padding-bottom: 6px;
               & > span {
                 font-size: 18px;
               }
             }
             .p2 {
               position: absolute;
               top: 120px;
               left: 50px;
             }
             svg {
               width: 190px;
               height: 190px;
             }
          }
          .deadline{
            padding: 20px 50px 0 84px;
            & > p {
               font-size: 18px;
               text-align: left;
               & > span {
                 display: block;
                 font-size: 14px;
                 color: #999;
               }
               &.p1{
                 color: #666666;
                 .fl(left);
                 & > i {
                  font-size: 20px;
                  font-style: normal;
                  color: @orange-color;
                 }
               }
               &.p2{
                 .fr(right);
                 color: @french-grey;
               }
            }
          }
          & > a {
             display: block;
             width: 291px;
             height: 38px;
             line-height: 38px;
             font-size: 16px;
             color: @white-color;
             border-radius: 4px;
             margin: 20px auto;
             background-color: #ff721d;
             -webkit-transition: background 0.2s;
             cursor: pointer;
             &.btn {
                 border: 1px solid #d9d9d9;
                 background-color: #d9d9d9;
                 box-shadow: 0 2px #d5d5d5;
             }
          }
        }
      }
    }
  }
  .media {
    margin: 90px 0;
    .mediaLf {
      width: 769px;
      height: 219px;
      .fl(left);
      .title {
        background-color: @white-color;
        .prTitle{
          color: @orange-color;
          font-size: 22px;
          font-weight: bold;
        }
      }
      .detail {
        margin-top: 30px;
        & > img {
          width: 205px;
          height: 115px;
          border: 0;
          .fl(left);
          vertical-align: middle;
        }
        & > .mediaTxt {
          width: 536px;
          height: 155px;
          .fr(right);
          position: relative;
          & > a{
            .fr(right);
          }
          & > div {
            font-size: 14px;
            margin-bottom: 25px;
            margin-top: 15px;
            height: 65px;
            overflow: hidden;
            color: #999999;
          }
          & > .detl {
            color: #fe5618;
            position: absolute;
            bottom: 0;
            right: 0;
          }
        }
      }
    }
    .mediaRt {
      height: 219px;
      width: 366px;
      overflow: hidden;
      .title {
        background-color: @white-color;
        a {
          color: @orange-color;
          font-size: 22px;
          font-weight: bold;
        }
      }
      .fr(right);
      & > ul {
        height: 157px;
        margin-top: 25px;
        li {
           height: 20%;
           a {
             color: #666666;
             & > p {
               width: 280px;
               font-size: 14px;
               .fl(left);
               overflow: hidden;
               text-overflow: ellipsis;
               white-space: nowrap;
               & + span {
                 .fr(right);
                 color: #999;
               }
             }
          }
        }
      }
    }
  }
}

}
</style>

回答
編輯回答
真難過

把你要渲染的路由放進(jìn)數(shù)組里,然后只支持history模式。但是這個東西是為了SEO的吧,并不能加快你真實(shí)頁面的渲染速度。

2017年9月11日 15:51
編輯回答
解夏

預(yù)渲染在構(gòu)建階段就已經(jīng)生成了匹配預(yù)渲染路徑的html文件,你的每個路由都可以作為入口文件,預(yù)渲染后其對應(yīng)文件夾下都有一個index.html,作為路口文件,之后在跳轉(zhuǎn)走的是前端路由,并不再請求html文件。首屏預(yù)渲染對還需要請求易變數(shù)據(jù)的頁面不太合適,因?yàn)檎故镜膆tml很可能是上次預(yù)渲染的html,等到請求完畢返回數(shù)據(jù)后再展示最新的html會引起客戶的誤解和疑惑。讓你配路由是因?yàn)?,若你一開始訪問的不是首頁,是其他路由,那么請求其他路由下已經(jīng)預(yù)渲染好的index.html,否則如果不做預(yù)渲染,會請求你的根節(jié)點(diǎn)的index.html,再根據(jù)路由匹配,鏈到你請求的路由下的頁面

2017年10月5日 10:13