一.ES6基本语法

        ES6全称为EcmaScript,是一种JavaScript统一书写规则。EcmaScript: 5.x  是至今所有浏览器使用的一种通用版本,但是6.x版本的出现带来了很多新特性,极大方便了开发。因此我们需要学习一下ES6的新语法。

 1.变量声明

        在ES5中,我们使用var关键字来声明变量,但是使用var声明变量存在作用范围混淆的问题,为了解决该问题,ES6提出了新的变量声明方式:

  • let : 用来声明局部变量。其作用范围严谨,从代码声明处开始到代码块结束, 一般在声明基本变量时推荐使用let
  • const : 用来声明常量。一旦被赋值不能被修改,作用范围较广。一般在声明对象时推荐使用const。注意:const声明对象,指对象的地址为常量,对象的属性仍可修改。
<script>
    //const 声明对象
    const emp = {id:id,name:name,age:age};
    console.log("es5",emp);
    //let 声明局部变量
    for (let i = 0; i < 10; i++) {
        console.log("for in",i);
    }
</script>

 2.匿名函数

        在ES6中,当使用匿名函数作为参数时(function(){}),推荐使用ES6中的箭头函数,即(参数,参数)=>{函数体}

//匿名函数:没有名称的函数(一般作为参数)
test:function () {
    axios.post("url",{json}).then(function (res){
        console.log(res);
    }).catch(function (err){
        console.log(err);
    })
}
//ES6:匿名函数推荐使用箭头函数书写
test:function () {
    axios.post("url",{json}).then((res)=>{
        console.log(res);
    }).catch((err)=>{
        console.log(err);
    })
}

 注意:

  • 当箭头函数没有参数或者参数大于1个时,必须加入();当箭头函数参数为1个时,()可以省略不写:param => {函数体}
  • 当箭头函数函数体中只有一行代码时,函数体{}可以省略不写:(参数,参数)=>代码
  • 匿名函数有自己的this(指代window),因此我们常需要使用_this = this在外部获取vue实例。而箭头函数没有自己this对象,其this就指代函数外的this对象(因此在axios箭头函数中,this就指代当前vue实例)
test:function () {
    axios.post("url",{json}).then(res=>{
        console.log(res);
        //do ...
        this.data = res.data
    }).catch(err=>console.log(err))
}

3.对象定义

       在ES6中,若在定义对象时如果对象属性名和变量名一致,则写一个即可。

let id = 21;
    let name = "小三";
    let age = 23;    
    //es5.x
    const emp = {id:id,name:name,age:age};
    console.log("es5",emp);
    //es6.x
    const emp1 = {id,name,age}
    console.log("es6",emp1);

 4.模板字符串

        在ES6中,含有HTML标签模板的字符串推荐使用反引号 `` ,反引号不会改变标签含义且不需要转义。

//原始html模板字符串写法
    let html = "<button onclick=\"test('+id+')\">点我</button>" +
               "<button onclick=\"test('+id+')\">点我</button>";
    //es6 html模板字符串写法
    let html_es6 = `<div>
                     <h1>我是小黑</h1>
                     <button onclick="test('success')">点我</button>
                    </div>`;
    console.log(html_es6);

二.Vue组件使用

  • 问题提出:在项目开发中,前端页面有时会成千上万十分庞大。如果我们在每一个页面中都new Vue实例开发,则系统的负荷会很大且会降低交互速度。因此,Vue推荐我们进行SPA(单页面应用)开发,即整个前端系统中应该只有一个页面/一个Vue实例。
  • 问题解决:为了在单页面应用中实现各种复杂的功能,Vue提供了组件(Coponent)机制,将各种不同的功能封装为小的组件,根据需求灵活的插入/渲染到单页面应用中去,实现组件化、单实例开发。
  • 组件优点:减少Vue开发代码量、实现业务功能隔离、组件可以复用、灵活高效

1.组件的注册使用

(1)全局组件

全局组件:直接挂载到vue根实例上,在任何对象实例/组件中都可使用(不常用),范围广 1.声明:Vue.component(id,{json object}); (1)id:指明全局组件的名称 (2){json object}:全局组件的配置对象: -template:组件渲染的html模板样式 -data、methods、computed等 2.使用:在html中声明 <id></id> 插入/渲染组件(样式/数据)

