vue從建立到完整餓了麼(16)watch監聽子路由變化

說明

1.上一章--組件動畫
2.蒼渡大神源碼--項目地址
3.數據接口--API接口地址
4.UI框架--Mint UI
5.下一章--本地緩存購物車css

開始

  1. 目前的路由配置
import App from '../App'

import home from '../page/home/home'
import login from '../page/login/login'
import city from '../page/city/city'
import miste from '../page/miste/miste'
import search from '../page/search/search'
import order from '../page/order/order'
import profile from '../page/profile/profile'
import shop from '../page/shop/shop'

export default [{
        path:'/',
        component:App,//頂層路由
        children:[
            {
                path:'',
                redirect: '/home'//爲空時跳轉到home頁面
            },{
                path:'/home',
                component:home
            },{
                path:'/login',
                component:login
            },{
                path:'/city',
                component:city
            },{
                path:'/miste',
                component:miste
            },{
                path:'/search',
                component:search
            },{
                path:'/order',
                component:order
            },{
                path:'/profile',
                component:profile
            },{
                path:'/shop',
                component:shop,
            }

        ]
        
    }]

2.添加子路由
如今要爲shop路由添加一個子路由,修改以下
圖片描述html

3.建立頁面
在src下的page文件夾下的shop文件下新建children 文件夾,用來放shop的全部子頁面,在children 文件夾新建shopDetail.vue文件,代碼以下
圖片描述vue

4.這時候,在地址輸入/shop/shopDetail發現頁面仍是shop頁面。這是由於shopDetail頁面是顯示在shop頁面內的。咱們須要<router-view></router-view>來展現shopDetail頁面。html修改代碼以下node

