Vue总结4-插槽,Vuex,VueRouter

1.插槽

  • 1.1匿名插槽

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>52-Vue组件-匿名插槽</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    <!--
    1.什么是插槽?
    默认情况下使用子组件时在子组件中编写的元素是不会被渲染的
    如果子组件中有部分内容是使用时才确定的, 那么我们就可以使用插槽
    插槽就是在子组件中放一个"坑", 以后由父组件来"填"
    
    1.什么是匿名插槽
    没有名字的插槽, 会利用使用时指定的内容替换整个插槽
    注意点: 如果有多个匿名插槽, 每一个匿名插槽都会被指定的内容替换
            虽然写多个匿名插槽不会报错, 但是在企业开发中推荐只能有一个匿名插槽
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
            <!--需求: 在使用子组件的时候给子组件动态的添加一些内容-->
            <son>
                <!--注意点: 默认情况下是不能在使用子组件的时候, 给子组件动态的添加内容的
                            如果想在使用子组件的时候, 给子组件动态的添加内容, 那么就必须使用插槽-->
                <div>我是追加的内容1</div>
                <div>我是追加的内容2</div>
                <div>我是追加的内容3</div>
            </son>
        </div>
    </template>
    <template id="son">
        <div>
            <div>我是头部</div>
            <!--这里的slot标签就是插槽, 插槽其实就是一个坑
                只要有了这个坑, 那么以后使用者就可以根据自己的需要来填这个坑-->
            <!--注意点: 插槽可以指定默认数据, 如果使用者没有填这个坑, 那么就会显示默认数据
                        如果使用者填了这个坑, 那么就会利用使用者填坑的内容替换整个插槽-->
            <!--匿名插槽的特点: 有多少个匿名插槽, 填充的数据就会被拷贝几份,如下会将son中追加的内容填写两份
                                虽然我们可以指定多个匿名插槽, 但是在企业开发中推荐只写一个匿名插槽-->
            <slot>我是默认数据</slot>
            <slot>我是默认数据</slot>
            <div>我是底部</div>
        </div>
    </template>
    <script>
        // 父组件
        Vue.component("father", {
            template: "#father",
            // 子组件
            components: {
                "son": {
                    template: "#son",
                }
            }
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app'
        });
    </script>
    </body>
    </html>
    
  • 1.2 具名插槽

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>53-Vue组件-具名插槽</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    <!--
    1.什么是具名插槽
    默认情况下有多少个匿名插槽, 我们填充的数据就会被拷贝多少份
    这导致了所有插槽中填充的内容都是一样的
    那么如果我们想给不同的插槽中填充不同的内容怎么办呢?
    这个时候就可以使用具名插槽
    
    2.具名插槽使用
    通过插槽的name属性给插槽指定名称
    在使用时可以通过slot="name"方式, 指定当前内容用于替换哪一个插槽
    
    注意点: 如果没有指定要替换哪个插槽中的内容, 则不会被替换
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
            <son>
                <!--这里通过slot属性告诉Vue,当前的内容是要填充到哪一个插槽中的-->
                <div slot="one">我是追加的内容1</div>
                <div slot="one">我是追加的内容11</div>
                <div slot="two">我是追加的内容2</div>
                <div slot="two">我是追加的内容22</div>
            </son>
        </div>
    </template>
    <template id="son">
        <div>
            <div>我是头部</div>
            <!--可以在定义插槽的时候给插槽添加一个name属性, 通过这个name属性来指定插槽的名称
                如通插槽指定了名称, 那么我们就称之为具名插槽-->
            <!--注意点: 默认情况下填充的内容是不会被填充到具名插槽中的,
                只有给填充的内容指定了要填充到哪一个具名插槽之后,
                才会将填充的内容填充到具名插槽中-->
            <slot name="one">我是默认内容</slot>
            <slot name="two">我是默认内容</slot>
            <div>我是底部</div>
        </div>
    </template>
    <script>
        // 父组件
        Vue.component("father", {
            template: "#father",
            // 子组件
            components: {
                "son": {
                    template: "#son",
                }
            }
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app'
       
        });
    </script>
    </body>
    </html>
    
  • 1.3 v-slot

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>54-Vue组件-v-slot指令</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    <!--
    1.什么是v-slot指令?
    v-slot指令是Vue2.6中用于替代slot属性的一个指令
    在Vue2.6之前, 我们通过slot属性告诉Vue当前内容填充到哪一个具名插槽
    从Vue2.6开始, 我们通过v-slot指令告诉Vue当前内容填充到哪一个具名插槽
    
    注意点: v-slot指令只能用在template标签上
            可以使用#号替代v-slot:
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
            <son>
                <!--
                <template v-slot:one>
                    <div>我是追加的内容1</div>
                    <div>我是追加的内容11</div>
                </template>
                <template v-slot:two>
                    <div>我是追加的内容2</div>
                    <div>我是追加的内容22</div>
                </template>
                -->
                <!--v-bind: :  v-on: @-->
                <template #one>
                    <div>我是追加的内容1</div>
                    <div>我是追加的内容11</div>
                </template>
                <template #two>
                    <div>我是追加的内容2</div>
                    <div>我是追加的内容22</div>
                </template>
            </son>
        </div>
    </template>
    <template id="son">
        <div>
            <div>我是头部</div>
            <slot name="one">我是one默认内容</slot>
            <slot name="two">我是two默认内容</slot>
            <div>我是底部</div>
        </div>
    </template>
    <script>
        // 父组件
        Vue.component("father", {
            template: "#father",
            // 子组件
            components: {
                "son": {
                    template: "#son",
                }
            }
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app'
        });
    </script>
    </body>
    </html>
    
  • 1.4 作用域插槽

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>55-Vue组件-作用域插槽</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    <!--
    1.什么是作用域插槽
    作用域插槽就是带数据的插槽, 就是让父组件在填充子组件插槽内容时也能使用子组件的数据
    
    2.如何使用作用域插槽
    2.1在slot中通过 v-bind:数据名称="数据名称" 方式暴露数据
    2.2在父组件中通过 <template slot-scope="作用域名称"> 接收数据
    2.3在父组件的<template></template>中通过 作用域名称.数据名称 方式使用数据
    
    3.通过v-slot来使用作用域插槽
    在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。
    它取代了 slot 和 slot-scope
    
    也就是说我们除了可以不仅可以通过v-slot指令告诉Vue内容要填充到哪一个具名插槽中
    还可以通过v-slot指令告诉Vue如何接收作用域插槽暴露的数据
    
    v-slot:插槽名称="作用域名称"
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
            <son>
                <!--
              1.使用slot-scope来接收数据
                slot-scope="abc"作用: 接收子组件插槽暴露的数据
                作用域插槽的应用场景: 子组件提供数据, 父组件决定如何渲染
                -->
                <template slot-scope="abc">
                    <li v-for="(name, index) in abc.names">{{name}}</li>
                </template>
                <!--
              2.使用v-slot来接收数据
                
                作用域插槽的应用场景: 子组件提供数据, 父组件决定如何渲染
                -->
                 <template #one="abc">
                    <li v-for="(name, index) in abc.names">{{name}}</li>
                </template>
            </son>
        </div>
    </template>
    <template id="son">
        <div>
            <div>我是头部 {{names}}</div>
            <!--
            v-bind:names="names"作用: 将当前子组件的names数据暴露给父组件
            -->
            <slot v-bind:names="names">我是默认内容 {{names}}</slot>
            <div>我是底部</div>
        </div>
    </template>
    <script>
        // 父组件
        Vue.component("father", {
            template: "#father",
            // 子组件
            components: {
                "son": {
                    template: "#son",
                    data:function () {
                        return {
                            names: ["zs", "ls", "ww", "zl"]
                        }
                    }
                }
            }
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app'     
        });
    </script>
    </body>
    </html>
    