<body>
    <div id="app">
        <h1>VUE 组件开发</h1>
        <!--使用全局组件-->
        <login></login>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    //全局组件声明
    Vue.component('login',{
        template:`<div>
                        <h1>用户登录组件(全局)</h1>
                        <button>点我登录</button>
                  </div>`
    });
</script>

 (2)局部组件

局部组件:挂载到某个vue实例对象上,只能在注册组件中使用,超出则无效(推荐使用)。范围小 1.声明:components:{ id1:{},id2:{}...}; (1)idx:指明局部组件的名称 (2){}:局部组件的配置对象: -template:组件渲染的html模板样式 -data、methods、computed等 2.使用:在当前所注册的vue实例声明的范围内(只在当前vue实例内有效),在html中声明 <id></id> 插入/渲染组件(样式/数据)

<!--###第一种开发方式###-->
<body>
    <div id="app">
        <h1>VUE 组件开发</h1>
        <!--使用局部组件-->
        <register></register>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    const app = new Vue({
        el:"#app",
        data:{},
        methods:{},
        computed:{},
        created:function () {
            //life-cycle function
        },

        //局部组件注册(vue的components属性)
        components:{
            register:{
                template:`<div>
                            <h1>用户注册组件(局部)</h1>
                            <button>点我注册</button>
                          </div>`
            }
        }
    })
</script>
<!--###第二种开发方式###-->
<body>
    <div id="app">
        <h1>VUE 组件开发</h1>
        <!--使用局部组件-->
        <register></register>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    //声明局部组件 配置对象
    let register = {
        template:`<div>
                      <h1>用户注册组件(局部)</h1>
                      <button>点我注册</button>
                   </div>`
    };


    const app = new Vue({
        el:"#app",
        data:{},
        methods:{},
        computed:{},
        created:function () {
            //life-cycle function
        },

        //局部组件 注册
        components:{
            register
        }
    })
</script>
<!--###第三种开发方式###-->
<body>
    <div id="app">
        <h1>VUE 组件开发</h1>
        <!--使用局部组件-->
        <register></register>
    </div>
</body>
<!--声明html模板-->
<template id="reg">
    <div>
       <h1>用户注册组件(局部)</h1>
       <button>点我注册</button>
    </div>
</template>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    //声明局部组件 配置对象
    let register = {
        //绑定html模板
        template:"#reg"
    };


    const app = new Vue({
        el:"#app",
        data:{},
        methods:{},
        computed:{},
        created:function () {
            //life-cycle function
        },

        //局部组件 注册
        components:{
            register
        }
    })
</script>

注意:
     1.组件可以重复使用,template支持各种vue语法指令
     2.template内必须加入唯一根元素(比如<div>包裹),不然报错
     3.组件之间可以相互嵌套,组件内也包含components,构成一颗组件树,来完成复杂功能。

2. 组件的配置属性

* 1.template : 定义组件渲染的html样式(可嵌入任何vue指令) * 2.data(){}: 给当前组件定义一系列组件数据(组件范围内有效),注意data必须是一个函数 * 3.methods : 给当前组件定义一系列组件方法(可以直接使用this调用组件数据) * 4.computed : 给当前组件定义一系列计算方法/属性 * 5.components : 定义组件的组件(该组件只能在父组件template范围内使用,超出无效) * 6.生命周期函数 : 组件运行过程中自动触发