<template>
  <div id="shop" class="bgfff">
        <div class="big">
              <div class="topbg">
                      <img class="topbgimg" :src="imgpath+shopinfo.image_path">
              </div>
              <div class="shoptop">
                  <div class="toptop ih30">
                    <router-link to="miste">
                        <icon class="backicon" name="back"></icon>
                    </router-link>
                    <span class="right">
                        <icon class="backicon2" name="cart"></icon>
                        <icon class="backicon2" name="more"></icon> 
                    </span>
                  </div>
                  <div class="topfoot">
                      <div class="topleft">
                          <img :src="imgpath+shopinfo.image_path">
                      </div>
                      <div class="topright nowarp">
                          <router-link to="shop/shopDetail">
                              <div class="foota">
                                  <div class="footamain fs1-2 nowarp">{{shopinfo.name}}</div>
                                  <icon name="right" class="icon3"></icon>
                              </div>
                          </router-link>
                          <div class="footb nowarp">
                              <div class="nowarp">公告:{{shopinfo.promotion_info}}</div>
                          </div>
                          <div class="footc">
                              <span class="footcmain"><span v-if="shopinfo.delivery_mode">{{shopinfo.delivery_mode.text}}•</span><span>約{{shopinfo.order_lead_time}}</span></span>
                          </div>
                      </div>
                  </div>
                  
              </div>
              <div class="shopmid mgtop10">
                  <div @click="modal=true" v-if="shopinfo.activities" class="midtop"><span class="te mgr5">{{shopinfo.activities[0].icon_name}}</span><span>{{shopinfo.activities[0].description}}</span><span class="right">{{shopinfo.activities.length}}個活動 <icon name="down" class="icon4"></icon></span></div>
                  <div class="mytab">
                      <div @click="shoporscore=true" :class="{ on:shoporscore }">商品</div>
                      <div @click="shoporscore=false" :class="{ on:!shoporscore }">評價{{shopinfo.rating}}分</div>
                  </div>
              </div>

          <transition name="left">
              <div v-if="shoporscore" class="shopmain">
                  <div class="mianleft">
                      <div v-for="(item,index) in shopmean" @click="itemgo(index)" :class="{on:index==shopon}" class="leftdiv">
                          <div >
                              <icon v-if="index==0" class="icon5" name="hot"></icon>
                              <icon v-if="index==1" class="icon5" name="discount"></icon>
                              <span class="fs0-8">{{item.name}}</span>
                          </div>
                      </div>
                  </div>
                  <div class="mainright">
                      <div class="item" v-for="item in shopmean">
                          <div class="itemtop padtop10 ih30 after">
                              <span class="fs15">{{item.name}}</span>
                              <span class="fs0-8 col9f">{{item.description}}</span>
                          </div>
                          <div class="itemmain">
                              <div v-for="items in item.foods" class="iteminfo after">
                                  <div class="infoimgbox">
                                      <img :src="imgpath+items.image_path">
                                  </div>
                                  <div class="inforight">
                                      <div class="fs15 ih20">{{items.name}}</div>
                                      <div class="ih15 col9f"><span class="fs10 mgl">{{items.tips}}</span></div>
                                      <div class="ih15"><span v-if="false" class="fs10 mgl"><span class="zk">包裝費</span><span class="yh">{{}}</span></span></div>
                                      <div class="ih20">
                                        <span class="colred fs12">¥</span>
                                        <span class="colred mgr5">{{items.specfoods[0].price}}</span>
                                        <span v-if="items.specfoods[0].original_price" class="fs12 col9f midline">¥56</span>
                                        <icon v-if="items.specfoods.length==1" name="add" class="addicon right" ></icon>
                                        <span class="fs12 right gz" v-if="items.specfoods.length>1">選規則</span>
                                      </div>
                                  </div>
                              </div>
                          </div>
                      </div>
                  </div>
              </div>
          </transition>

          <transition name="left">
              <div v-if="shoporscore" class="foot">
                <div class="footleft">
                    <div class="footlogo"><icon name="footcar" class="footicon"></icon></div>
                    <div class="footmain">未選購商品</div>
                </div>
                <div class="footright">
                    ¥20起送
                </div>
              </div>
          </transition>

          <transition name="right">
              <div class="score" v-if="!shoporscore">
                  <div class="scoretop">
                    <div class="scoretopleft">
                        <div class="fs1-2 colf60">{{shopinfo.rating}}</div>
                        <div class="fs15 col9f">綜合評價</div>
                        <div class="fs0-8 col9f">高於周邊商家{{parseInt(scorerating.compare_rating*100)}}%</div>
                    </div>
                    <div class="scoretopright">
                        <div><span class="fs15 col9f mgr5">評價服務</span><stars :num="scorerating.service_score.toFixed(1)"></stars><span class="colf60 right">{{scorerating.service_score.toFixed(1)}}</span></div>
                        <div><span class="fs15 col9f mgr5">菜品評價</span><stars :num="scorerating.food_score.toFixed(1)"></stars><span class="colf60 right">{{scorerating.food_score.toFixed(1)}}</span></div>
                        <div><span class="fs15 col9f mgr5">送達時間</span><span class="fs15 colf60">{{scorerating.deliver_time}}分鐘</span></div>
                    </div>
                  </div>
                  <div class="scoremain">
                        <div class="scoremaintop after">
                          <div v-for="(item,index) in scoretags" class="ih30 fs0-8" :class="{sty2:item.unsatisfied,sty1:!(item.unsatisfied),on:index==scoreindex}">{{item.name}}({{item.count}})</div>
                        </div>
                        <div class="scoremaininfo">
                            <div v-for="item in score" class="scoreitem after">
                                <div class="scoreitemleft">
                                    <img :src="imgaddpath(item.avatar)" >
                                </div>
                                <div class="scoreitemright fs12 col9f">
                                    <div>
                                        <span>{{item.username}}</span>
                                        <span class="right">{{item.rated_at}}</span>
                                    </div>
                                    <div>
                                        <stars :num="item.rating_star"></stars>
                                    </div>
                                    <div>
                                        {{item.time_spent_desc}}
                                    </div>
                                    <div class="scoreimgbox">
                                      <img v-for="itema in item.item_ratings" :src="imgaddpath(itema.image_hash)">
                                    </div>
                                    <div class="namebox">
                                        <div v-for="itemb in item.item_ratings">{{itemb.food_name}}</div>
                                    </div>

                                </div>
                            </div>
                          
                        </div>
                  </div>
              </div>
          </transition>

          <transition name="top">
              <div v-if="modal" class="modal flex2 colfff pad10">
                  <div class="modaltop flex1">
                    <div>
                      <div class="modaltitle">
                          {{shopinfo.name}}
                      </div>
                      <div class="modalmid">
                            <div class="modal_title ih30"><span>優惠信息</span></div>
                            <div>
                                <div v-if="shopinfo.activities" v-for="item in shopinfo.activities" class="midtop"><span class="te mgr5">{{item.icon_name}}</span><span>{{item.description}}</span></div>
                            </div>
                      </div>
                      <div class="modalinfo mgtop40">
                            <div class="modal_title ih30"><span>商家公告</span></div>
                            <div> 
                                {{shopinfo.promotion_info}}  
                            </div>
                      </div>
                    </div>
                  </div>
                  <div @click="modal=false" class="modalfoot">
                        <span>X</span>
                  </div>
              </div>
          </transition>

          <load v-if="num!=1"></load>
    </div>

    <router-view></router-view>
  </div>
</template>

bigdiv的css以下git

.big{
  display:-webkit-box;
  -webkit-box-orient:vertical;
  height:100vh;
}

結果以下(需滑動滾動條)
圖片描述github

5.這裏有一個很嚴重的問題,就是shopDetail頁面與shop頁面顯示在一塊兒,而咱們但願它是分開的。
shop頁面到shopDetail頁面,惟一改變的就是路由的改變,因此咱們來監聽路由的變化,來控制顯示哪個組件。web

