10-08-vue-router路由基础、嵌套、动态、编程路由、命名、别名、视图、组件复用代码

路由的基本使用和嵌套

import Vue from "vue";
import VueRouter from "vue-router";
import Index from "../views/Index"
import Setting from "../views/Setting"
import Setting_1 from "../views/Setting_1"
import Setting_2 from "../views/Setting_2"
Vue.use(VueRouter)

export default new VueRouter({
    mode:"history",
    routes:[
        { path:"/",component: Index},
        {
            path:"/setting",
            component: Setting,
            children:[
                { path:"/setting/setting_1",component: Setting_1},
                { path:"/setting/setting_2",component: Setting_2},
            ]
        },
    ]
})

卖座网基本路由和嵌套

App.vue文件

<template>
  <div id="app">
      <!--
       a标签的问题:
        1)href="/#/films"
        2)如果在地址栏中直接访问路由
      -->
      <!-- 声明式导航 -->
      <!--<a href="/#/films" :class="{current:current=='films'}" @click="current='films'">电影</a> |
      <a href="/#/cinemas" :class="{current:current=='cinemas'}" @click="current='cinemas'">影院</a> |
      <a href="/#/center" :class="{current:current=='center'}" @click="current='center'">我的</a>-->

      <!--tag="li" 渲染router-link时,渲染成li标签-->
      <!-- 声明式导航 -->
      <router-link to="/films" tag="li" active-class="current">电影</router-link>
      <router-link to="/cinemas" tag="li" active-class="current">影院</router-link>
      <router-link to="/center" tag="li" active-class="current">我的</router-link>

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

<script>
export default {
    name: 'App',
    data(){
      return{
          current:"films",
      }
    },
   components: {
   }
}
</script>

<style scoped>
    .current{
        color: red;
    }
</style>

index.js路由文件

import Vue from "vue"
import VueRouter from "vue-router"

import Film from "../views/Film";
import Cinemas from "../views/Cinemas";
import Center from "../views/Center";
import CommingSoon from "../views/film/CommingSoon";
import NowPlaying from "../views/film/NowPlaying";

Vue.use(VueRouter)

export default new VueRouter({
    mode:"hash",
    routes:[
        {
            path:"/films",
            component:Film,
            children:[
                /*{path:"/films/nowPlaying",component:NowPlaying},*/
                /*{path:"/films/comingSoon",component:ComingSoon},*/
                {path:"nowPlaying",component:NowPlaying},
                {path:"commingSoon",component:CommingSoon},
            ]
        },
        {path:"/cinemas",component:Cinemas},
        {path:"/center",component:Center},
        {path:"*",redirect:"/films"},
    ]
})

卖座网核心vue

cart.vue