<!--###以局部组件为例###-->
<body>
    <div id="app">
        <h1>VUE 组件开发</h1>
        <!--使用局部组件-->
        <register></register>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    //声明全局组件
    Vue.component('login',{
        template:`<div>
                        <h1>用户登录组件(全局)</h1>
                        <button>点我登录</button>
                  </div>`
    });

    //声明局部组件 配置对象
    let register = {
        //html模板
        template:`<div id="reg">
                      <h1>用户注册组件(局部)</h1>
                      <h2>{{counter}}---{{msg}}---{{counterSqrt}}</h2>
                      <button @click="increment(10)">点我++</button>
                      <!--嵌入子组件-->
                      <tip></tip>
                      <!--嵌入全局组件-->
                      <login></login>
                   </div>`,
        //组件数据
        data(){
            return {
                counter:0,
                msg:"我是组件register"
            }
        },
        //组件方法函数
        methods:{
            increment:function (count) {
                this.counter+=count;
            }
        },
        //组件计算属性
        computed:{
            counterSqrt(){
                return this.counter*this.counter;
            }
        },
        //组件的组件<tip>
        components:{
            tip:{
                template:'<div><span>我是tip子组件</span></div>'
            },
        },
        //生命周期函数
        //1.初始化阶段
        beforeCreate(){
            console.log("beforeCreate:",this.msg);},
        created(){
            console.log("created:",this.msg);
        },
        beforeMount(){ //此时组件中template还是模板还没有渲染
            console.log(this);
        },
        mounted(){  // 此时组件中页面的数据已经和data中数据一致
            console.log("mounted:",document.getElementById("reg").innerHTML);
        },
        //2.运行阶段
        beforeUpdate(){// 此时data中数据变化了  页面数据还是原始数据
            console.log("beforeUpdate:",this.counter);
            console.log("beforeUpdate:",document.getElementById("reg").innerHTML);
        },
        updated(){  //此时data 页面数据一致
            console.log("updated:",this.counter);
            console.log("updated:",document.getElementById("reg").innerHTML);
        },
        //3.销毁阶段
        beforeDestroy(){},
        destroyed(){},
    };


    const app = new Vue({
        el:"#app",
        data:{},
        methods:{},
        computed:{},
        created:function () {
            //life-cycle function
        },
        //注册局部组件
        components:{
            register:register
        }
    });
</script>

3.组件的数据传递(父组件->子组件的数据传输)

        为了实现组件之间的数据传递,vue提供了props机制。不过props仅提供单向数据流,即所有的 prop 都使得其父子之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。 这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。 使用方法:

  • 在组件内声明props属性来接收数据:psops:["param_1","param_2"...]
  • 静态数据绑定:<component param_1="value1"...></component>
  • 动态数据绑定:<component :param_1="paraentParamId"...></component>

         props机制接收数据就相当于自己组件data中声明了一个这样的数据,可以直接拿来使用,并且随着父组件的更新,props也会随之更新。

<body>
    <div id="app">
        <h1>VUE 组件开发之数据传递Props</h1>
        <input type="text" v-model="content">
        <button @click="increment">点我+1</button>

        <!--使用局部组件 传递数据
                ptitle:静态数据字符串
                content:vue父组件的动态data
                counter:vue父组件的动态data
        -->
        <block ptitle="静态数据传递" :pcontent="content" :pcounter="counter"></block>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>

    //声明局部组件-配置对象
    const block = {
        template:`<div>
                      <h1>{{msg}}</h1>
                      <h2>{{ptitle}}--{{pcontent}}---{{pcounter}}</h2>
                      <!--组件的组件 传递数据-->
                      <blockchild :cnt="pcounter"></blockchild>
                   </div>`,
        data(){
            return {
                msg:"我是组件block",
            }
        },
        <!--声明props数组,来接收传递数据-->
        props:["ptitle","pcontent","pcounter"],
        components:{
            blockchild:{
                template:`<div>
                            <span>我是blockchild子组件</span>
                            <span>{{cnt}}</span>
                          </div>`,
                props:["cnt"]
            },
        },
    };


    const app = new Vue({
        el:"#app",
        data:{
            counter:0,
            content:"初始内容"
        },
        methods:{
            increment:function () {
                this.counter++;
            }
        },
        components:{
            block:block
        }
    });
</script>

        注意:额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。即,子组件对于props数据仅享有读取权,而不应该有修改权。若要修改父组件传来的数据可参考如下(先赋值再修改):

<body>
    <div id="app">
        <h1>VUE 组件开发之数据传递Props</h1>
        <input type="text" v-model="content">
        <button @click="increment">点我+1</button>

        <!--使用局部组件-->
        <block ptitle="静态数据传递" :pcontent="content" :pcounter="counter"></block>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>

    //声明局部组件-配置对象
    const block = {
        template:`<div>
                      <h1>{{msg}}</h1>
                      <h2>{{ptitle}}--{{pcontent}}---{{pcounter}}--{{bcnt}}</h2>
                      <blockchild :cnt="pcounter"></blockchild>
                      <button @click="incre(10)">点我+10</button>
                   </div>`,
        data(){
            return {
                msg:"我是组件block",
                //先赋值,再修改。但是赋值仅发生一次,赋值data不随props更新
                bcnt:this.pcounter
            }
        },
        props:["ptitle","pcontent","pcounter"],
        methods:{
            incre(num){
                //这是不对的!子组件不应该修改props单向数据
                //this.pcounter+=num; 
                先赋值,再修改。
                this.bcnt+=num;
            }
        },
        components:{
            blockchild:{
                template:`<div>
                            <span>我是blockchild子组件</span>
                            <span>{{cnt}}</span>
                          </div>`,
                props:["cnt"]
            },
        },
    };


    const app = new Vue({
        el:"#app",
        data:{
            counter:0,
            content:"初始内容"
        },
        methods:{
            increment:function () {
                this.counter++;
            }
        },
        components:{
            block:block
        }
    });