6.路由爲/shop時,顯示bigdiv。路由爲/shop/shopDetail時,隱藏bigdiv,來展現router-view內容。
data中新增變量myrouter來控制bigdiv顯示隱藏segmentfault

data () {
    return {
      shopon:0,                                 //商品種類選中的哪一個
      imgpath:'http://cangdu.org:8001/img/',    //商家頭像的路徑地址path
      shopinfo:"",                              //商家信息
      shopmean:"",                              //食品信息
      shoporscore:true,                         //商家仍是評價
      score:"",                                 //評價信息
      scorerating:"",                           //評價分數  
      scoretags:"",                             //評價分類
      scoreindex:0,                             //選中第幾個評價分類
      num:1,
      modal:false,                              //模態框顯示隱藏
      myrouter:true                             //是否顯示big div
    }
  },

bigdiv中加v-if來判斷緩存

<div v-if="myrouter" class="big">

剩下就是改變myrouter來控制bigdiv。
在shop.vue的js的watch中監聽路由變化安全

watch:{
       "$route":"newpage",
  }

當路由改變時,運行newpage函數。在methods添加newpage函數

newpage:function(){
        this.myrouter=(this.$route.path=="/shop"?true:false);
}

ok!運行試試
圖片描述

沒毛病!

7.shopDetail頁面UI圖
圖片描述

shopDetail.vue修改以下

<template>
  <div class="padtop50 bgf5">
      <mt-header fixed class="fs1-2" title="商家詳情">
          <router-link to="/shop" slot="left">
              <mt-button icon="back"></mt-button>
          </router-link>
      </mt-header>

      <div class="maina bgfff">
          <mt-cell class="after" title="活動與屬性"></mt-cell>
          <div class="pad10">
              <div class="ih30 fs0-8 ">
                  <span class="colfff myicon bgcolred mgr5">減</span>
                  <span class="col9f">滿30減5,滿60減8</span>
              </div>
              <div class="ih30 fs0-8 ">
                  <span class="colfff myicon bgcolred mgr5">減</span>
                  <span class="col9f">滿30減5,滿60減8</span>
              </div>
              <div class="ih30 fs0-8 ">
                  <span class="colfff myicon bgcolred mgr5">減</span>
                  <span class="col9f">滿30減5,滿60減8</span>
              </div>
              <div class="ih30 fs0-8 ">
                  <span class="colfff myicon bgcolred mgr5">減</span>
                  <span class="col9f">滿30減5,滿60減8</span>
              </div>
          </div>
      </div>

      <div class="mgtop10 bgfff">
          <mt-cell class="after" title="食品監督安全公示" to="//github.com" is-link value="企業認證詳情"></mt-cell>
          <div class="pad10 flex">
                <div class="w60 mgr5">
                     <img class="">
                </div>
                <div class="flex1">
                      <div class="ih30"><span class="col9f">督查檢查結果:</span><span class="colred">差</span></div>
                      <div class="ih30"><span class="col9f">檢查日期:</span><span class="col9f">2017-02-03</span></div>
                </div>
          </div>
      </div>

      <div class="mgtop10 bgfff">
          <mt-cell class="after" title="商家信息"></mt-cell>
          <div class="shopmain fs0-8">
            <div class="ih50 after padr10">
                <span>商家名稱:效果演示</span>
            </div>
            <div class="ih50 after padr10">
                <span>地址:上海市江岸區</span>
            </div>
            <div class="ih50 after padr10">
                <span>營業時間:9:30-22:00</span>
            </div>
            <div class="ih50 after padr10">
                <span>營業執照</span>
                <span class="right"><icon class="w15 col9f" name="right"></icon></span>
            </div>
            <div class="ih50 after padr10">
                <span>餐飲服務許可證</span>
                <span class="right"><icon class="w15 col9f" name="right"></icon></span>
            </div>
          </div>
      </div>

  </div>
</template>

<script>


export default {
  data () {
    return {
      
    }
  },
  components:{
  //註冊組件
      
  },
  mounted:function(){
  //生命週期

  },
  computed:{
  //計算屬性

  },
  methods:{
  //函數
  
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

.myicon{
  padding:0px 2px;
  border-radius:3px;
}
.bgcolred{
  background-color:red;
}
.shopmain{
  box-sizing:border-box;
  padding-left:10px;
}
</style>

頁面以下
圖片描述

沒有寫那個紅色的巨大表情我想API應該會給我們傳,不傳的話我們再本身寫。

8.添加過渡動畫,將bigdiv寫在下面代碼內便可(原本想給router-view添加動畫,可是隻顯示進入動畫,不顯示離開動畫,動畫在上一章已寫好)

<transition name="left">

</transition>

結果以下
圖片描述

相關文章
相關標籤/搜索