<template>
    <div>
        <!--头部区域-->
        <header class="header">
            <a href="index.html" class="icon-back"></a>
            <h3>购物车</h3>
            <a href="" class="icon-menu"></a>
        </header>
        <!--安全提示-->
        <section class="jd-safe-tip">
            <p class="tip-word">
                您正在安全购物环境中,请放心购物
            </p>
        </section>
        <!--中间内容-->
        <main class="jd-shop-cart-list">
            <section>
                <div class="shop-cart-list-title">
                    <div class="left">
                        <a href="javascript:;" class="cart-check-box" checked></a>
                        <span class="cart-logo"></span>
                        <span class="cart-title">京东自营</span>
                    </div>
                    <span class="right">您享受满100元免运费服务</span>
                </div>
                <!-- 以后,使用v-for,必须加上:key=“唯一值"  :key="shop.shopId" -->
                <div class="shop-cart-list-con" v-for="(shop,index) in shopList" :key="shop.shopId">
                    <div class="left">
                        <a href="javascript:;" class="cart-check-box"
                           :checked="shop.checked"
                           @click.prevent="singeShopSeclected(shop)"
                        ></a>
                    </div>
                    <div class="center">
                        <img :src="shop.shopImage" alt="">
                    </div>
                    <div class="right">
                        <a href="#">{{shop.shopName}}</a>
                        <div>
                            <div class="shop-price">{{ shop.shopPrice | moneyFormat}} <span style="color: red;font-size: 18px">{{ shop.shopPrice*shop.shopNumber | moneyFormat}}</span></div>
                        </div>
                        <div class="shop-deal">
                            <span @click="singerShopPrice(shop,false)">-</span>
                            <!--<input type="number" disabled :value="shop.shopNumber">-->
                            <input type="number" disabled v-model="shop.shopNumber">
                            <span @click="singerShopPrice(shop,true)">+</span>
                        </div>
                        <div class="shop-deal-right" @click="clickTrash(shop,$event)">
                            <span></span>
                            <span></span>
                        </div>
                    </div>
                </div>
            </section>
        </main>
        <!--面板-->
        <div ref="panel" class="panel" style="display: none;">
            <div class="panel-content">
                <div class="panel-title">您确认删除这个商品吗?</div>
                <div class="panel-footer">
                    <a href="javascript:;" class="cancel" @click.prevent="hidePanel()">取消</a>
                    <a href="javascript:;" class="submit" @click.prevent="delShop()">确定</a>
                </div>
            </div>
        </div>
        <!--底部通栏-->
        <div id="tab_bar">
            <div class="tab-bar-left">
                <a href="javascript:;"
                   class="cart-check-box"
                   :checked="isSelectedAll"
                   @click="selectAll(isSelectedAll)"
                ></a>
                <span style="font-size: 16px;">全选</span>
                <div class="select-all">
                    合计:<span class="total-price">{{totalPrice | moneyFormat}}</span>
                </div>
            </div>
            <div class="tab-bar-right">
                <a href="index.html" class="pay">去结算</a>
            </div>
        </div>
    </div>
</template>

<script>
    import './../assets/css/base.css'
    import '../assets/css/cart.css'
    import axios from 'axios'
    export default {
        name: "Cart",
        data(){
            return {
                // 数据写在data中,vue就会监听它
                // 只有监听到,数据发生改变了,vue会帮我们自动刷新视图
                shopList:[], // 保存商品数据
                isSelectedAll:false, // 控制全选按钮是否被选中
                totalPrice:0, // 选中商品的总价
                up:null, // 垃圾桶的盖子
                currentDelShop:null, // 要删除的商品
            }
        },
        created() {
            this.getProduct();
        },
        methods: {
            // ajax获取商品数据
            getProduct(){
               /* axios.get("https://mockapi.eolinker.com/2ZhGVxjacb39010e6753bd9c02ee803e6e3bfeab6e8007c/data").then(response=>{
                    // console.log(response)
                    if(response.data.status == 200){
                        let shopList = response.data.result.shopList
                        /!*console.log(shopList)*!/
                        this.shopList = shopList;
                    }
                }).catch(error=>{
                    alert("网络错误~")
                })*/
                axios.get("http://localhost:8080/data.json").then(response=>{
                    // console.log(response)
                    if(response.data.status == 200){
                        let shopList = response.data.result.shopList
                        /*console.log(shopList)*/
                        this.shopList = shopList;
                    }
                }).catch(error=>{
                    alert("网络错误~")
                })
            },
            // 单个商品的加减
            singerShopPrice(shop,flag){
                if(flag){
                    // 点击了+
                    /*  shop.shopNumber = shop.shopNumber + 1;*/
                    shop.shopNumber += 1;
                }else{
                    // 点击了-
                    if(shop.shopNumber <= 1){
                        shop.shopNumber = 1;
                        alert("只有一件商品了,不能减了~")
                        return;
                    }
                    shop.shopNumber -= 1;
                }
                this.getAllShopPrice(); // 计算选中商品的总价
            },
            // 全选与反选
            selectAll(flag){
                this.isSelectedAll = !flag
                this.shopList.forEach((item,index)=>{
                    // 没有check属性,需要添加一个check属性
                    if(item.checked == undefined){
                        // 没有这个属性  item代表这个商品  需要给这个商品添加checked属性
                        // 我们添加这个checked属性,我们学想让vue监听它。
                        // 要想让vue监听到你添加的属性,必须使用vue提供的api  $set
                        this.$set(item,'checked',!flag);
                    }else{
                        // item中默认就有checked属性  不需要监听了
                        item.checked = !flag;
                    }
                })
                this.getAllShopPrice(); // 计算选中商品的总价
            },
            // 单个商品的选中与否
            singeShopSeclected(shop){
                if (shop.checked == undefined){
                    this.$set(shop,"checked",true)
                }else{
                    shop.checked = !shop.checked;
                }
                this.hasSelectedAll(); // 判断全选按钮是否要被选中
                this.getAllShopPrice(); // 计算选中商品的总价
            },
            // 当每一个商品都选中了,需要让全选按钮也被选中
            hasSelectedAll(){
                let flag = true;
                this.shopList.forEach(item=>{
                    if(!item.checked){
                        // 说明有商品没有被选中
                        flag = false;
                    }
                })
                this.isSelectedAll = flag && this.shopList.length>0;
            },
            // 计算总价
            getAllShopPrice(){
                let tPrice = 0;
                this.shopList.forEach(item=>{
                    if(item.checked){
                        tPrice += item.shopNumber*item.shopPrice;
                    }
                })
                this.totalPrice = tPrice;
            },
            // 点击垃圾桶
            clickTrash(shop,e){
                let up = e.target.parentNode.firstElementChild; // up指垃圾桶的盖子
                this.up = up;

                // 过渡动画
                up.style.transition = "all .3s ease"

                // 过渡动画   变形动画   自定义动画
                // 先突变后过渡
                // 改变科旋转中心
                up.style.transformOrigin = "left bottom"
                up.style.transform = "rotate(-45deg)"

                // 让panel显示
                this.$refs.panel.style.display = "block";
                // this.$refs.panel.className = "panel-content jump";

                // 记录你要删除的商品
                this.currentDelShop = shop;

            },
            // 点击了取消
            hidePanel(){
                this.$refs.panel.style.display = "none";

                // 盖上盖子
                this.up.style.transformOrigin = "left bottom"
                this.up.style.transform = "rotate(0deg)"
            },
            // 点击了确定
            delShop(){
                this.$refs.panel.style.display = "none";
                let index = this.shopList.indexOf(this.currentDelShop);
                console.log(index)
                if(index !== -1){
                    this.shopList.splice(index,1)
                }
                // 重新计算总价
                this.getAllShopPrice();
                // 当删除商品时,还需要判断全选按钮是否需要全选
                this.hasSelectedAll();
            },
        },
        filters:{
            // 定义了一个过滤器,专六对价格进行过滤
            moneyFormat(money){
                /*3299  ---> ¥3299.00*/
                return `¥${Number(money).toFixed(2)}`
            }
        }
    }