</script>

 4.组件的事件传递(子组件->父组件的数据传输)

        props只能实现父组件到子组件的单向数据流,那么如何实现子组件向父组件传递数据呢?vue提供了组件的事件传递,可以将父组件的函数/方法传递给子组件调用,我们可以在子组件调用父组件时传递子组件数据,从而实现子组件->父组件的数据传输。用法:

  • 在标签中使用  @传递事件名="父组件方法名"传递事件:<component @paramMethod="paraentMethod"></component>
  • 在子组件中,使用this.$emit('传递事件名',参数,参数...)调用父组件方法
<body>
    <div id="app">
        <h1>VUE 组件开发之数据传递Props</h1>
        <input type="text" v-model="content">
        <button @click="increment">点我+1</button>

        <!--使用局部组件-->
        <block :pcontent="content" :pcounter="counter" @postdata="increByNum"></block>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>

    //声明局部组件-配置对象
    const block = {
        template:`<div>
                      <h1>{{msg}}</h1>
                      <h2>{{pcontent}}---{{pcounter}}</h2>
                      <button @click="incre(10)">点我+10</button>
                   </div>`,
        data(){
            return {
                msg:"我是组件block",
            }
        },
        props:["ptitle","pcontent","pcounter"],
        methods:{
            incre(num){
                alert("子组件触发了");
                //调用父组件的increByNum方法,并传递子组件参数num
                this.$emit("postdata",num);
            }
        },
    };


    const app = new Vue({
        el:"#app",
        data:{
            counter:0,
            content:"初始内容"
        },
        methods:{
            increment:function () {
                this.counter++;
            },
            //传递方法
            increByNum:function (cnt) {
                alert("父组件触发了");
                this.counter+=cnt;
            }
        },
        components:{
            block:block
        }
    });
</script>

三.Vue路由

        基于组件开发,在实际生产过程中不可能将所有组件都展示到页面上,而是应该根据用户需求在单页面应用中灵活的切换组件展示。为此,vue引入了路由router的概念,根据请求的路径按照一定的路由规则进行请求的转发从而帮助我们实现统一请求的管理,根据url展示不同的组件。

1.路由的基本使用

(1)引入vue-router 的 js 文件

        vue-router是与vue深度集成的一个第三方支持文件,提供实现路由的功能。注意:vue-router的 js文件必须放在vue之后!

<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>

(2)注册路由的基本使用

步骤:

        1.开发相关功能组件,比如登陆组件、注册组件

        2.创建路由管理对象VueRouter,配置路由映射规则(即url -> component)

        3.在vue实例中注册路由管理对象

        4.在html中显示路由组件标签,指代切换组件的位置

<script>
    //2. 开发相关组件
    //登陆组件
    const login={
        template:`<div>
                    <h2>登陆组件</h2>
                    <!--切换url路径,来切换功能组件。
                        url与component的映射在router配置中
                    -->
                    <a href="#/login">用户登陆</a>
                    <a href="#/reg">用户注册</a>
                  </div>`
    };
    //注册组件
    const reg={
        template:`<div>
                    <h2>注册组件</h2>
                    <a href="#/login">用户登陆</a>
                    <a href="#/reg">用户注册</a>
                  </div>`
    };
    //404提示组件
    const notFound={
        template:`<div><h2>404 Not Found!</h2></div>`
    };
</script>
<script>
    //3.创建路由管理对象,管理多个路由
    const router = new VueRouter({
        //routes数组: 配置路由映射规则,即路由对象
        //  -path:路由路径(https://localhost:8080/index.html#/path  #为哈希路由,表示此路径由路由router管理映射)
        //  -component:路由路径对应的展示组件
        //  -redirect:路由路径的重定向(将默认路由/ 重定向到 login)
        //  -path:"*":通配符匹配任意路径
        routes:[
            {path:'/',redirect:'login'},
            {path:'/login',component:login},
            {path:'/reg',component:reg},
            {path:'*',component:notFound}
        ]
    });

    const app = new Vue({
        el:"#app",
        data:{
            msg:"vue router 基本使用"
        },
        methods:{},
        //4.在vue实例中注册路由管理器
        router:router
    });