2.Vuex--共享数据

  • 2.1 传统传递数据

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>57-Vuex-基本使用</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    <!--
    1.什么是Vuex?
    vuex 是 Vue 配套的 公共数据管理工具,它可以把一些共享的数据,保存到 vuex 中,
    方便整个程序中的任何组件直接获取或修改我们的公共数据
    
    注意点:
    只有需要共享的才放到vuex上, 不需要共享的数据依然放到组件自身的data上
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
            <son1 @parentchange="change"></son1>
            <son2 :parentnum="num"></son2>
        </div>
    </template>
    <template id="son1">
        <div>
            <!--需求: 在第一个子组件中添加两个按钮和一个输入框, 要求通过按钮控制输入框中的数据+1和-1-->
            <button @click="add">增加</button>
            <button @click="sub">减少</button>
            <input type="text" :value="count">
        </div>
    </template>
    <template id="son2">
        <div>
            <!--需求: 在第二个子组件中展示第一个子组件中的数据-->
            <!--
            注意点:
            1.如果想要在子组件中使用父组件中的数据, 那么必须通过父组件传递
            2.如果想要在子组件中使用祖先组件中的数据, 那么就必须一层一层的传递
            3.兄弟组件之间不能直接传递数据, 如果兄弟组件之间想要传递数据, 那么就必须借助父组件
            -->
            <!--
            注意点:
            虽然通过借助父组件能够实现兄弟组件之间的数据传递, 但是这种方式非常的复杂, 非常的不推荐
            那么当前在企业开发中我们遇到了两个问题:
            1.如果想要在子组件中使用祖先组件中的数据, 那么就必须一层一层的传递(非常麻烦)
            2.兄弟组件之间不能直接传递数据, 如果兄弟组件之间想要传递数据, 那么就必须借助父组件(非常麻烦)
            解决方案: 使用Vuex
            -->
            <p>{{parentnum}}</p>
        </div>
    </template>
    <script>
        // 爸爸组件
        Vue.component("father", {
            template: "#father",
            data: function(){
                return {
                    num: 0
                }
            },
            methods: {
                change(newCount){
                    this.num = newCount;
                }
            },
            // 儿子组件
            components: {
                "son1": {
                    template: "#son1",
                    data: function () {
                        return {
                            count: 0
                        }
                    },
                    methods: {
                        add(){
                            /*
                            如何实现儿子中的数据和父亲中的数据同步
                            1.父亲给儿子传递一个方法
                            2.在儿子中修改数据
                            3.儿子中修改完数据, 调用父亲传递过来的方法, 并且将修改之后的数据传递给父亲的方法
                            4.在父亲的方法中保存最新的数据
                            * */
                            this.count = this.count + 1;
                            this.$emit("parentchange", this.count);
                        },
                        sub(){
                            this.count = this.count - 1;
                            this.$emit("parentchange", this.count);
                        }
                    }
                },
                "son2": {
                    template: "#son2",
                    props: ["parentnum"]
                }
            }
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 这里就是MVVM中的Model
            data: {
            },
            // 专门用于存储监听事件回调函数
            methods: {
            },
            // 专门用于定义计算属性的
            computed: {
            },
            // 专门用于定义局部组件的
            components: {
            }
        });
    </script>
    </body>
    </html>
    
  • 2.2 通过Vuex来共享数据

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>58-Vuex-共享数据</title>
        <script src="js/vue.js"></script>
        <!--1.导入Vuex-->
        <!--注意点: 在导入Vuex之前必须先导入Vue-->
        <script src="js/vuex.js"></script>
    </head>
    <body>
    <!--
    1.当前在企业开发中我们遇到了两个问题:
    1.如果想要在子组件中使用祖先组件中的数据, 那么就必须一层一层的传递(非常麻烦)
    2.兄弟组件之间不能直接传递数据, 如果兄弟组件之间想要传递数据, 那么就必须借助父组件(非常麻烦)
    解决方案: 使用Vuex
    
    注意点:
    必须在引入Vue之后再引入Vuex
    只有需要共享的才放到vuex上, 不需要共享的数据依然放到组件自身的data上
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <grandfather></grandfather>
    </div>
    <template id="grandfather">
        <div>
            <p>{{this.$store.state.msg}}</p>
            <father></father>
        </div>
    </template>
    <template id="father">
        <div>
            <!--4.在使用Vuex中保存的共享数据的时候, 必须通过如下的格式来使用-->
            <p>{{this.$store.state.msg}}</p>
            <son></son>
        </div>
    </template>
    <template id="son">
        <div>
            <p>{{this.$store.state.msg}}</p>
        </div>
    </template>
    
    <script>
        // 2.创建Vuex对象
        const store = new Vuex.Store({
            // 这里的state就相当于组件中的data, 就是专门用于保存共享数据的
            state: {
                msg: "twc"
            },
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 这里就是MVVM中的Model
            data: {
            },
            // 专门用于存储监听事件回调函数
            methods: {
            },
            // 专门用于定义计算属性的
            computed: {
            },
            // 专门用于定义局部组件的
            components: {
                "grandfather":{
                    template:"#grandfather",
                    // 3.在祖先组件中添加store的key保存Vuex对象
                    // 只要祖先组件中保存了Vuex对象 , 那么祖先组件和所有的后代组件就可以使用Vuex中保存的共享                   数据了
                    store:store,
                    components:{
                        "father":{
                            template:"#father",
                            components: {
                                "son": {
                                    template: "#son",
                                }
                            }
                        }
                    }
                }
            },
        });
    </script>
    </body>
    </html>
    
  • 2.3 修改Vuex共享数据

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>59-Vuex-修改共享数据</title>
        <script src="js/vue.js"></script>
        <script src="js/vuex.js"></script>
    </head>
    <body>
    <!--这里就是MVVM中的View-->
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
            <son1></son1>
            <son2></son2>
        </div>
    </template>
    <template id="son1">
        <div>
            <!--需求: 在第一个子组件中添加两个按钮和一个输入框, 要求通过按钮控制输入框中的数据+1和-1-->
            <button @click="add">增加</button>
            <button @click="sub">减少</button>
            <input type="text" :value="this.$store.state.count">
        </div>
    </template>
    <template id="son2">
        <div>
            <button @click="add">增加</button>
            <button @click="sub">减少</button>
            <input type="text" :value="this.$store.state.count">
        </div>
    </template>
    
    <script>
        const store = new Vuex.Store({
            // state: 用于保存共享数据
            state: {
                count: 0
            },
            // mutations: 用于保存修改共享数据的方法
            mutations: {
                // 注意点: 在执行mutations中定义的方法的时候, 系统会自动给这些方法传递一个state参数
                //         state中就保存了共享的数据
                mAdd(state){
                    state.count = state.count + 1;
                },
                mSub(state){
                    state.count = state.count - 1;
                }
            }
        });
        // 爸爸组件
        Vue.component("father", {
            template: "#father",
            store: store,
            // 儿子组件
            components: {
                "son1": {
                    template: "#son1",
                    methods: {
                        add(){
                            // 注意点: 在Vuex中不推荐直接修改共享数据
                            //我们可以通过this.$store.commit("方法名称")来调用mutation中的方法
                          
                            this.$store.commit("mAdd");
                        },
                        sub(){
                            
                            this.$store.commit("mSub");
                        }
                    }
                },
                "son2": {
                    template: "#son2",
                    methods: {
                        add(){
                        // 注意点: 在Vuex中不推荐直接修改共享数据
                        // 如果多个组件都修改了共享的数据, 那么后期数据发生了错误, 我们如果需要去调试错误
                        // 就需要把每一个修改了共享数据的组件都检查一遍, 这样非常低效, 非常的不利于我们去维护
                            // this.$store.state.count = this.$store.state.count + 1;(不行)
                            this.$store.commit("mAdd");
                        },
                        sub(){
                            // this.$store.state.count = this.$store.state.count - 1;
                            this.$store.commit("mSub");
                        }
                    }
                }
            }
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 这里就是MVVM中的Model
            data: {
            },
            // 专门用于存储监听事件回调函数
            methods: {
            },
            // 专门用于定义计算属性的
            computed: {
            },
            // 专门用于定义局部组件的
            components: {
            }
        });
    </script>
    </body>
    </html>
    
  • 2.4 Vuex中的getter

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>60-Vuex-getters</title>
        <script src="js/vue.js"></script>
        <script src="js/vuex.js"></script>
    </head>
    <body>
    <!--
    1.什么是Vuex的getters?
    Vuex的getters属性就和组件的计算属性一样, 会将数据缓存起来, 只有数据发生变化才会重新计算
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <father></father>
    </div>
    <template id="father">
        <div>
    <!--        {{this.$store.state.msg}} "www.it666.com"-->
    <!--        {{this.$store.state.msg}} "www.it666.com"-->
    <!--        {{this.$store.state.msg}} "www.it666.com"-->
            {{this.$store.getters.formart}}
            {{this.$store.getters.formart}}
            {{this.$store.getters.formart}}
        </div>
    </template>
    
    <script>
        const store = new Vuex.Store({
            // state: 用于保存共享数据
            state: {
                msg: "知播渔"
            },
            // mutations: 用于保存修改共享数据的方法
            mutations: {
            },
            getters: {
                formart(state){
                    console.log("getters方法被执行了");
                    return state.msg + "www.it666.com"
                }
            }
        });
        // 爸爸组件
        Vue.component("father", {
            template: "#father",
            store: store,
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 这里就是MVVM中的Model
            data: {
            },
            // 专门用于存储监听事件回调函数
            methods: {
            },
            // 专门用于定义计算属性的
            computed: {
            },
            // 专门用于定义局部组件的
            components: {
            }
        });
    </script>
    </body>
    </html>
    