</script>



卖座网的动态路由和编程路由

index.js路由文件

import Vue from "vue"
import VueRouter from "vue-router"

import Film from "../views/Film";
import Cinemas from "../views/Cinemas";
import Center from "../views/Center";
import CommingSoon from "../views/film/CommingSoon";
import NowPlaying from "../views/film/NowPlaying";
import Detail from "../views/detail/Detail";

Vue.use(VueRouter)

export default new VueRouter({
    mode:"hash",
    routes:[
        {
            path:"/films",
            component:Film,
            children:[
                {path:"nowPlaying",component:NowPlaying},
                {path:"commingSoon",component:CommingSoon},
                {path:"",redirect:"nowPlaying"},
            ]
        },
        {path:"/cinemas",component:Cinemas},
        {path:"/center",component:Center},
        {path:"/detail/:myid",component:Detail},
        {path:"*",redirect:"/films"},
    ]
})

Detail.vue文件

<template>
    <div>
        这是{{$route.params.myid}}电影的详情
        <!-- 根据ID发起ajax请求,获取此电影详情 -->
    </div>
</template>

<script>
    export default {
        name: "Detail",

    }
</script>

<style scoped>

</style>

NowPlaying.vue文件

<template>
    <div>
        正在热映的电影
        <ul>
            <li
               v-for="(item,index) in films"
               :key="item.filmId"
               @click="toDetail(item.filmId)"
            >{{item.name}}</li>
        </ul>
    </div>
</template>