</script>
<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--5. 显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>

2.路由切换

(1) 显式标签切换路由

        显式切换路由即在HTML样式中,通过标签来切换路由对象或路径,以便于展示不同的组件。主要有以下四种方式:

<1> 第一种方式: <a href="">标签切换 -切换方式:href="#/path" 切换url路径 -注意:必须使用# (哈希路由匹配符)

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--第一种方式: <a href="">标签切换
            -切换方式:href="#/path" 切换url路径
            -注意:必须使用# (哈希路由匹配符)
        -->
        <a href="#/login">用户登陆</a>
        <a href="#/reg">用户注册</a>
        
        <!--显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>

<2> 第二种方式: <router-link to=""> 路径切换 -切换方式:to="/path" 切换url路径 -注意:不用加入#,但是必须使用to 属性指明路径

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--第二种方式: <router-link to=""> 路径切换
            -切换方式:to="/path" 切换url路径
            -注意:不用加入#,但是必须使用to 属性指明路径
        -->
        <router-link to="/login">用户登陆</router-link>
        <router-link to="/reg">用户注册</router-link>
       
        <!--显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>

<3> 第三种方式: <router-link :to=""> 路径对象切换 -切换方式::to={path:'/path'} 切换url路径 -注意:使用to 属性绑定路径对象必须使用v-bind(即:)

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--第三种方式: <router-link :to=""> 路径对象切换
            -切换方式::to={path:'/path'} 切换url路径
            -注意:使用to 属性绑定路径对象必须使用v-bind(即:)
        -->
        <router-link :to="{path:'/login'}">用户登陆</router-link>
        <router-link :to="{path:'/reg'}">用户注册</router-link>
       
        <!--显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>

<4> 第四种方式: <router-link :to=""> 通过命名路由切换(即根据路由名称切换) -切换方式::to={name:'routerId'} 切换路由对象 -注意: 使用名称切换必须使用命名路由(即给路由对象个name属性) -推荐使用命名路由切换的方式,解耦

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--第四种方式: <router-link :to=""> 通过命名路由切换(即根据路由名称切换)
           -切换方式::to={name:'routerId'} 切换路由对象
           -注意: 使用名称切换必须使用命名路由(即给路由对象个name属性)
           -推荐使用命名路由切换的方式,解耦
       -->
        <router-link :to="{name:'Login'}">用户登陆</router-link>
        <router-link :to="{name:'Register'}">用户注册</router-link>
        <!--显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>

<script>
    //创建路由管理对象,管理多个路由
    const router = new VueRouter({
        routes:[
            {path:'/',redirect:'login'},
            //name:这个属性代表路由对象名称  用来给路由对象一个唯一名称标识
            {path:'/login',component:login,name:'Login'},
            {path:'/reg',component:reg,name:'Register'},
            {path:'*',component:notFound}
        ]
    });
</script>

 (2)js代码切换路由

        我们在业务开发中,经常遇到需要在js代码中来切换路由的情况,比如登陆时需要在函数中发送axios请求,等响应回来后切换路由到主页。在js代码的vue实例中我们可以通过$router 访问路由实例。因此你可以调用 this.$router.push

-组件、vue实例当中都包含两个关键对象: 1.this.$route 当前路由对象 2.this.$router 路由管理器对象 -切换方式:调用$router的push方法: this.$router.push("/login"); 路径切换 this.$router.push({path:'login'}); 路径对象切换 this.$router.push({name:'Login'}); 命名路由切换(推荐)

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--在js代码中切换路由-->
        <button @click="login">用户登陆</button>
        <button @click="register">用户注册</button>
        <!--显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>