3.VueRouter

  • 3.1 基本使用(通过a标签设置hash)

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>61-VueRouter-基本使用</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .onepage, .twopage{
                width: 500px;
                height: 500px;
            }
            .onepage{
                background: pink;
            }
            .twopage{
                background: skyblue;
            }
        </style>
        <script src="js/vue.js"></script>
        <!--1.导入Vue Router-->
        <!--注意点: 必须先导入Vue之后再导入Vue Router-->
        <script src="js/vue-router.js"></script>
    </head>
    <body>
    <!--
    1.什么是Vue Router?
    Vue Router和v-if/v-show一样, 是用来切换组件的显示的
    v-if/v-show是标记来切换(true/false)
    Vue Router用哈希来切换(#/xxx)
    比v-if/v-show强大的是Vue Router不仅仅能够切换组件的显示, 还能够在切换的时候传递参数
    
    2.Vue Router使用
    2.1导入Vue Router
    2.2定义路由规则
    2.3根据路由规则创建路由对象
    2.4将路径对象挂载到Vue实例中
    2.5修改URL哈希值
    2.6通过<router-view>渲染匹配的组件
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <a href="#/one">切换到第一个界面</a>
        <a href="#/two">切换到第二个界面</a>
        <!-- 路由出口 -->
        <!-- 路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    <template id="one">
        <div class="onepage">
            <p>我是第一个界面</p>
        </div>
    </template>
    <template id="two">
        <div class="twopage">
            <p>我是第二个界面</p>
        </div>
    </template>
    <script>
    
        // 1.定义组件
        const one = {
            template: "#one"
        };
        const two = {
            template: "#two"
        };
        // 2.定义切换的规则(定义路由规则)
        const routes = [
            // 数组中的每一个对象就是一条规则
            { path: '/one1', component: one },
            { path: '/two', component: two }
        ];
        // 3.根据自定义的切换规则创建路由对象
        const router = new VueRouter({
            routes: routes
        });
    
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 4.将创建好的路由对象绑定到Vue实例上
            router: router,
            // 这里就是MVVM中的Model
            data: {
            },
            // 专门用于存储监听事件回调函数
            methods: {
            },
            // 专门用于定义计算属性的
            computed: {
            },
            // 专门用于定义局部组件的
            components: {
                one: one,
                two: two
            }
        });
    </script>
    </body>
    </html>
    
  • 3.2 router-link设置hash

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>62-VueRouter-基本使用</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .onepage, .twopage{
                width: 500px;
                height: 500px;
            }
            .onepage{
                background: pink;
            }
            .twopage{
                background: skyblue;
            }
            /*.router-link-active{*/
            /*    background: red;*/
            /*}*/
            .nj-active{
                background: skyblue;
            }
        </style>
        <script src="js/vue.js"></script>
        <!--1.导入Vue Router-->
        <!--注意点: 必须先导入Vue之后再导入Vue Router-->
        <script src="js/vue-router.js"></script>
    </head>
    <body>
    <!--
    1.什么是router-link?
    通过a标签确实能设置URL的hash,但是这种方式并不专业
    在Vue Router中提供了一个专门用于设置hash的标签 router-link
    
    2.router-link特点
    默认情况下Vue会将router-link渲染成a标签, 但是我们可以通过tag来指定到底渲染成什么
    
    3.给router-link设置选中样式
    默认情况下我们可以通过重写router-link-active类名来实现设置选中样式
    但是我们也可以通过linkActiveClass来指定选中样式
    
    4.重定向路由
    { path: '被重定向值', redirect: '重定向之后的值' }
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
       <!-- <a href="#/one">切换到第一个界面</a>
        <a href="#/two">切换到第二个界面</a>-->
        <!--
        如果是通过router-link来设置URL的HASH值, 那么不用写#, 那么是通过to属性来设置HASH值
        -->
        <!--
        默认情况下Vue在渲染router-link的时候, 是通过a标签来渲染的
        如果在企业开发中不想使用a标签来渲染, 那么可以通过tag属性来告诉vue通过什么标签来渲染
        -->
        <router-link to="/one" tag="div">切换到第一个界面</router-link>
        <router-link to="/two" tag="div">切换到第二个界面</router-link>
        <!-- 路由出口 -->
        <!-- 路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    <template id="one">
        <div class="onepage">
            <p>我是第一个界面</p>
        </div>
    </template>
    <template id="two">
        <div class="twopage">
            <p>我是第二个界面</p>
        </div>
    </template>
    <script>
    
        // 1.定义组件
        const one = {
            template: "#one"
        };
        const two = {
            template: "#two"
        };
        // 2.定义切换的规则(定义路由规则)
        const routes = [
            // 重定向路由
            //{ path: '/', redirect: '/two' },
            // 数组中的每一个对象就是一条规则
            { path: '/one', component: one },
            { path: '/two', component: two }
        ];
        // 3.根据自定义的切换规则创建路由对象
        const router = new VueRouter({
            routes: routes,
            // 指定导航激活状态样式类名
            linkActiveClass: "nj-active"
        });
    
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 4.将创建好的路由对象绑定到Vue实例上
            router: router,       
            // 专门用于定义局部组件的
            components: {
                //one: one,
                //two: two
            }
        });
    </script>
    </body>
    </html>
    
  • 3.3 传递参数

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>63-VueRouter-参数传递</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .onepage, .twopage{
                width: 500px;
                height: 500px;
            }
            .onepage{
                background: pink;
            }
            .twopage{
                background: skyblue;
            }
            /*.router-link-active{*/
            /*    background: red;*/
            /*}*/
            .nj-active{
                background: skyblue;
            }
        </style>
        <script src="js/vue.js"></script>
        <!--1.导入Vue Router-->
        <script src="js/vue-router.js"></script>
    </head>
    <body>
    <!--
    1.Vue Router传递参数
    只要将Vue Router挂载到了Vue实例对象上, 我们就可以通过vue.$route拿到路由对象
    只要能拿到路由对象, 就可以通过路由对象拿到传递的参数
    
    方式一: 通过URL参数参数(?key=value&key=value), 通过this.$route.query获取
    方式二: 通过占位符传递(路由规则中/:key/:key, 路径中/value/value), 通过this.$route.params获取
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <!--
        第一种传递参数的方式: 通过URL参数的方式传递
        在指定HASH的时候, 通过?key=value&key=value的方式传递
        在传递的组件的生命周期方法中通过 this.$route.query的方式来获取
        -->
        <router-link to="/one?name=lnj&age=33" tag="button">切换到第一个界面</router-link>
        <!--
        第二种传递参数的方式: 通过路由规则中的占位符传递
        在指定路由规则的时候通过/:key/:key的方式来指定占位符
        在指定HASH的时候, 通过/value/value的方式来传递值
        在传递的组件的生命周期方法中通过 this.$route.params的方式来获取
        -->
        <router-link to="/two/zs/66" tag="button">切换到第二个界面</router-link>
        <!-- 路由出口 -->
        <!-- 路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    <template id="one">
        <div class="onepage">
            <p>我是第一个界面</p>
        </div>
    </template>
    <template id="two">
        <div class="twopage">
            <p>我是第二个界面</p>
        </div>
    </template>
    <script>
        // 1.定义组件
        const one = {
            template: "#one",
            created: function () {
                console.log(this.$route);
                console.log(this.$route.query.name);
                console.log(this.$route.query.age);
            }
        };
        const two = {
            template: "#two",
            created: function () {
                console.log(this.$route);
                console.log(this.$route.params.name);
                console.log(this.$route.params.age);
            }
        };
        // 2.定义切换的规则(定义路由规则)
        const routes = [
            // 数组中的每一个对象就是一条规则
            { path: '/one', component: one },
            { path: '/two/:name/:age', component: two }
        ];
        // 3.根据自定义的切换规则创建路由对象
        const router = new VueRouter({
            routes: routes,
            linkActiveClass: "nj-active"
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
              router:router,
            // 专门用于定义局部组件的
            components: {
                one: one,
                two: two
            }
        });
        // console.log(vue.$route);
    </script>
    </body>
    </html>
    
  • 3.4 嵌套路由

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>64-VueRouter-嵌套路由</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .onepage, .twopage{
                width: 500px;
                height: 500px;
            }
            .onepage{
                background: pink;
            }
            .twopage{
                background: skyblue;
            }
            .onesub1page, .onesub2page{
                width: 100%;
                height: 300px;
            }
            .onesub1page{
                background: orangered;
            }
            .onesub2page{
                background: blueviolet;
            }
            .nj-active{
                background: skyblue;
            }
        </style>
        <script src="js/vue.js"></script>
        <!--1.导入Vue Router-->
        <script src="js/vue-router.js"></script>
    </head>
    <body>
    <!--
    1.什么是嵌套路由?
    嵌套路由也称之为子路由, 就是在被切换的组件中又切换其它子组件
    例如: 在one界面中又有两个按钮, 通过这两个按钮进一步切换one中的内容
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <router-link to="/one" tag="button">切换到第一个界面</router-link>
        <router-link to="/two" tag="button">切换到第二个界面</router-link>
        <!-- 路由出口 -->
        <!-- 路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    <template id="one">
        <div class="onepage">
            <p>我是第一个界面</p>
            <router-link to="/one/onesub1" tag="button">切换到第一个子界面</router-link>
            <router-link to="/one/onesub2" tag="button">切换到第二个子界面</router-link>
            <!-- 路由出口 -->
            <!-- 路由匹配到的组件将渲染在这里 -->
            <router-view></router-view>
        </div>
    </template>
    <template id="onesub1">
        <div class="onesub1page">
            <p>我是第一个界面子界面1</p>
        </div>
    </template>
    <template id="onesub2">
        <div class="onesub2page">
            <p>我是第一个界面子界面2</p>
        </div>
    </template>
    <template id="two">
        <div class="twopage">
            <p>我是第二个界面</p>
        </div>
    </template>
    <script>
        // 1.定义组件
        const onesub1 = {
            template: "#onesub1",
        };
        const onesub2 = {
            template: "#onesub2",
        };
        const one = {
            template: "#one",
            components:{
                onesub1:onesub1,
                onesub2: onesub2
            }
        };
        const two = {
            template: "#two"
        };
        // 2.定义切换的规则(定义路由规则)
        const routes = [
            // 数组中的每一个对象就是一条规则
            {
                path: '/one',
                component: one,
                children:[
                    {
                        // 注意点: 如果是嵌套路由(子路由), 那么不用写一级路径的地址, 并且也不用写/
                        path: "onesub1",
                        component: onesub1
                    },
                    {
                        // 注意点: 如果是嵌套路由(子路由), 那么不用写一级路径的地址, 并且也不用写/
                        path: "onesub2",
                        component: onesub2
                    }
                ]
            },
            // { path: '/one/onesub1', component: onesub1 },
            // { path: '/one/onesub2', component: onesub2 },
            { path: '/two', component: two }
        ];
        // 3.根据自定义的切换规则创建路由对象
        const router = new VueRouter({
            routes: routes,
            linkActiveClass: "nj-active"
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 4.将创建好的路由对象绑定到Vue实例上
            router: router,    
            // 专门用于定义局部组件的
            components: {
                one: one,
                two: two
            }
        });
        // console.log(vue.$route);
    </script>
    </body>
    </html>
    
  • 3.5 命名视图

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>66-VueRouter-命名视图</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .onepage, .twopage{
                width: 200px;
                height: 200px;
            }
            .onepage{
                background: pink;
            }
            .twopage{
                background: skyblue;
            }
            .nj-active{
                background: skyblue;
            }
        </style>
        <script src="js/vue.js"></script>
        <!--1.导入Vue Router-->
        <script src="js/vue-router.js"></script>
    </head>
    <body>
    <!--
    1.什么是命名视图?
    命名视图和前面讲解的具名插槽很像, 都是让不同的出口显示不同的内容
    命名视图就是当路由地址被匹配的时候同时指定多个出口, 并且每个出口中显示的内容不同
    -->
    <!--这里就是MVVM中的View-->
    <div id="app">
        <!-- 路由出口 -->
        <!-- 路由匹配到的组件将渲染在这里 -->
        <!--和匿名插槽一样, 如果指定了多个router-view, 那么当路由地址被匹配之后, 多个router-view中显示的内容是一样的-->
        <!--<router-view></router-view>
        <router-view></router-view>-->
        <!--和具名插槽一样, 如果想同时显示多个不同的组件, 那么可以给出口指定名称
            1.在路由规则中给组件起名称
            2.在出口中指定显示哪个名称的组件-->
        <router-view name="name1"></router-view>
        <router-view name="name2"></router-view>
    </div>
    <template id="one">
        <div class="onepage">
            <p>我是第一个界面</p>
        </div>
    </template>
    <template id="two">
        <div class="twopage">
            <p>我是第二个界面</p>
        </div>
    </template>
    <script>
        // 1.定义组件
        const one = {
            template: "#one",
        };
        const two = {
            template: "#two"
        };
        // 2.定义切换的规则(定义路由规则)
        const routes = [
            // 数组中的每一个对象就是一条规则
            {
                path: '/',
                components: {
                    name1: one,
                    name2: two
                }
            },
        ];
        // 3.根据自定义的切换规则创建路由对象
        const router = new VueRouter({
            routes: routes,
            linkActiveClass: "nj-active"
        });
        // 这里就是MVVM中的View Model
        let vue = new Vue({
            el: '#app',
            // 4.将创建好的路由对象绑定到Vue实例上
            router: router,
            // 这里就是MVVM中的Model
            data: {
            },
            // 专门用于存储监听事件回调函数
            methods: {
            },
            // 专门用于定义计算属性的
            computed: {
            },
            // 专门用于定义局部组件的
            components: {
                one: one,
                two: two
            }
        });
        // console.log(vue.$route);
    </script>
    </body>
    </html>
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容