<script>
    export default {
        name: "NowPlaying",
        data(){
            return{
                films:[
                    {filmId: 1001,name:"热映电影1"},
                    {filmId: 1002,name:"热映电影2"},
                    {filmId: 1003,name:"热映电影3"},
                    {filmId: 1004,name:"热映电影4"},
                    {filmId: 1005,name:"热映电影5"},
                ]
            }
        },
        methods:{
            toDetail(id){
                // 编程式路由  $route后面跟属性    $router后面跟方法
                // this.$router.push("/detail")  只是跳到/detail路由
                this.$router.push({path:`/detail/${id}`})  // 跳到/detail/1002路由
                // this.$router.push({path:"/detail",params:id})   // 跳到/detail路由,并且传递id数据到Detail组件
            }
        }
    }
</script>

<style scoped>

</style>

命名路由和路由的别名

App.vue文件

<template>
  <div id="app">
      <router-link to="/films" tag="li" active-class="current">电影</router-link>
      <!--<router-link to="/cinemas" tag="li" active-class="current">影院</router-link>-->
      <router-link to="/yingyuan" tag="li" active-class="current">影院</router-link>
      <router-link to="/center" tag="li" active-class="current">我的</router-link>
      <router-view></router-view>
  </div>
</template>

<script>
export default {
    name: 'App',
    data(){
      return{
          current:"films",
      }
    },
   components: {
   }
}
</script>

<style scoped>

    .current{
        color: red;
    }
</style>

index.js路由文件

import Vue from "vue"
import VueRouter from "vue-router"

import Film from "../views/Film";
import Cinemas from "../views/Cinemas";
import Center from "../views/Center";
import CommingSoon from "../views/film/CommingSoon";
import NowPlaying from "../views/film/NowPlaying";
import Detail from "../views/detail/Detail";

Vue.use(VueRouter)

export default new VueRouter({
    mode:"hash",
    routes:[
        {
            path:"/films",
            component:Film,
            children:[
                {path:"nowPlaying",component:NowPlaying},
                {path:"commingSoon",component:CommingSoon},
                {path:"",redirect:"nowPlaying"},
            ]
        },
        {path:"/cinemas",component:Cinemas,alias:"/yingyuan"},
        {path:"/center",component:Center},
        {
            path:"/detail/:myid",
            name:"detail",  // 给当前的路由起一个名字
            component:Detail,
        },
        {path:"*",redirect:"/films"},
    ]
})

命名视图

App.vue文件

<template>
  <div id="app">
      <div class="header"><router-view name="Header"></router-view></div>
      <div class="body">
          <div class="sidebar"><router-view name="Sidebar"></router-view></div>
          <div class="main"><router-view name="Main"></router-view></div>
      </div>
      <div class="footer"><router-view name="Footer"></router-view></div>
      <router-view></router-view>
      <router-view></router-view>
      <router-view></router-view>
      <router-view></router-view>
      <router-view></router-view>
  </div>
</template>

<script>
export default {
    name: 'App',
    data(){
      return{
          current:"films",
      }
    },
   components: {
   }
}
</script>

<style scoped>

    .current{
        color: red;
    }
</style>

index.js路由文件

import Vue from "vue"
import VueRouter from "vue-router"
import NotFount from "../views/NotFount"
import Header from "../views/Header"
import Sidebar from "../views/Sidebar"
import Main from "../views/Main"
import Footer from "../views/Footer"
Vue.use(VueRouter)

export default new VueRouter({
    mode:"hash",
    routes:[
        { path:"/",components:{ Header,Sidebar,Main,Footer  } },
        { path:"*",component:NotFount }  // 配置404页面
    ]
})

组件复用

<template>
    <h1>{{$route.params.userName}}的个人中心</h1>
</template>

<script>
    export default {
        name: "Profile",
        data(){return { firstName:"" }},
        mounted() {  // 因为这个组件会被缓存起来,vue为了提升性能
            // 就想在mouted勾子中获取用户名,我要根据用户名发起ajax请求
            // console.log(this.$route.params.userName)
            // 我需要拿着用户名去请求服务器
        },
        /*watch:{
            firstName(){},
            $route(to,from){
               /!* console.log("to:",to)
                console.log("from:",from)*!/
                // console.log(to.params.userName)

                // 发起ajax请求
            }
        }*/
        beforeRouteUpdate(to,from,next){  // 这是一个路由的钩子
            // 当路由变化,自动地执行这个钩子函数
            console.log(to.params.userName)
            next();
        }
    }
</script>

<style scoped>

</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值