<script>
    //登陆组件
    const login={
        template:`<div>
                    <h2>登陆组件</h2>
                  </div>`
    };
    //注册组件
    const reg={
        template:`<div>
                    <h2>注册组件</h2>
                  </div>`
    };
    //404提示组件
    const notFound={
        template:`<div><h2>404 Not Found!</h2></div>`
    };
    //3.创建路由管理对象,管理多个路由
    const router = new VueRouter({
        routes:[
            {path:'/',redirect:'login'},
            {path:'/login',component:login,name:'Login'},
            {path:'/reg',component:reg,name:'Register'},
            {path:'*',component:notFound}
        ]
    });

    const app = new Vue({
        el:"#app",
        data:{
            msg:"vue router 路由切换"
        },
        methods:{
            login:function () { 
                this.$router.push({name:'Login'});
            },
            register:function () {
                this.$router.push({name:'Register'});
            }
        },
        //在vue实例中注册路由
        router
    });
</script>

-注意:在直接使用this.$router.push()时,多次切换相同路由会出现报错。其解决方法为: 1.在切换之前进行相同路由判断 2.加入一段配置,回调catch掉报错

<script>
    //创建路由管理对象,管理多个路由
    const router = new VueRouter({
        routes:[
            {path:'/',redirect:'login'},
            {path:'/login',component:login,name:'Login'},
            {path:'/reg',component:reg,name:'Register'},
            {path:'*',component:notFound}
        ]
    });

    //配置:解决同一个路由多次切换报错的问题
    const originalPush = VueRouter.prototype.push;
    VueRouter.prototype.push = function push(location) {
        return originalPush.call(this, location).catch(err => err)
    };

    const app = new Vue({
        el:"#app",
        data:{
            msg:"vue router 路由切换"
        },
        methods:{
            login:function () {
                //在直接使用this.$router.push()时,多次切换相同路由会出现报错。其解决方法为:
                //  1.在切换之前进行相同路由判断
                //  2.加入一段配置,回调catch掉报错

                if(this.$route.name!="Login"){//判断:判断是否为相同路由
                    this.$router.push({name:'Login'});
                }
            },
            register:function () {
                this.$router.push({name:'Register'});
            }
        },
        //在vue实例中注册路由
        router
    });
</script>

3.路由参数传递

(1)queryString方式传参

-queryString方式: 传递格式:?id=xx&name=xx 获取参数:this.$route.query.key

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--地址栏传递参数分为两种方式:
               1.queryString方式:
                    传递格式:?id=xx&name=xx
                    获取参数:this.$route.query.key
        -->
        <a href="#/login?id=11&name=xiaochen">用户登录</a>

        <router-link to="/login?id=13&name=xiaohong">用户登录</router-link>

        <router-link :to="{path:'/login',query:{id:15,name:'xiaolan'}}">用户登录</router-link>

        <router-link :to="{name:'Login',query:{id:17,name:'xiaohei'}}">用户登录</router-link>
    </div>
</body>
<script>
    //开发相关组件
    //登陆组件
    const login={
        template:`<div>
                    <h2>登陆组件</h2>
                  </div>`,
        created(){
            //获取query参数
            console.log("=======>" + this.$route.query.id + "=======>" + this.$route.query.name);
        }
    };
   
    //创建路由管理对象,管理多个路由
    const router = new VueRouter({
        routes:[
            {path:'/',redirect:'login'},
            {path:'/login',component:login,name:'Login'}
        ]
</script>

 (2)restful方式传参

-restful路径传递参数: 传递格式:/xx/21 (需要配合routes配置) 获取参数:this.$route.params.key

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--地址栏传递参数分为两种方式:
               2.restful路径传递参数
                    传递格式:/xx/21 (需要配合routes配置)
                    获取参数:this.$route.params.key
        -->
        <a href="#/reg/21/xiaoli">用户注册</a>

        <router-link :to="{path:'/reg/22/xiaojindou'}">用户注册</router-link>

        <router-link :to="{name:'Register',params:{id:233,name:'xiaojinniu'}}">用户注册</router-link>

        <!--显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>
    //开发相关组件
    //注册组件
    const reg={
        template:`<div>
                    <h2>注册组件</h2>
                  </div>`,
        created(){
            console.log("=======>" + this.$route.params.id + "=======>" + this.$route.params.name);
        }
    };
    
    //创建路由管理对象,管理多个路由
    const router = new VueRouter({
        routes:[
            {path:'/',redirect:'login'},
            //使用/path/:param的方式,给路径绑定参数->this.$route.params
            {path:'/reg/:id/:name',component:reg,name:'Register'}
        ]
    });

    const app = new Vue({
        el:"#app",
        data:{
            msg:"vue router 路由切换"
        },
        //在vue实例中注册路由
        router
    });
</script>

(3)使用props解耦

        使用 props 将组件和路由解耦,如果 props 被设置为 true,route.params 将会被设置为组件属性。

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!--props-->
        <router-link :to="{path:'/notfound/test hahahaha/this is wranning'}">props测试</router-link>

        <router-link :to="{name:'NotFound',params:{title:'test hahahaha',content:'this is wranning'}}">props测试</router-link>


        <!--显示路由组件标签,指代组件切换位置-->
        <router-view></router-view>
    </div>
</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>
    //开发相关组件
    //404提示组件
    const notFound={
        template:`<div><h2>{{title}} 404 Not Found! {{content}}</h2></div>`,
        //接收参数
        props:["title","content"],
        created(){
            console.log("=======>" + this.title + "=======>" + this.content);
        }
    };
    //创建路由管理对象,管理多个路由
    const router = new VueRouter({
        routes:[
            {path:'/',redirect:'login'}, 
            //props:true   -- 使用 props 将组件和路由解耦,如果 props 被设置为 true,route.params 将会被设置为组件属性。
            {path:'/notfound/:title/:content',component:notFound,name:'NotFound',props:true,}
        ]
    });

    const app = new Vue({
        el:"#app",
        data:{
            msg:"vue router 路由切换"
        },
        //在vue实例中注册路由
        router
    });
</script>

 4.嵌套路由

        很多时候,我们需要在一个页面中同时展示多个组件,或者说在一个模块下展示多个子模块。这时仅靠简单的路由切换就不满足我们的需求了。因此vue提出了路由嵌套的概念,通过children属性在路由中嵌套子路由,同时展示子组件。

  • 路由规则routes中:routes:[ {path,name,component,children:[ ](子路由数组) } ]
  • 组件template中展示子路由:<router-view></router-view>
<template id="users">
    <div>
        <h3>用户列表</h3>
        <a href="#/users/useradd">添加用户信息</a>
        <table border="1">
            <tr>
                <th>id</th>
                <th>name</th>
                <th>age</th>
                <th>salary</th>
                <th>操作</th>
            </tr>
            <tr v-for="user,index in users">
                <td>{{user.id}}</td>
                <td>{{user.name}}</td>
                <td>{{user.age}}</td>
                <td>{{user.salary}}</td>
                <td><a href="">删除</a> <router-link :to="{name:'useredit',query:{id:user.id}}">修改</router-link></td>
            </tr>
        </table>

        <!--在组件中展示子路由组件标签-->
        <router-view></router-view>
    </div>
</template>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>

    //定义用户列表
    const users = {
        template:'#users',
        data(){
            return {
                users:[]
            }
        },
        created(){
            //发送axios请求查询所有
            this.users = [{id:1,name:'xiaochen',age:23,salary:2300}]
        }
    };

    //定义用户添加组件
    const useradd={
        template:`<div><form action="">姓名: <input type="text"> <br> 年龄: <input type="text"> <br>  工资: <input type="text"> <br> <input type="submit" value="提交"></form></div>`
    };
    //定义用户修改组件
    const useredit={
        template:`<div><form action="">id: <input type="text" v-model="user.id"> <br> 姓名: <input type="text" v-model="user.name"> <br> 年龄: <input type="text" v-model="user.age"> <br>  工资: <input type="text" v-model="user.salary"> <br> <input type="button" @click="editUser" value="提交"></form></div>`,
        data(){
          return {
              user:{}
          }
        },
        methods:{
            editUser(){
                //发送axios请求更新用户
                // axios.post("url",this.user).then(res=>{
                //     this.user = {};//清空数据
                //     this.$router.push({name:'users'})//切换路由
                // });
                this.$router.push({name:'users'})//切换路由,重新查询所有用户
            }
        },
        created(){
            let id = this.$route.query.id;
            console.log("updated: ",id);
            //发送axios请求
            //axios.get("url?id="+id).then(res=>this.user = res.data);
            this.user = {id:id,name:'xiaochen',age:23,salary:2300};
        }
    };

    //定义路由规则对象
    const router = new VueRouter({
        routes:[
            {
                path:'/users',name:'users',component:users,
                children:[ //嵌套子组件路由
                    //注意:嵌套路由中子路由不能使用/开头,访问子路由 /users/useradd
                    {path:'useradd',name:'useradd',component:useradd},
                    {path:'useredit',name:'useredit',component:useredit},
                ]
            },
        ]
    });
</script>