Vue入门使用


Vue简介

Jquery的复杂性问题

  • 使用jQuery进行前后端分离开发,既可以实现前后端交互(ajax),又可以完成数据渲染;
  • 存在的问题:jQuery需要通过HTML标签拼接、DOM节点操作完成数据的显示,开发效率低且容易出错,渲染效率较低
  • vue 是继jQuery之后的又一优秀的前端框架:专注于前端数据的渲染——语法简单、渲染效率高

VUE简介

前端框架

  • 前端三要素:HTML、CSS、JavaScript
    • HTML决定网页结构
    • CSS决定显示效率
    • JavaScript决定网页功能(交互、数据显示)
  • UI框架:
    • Bootstrap
    • amazeUI
    • Layui
  • JS框架:
    • jQuery(jQuery UI)
    • React
    • angular
    • nodejs—-后端开发
    • vue 集各种前端框架的优势发展而来

MVVM

项目结构经历的三个阶段:

后端MVC 我们就可以理解为单体架构,流程控制是由后端控制器来完成

前端MVC 前后端分离开发,后端只负责接收响应请求

MVVM 前端请求后端接口,后端返回数据,前端接收数据,并将接收的数据设置“VM”,HTML从vm取值

  • M model 数据模型 指的是后端接口返回的数据

  • V view 视图

  • VM ViewModel 视图模型 数据模型与视图之间的桥梁,后端返回的model转换前端所需的vm,视图层可以直接从vm中提取数据

Vue入门使用

vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合.

vue的引入

  1. 离线引用:下载vue的js文件,添加到前端项目,在网页中通过script标签引用vue.js文件
  2. CDN引用:

声明式渲染

<div id="app">
  {{msg}}
</div>

<script src="plugins/vue.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data:{
      msg:"vue-success"
    }
  })
</script>
  1. 渲染基本数据类型和字符串

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Document</title>
    </head>
    
    <body>
     <div id="app">
         {{id}}<br>
         {{msg}}<br>
         <!-- 支持ognl -->
         {{student.stuName}}
     </div>
     <script src="plugins/vue.js"></script>
     <script>
         var vue = new Vue({
             el:"#app",
             data:{
                 id:100,
                 msg:"天才帅管",
                 student:{
                     stuNum:"100001",
                     stuName:"管成功",
                     stuGender:'M',
                     stuAge:20
                 }
             }
         })
     </script>
    </body>
    </html>
    

v-if以及v-for的入门使用

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
</head>

<body>
 <div id="app">
     <!-- v-if -->
     <label v-if="student.stuGender=='M'"></label>
     <!-- v-for -->
     <table border="1" cellspacing="0" width="400">
         <tr>
             <th>序号</th>
             <th>学号</th>
             <th>姓名</th>
             <th>性别</th>
             <th>年龄</th>
         </tr>
         <tr v-for="s,index in stus">
             <td>{{index+1}}</td>
             <td>{{s.stuNum}}</td>
             <td>{{s.stuName}}</td>
             <td>{{s.stuGender=='M'?'男':'女'}}</td>
             <td>{{s.stuAge}}</td>
         </tr>
         </tr>
     </table>
 </div>
 <script src="plugins/vue.js"></script>
 <script>
     var vue = new Vue({
         el:"#app",
         data:{
             id:100,
             msg:"天才帅管",
             student:{
                 stuNum:"100001",
                 stuName:"管成功",
                 stuGender:'M',
                 stuAge:20
             },
             stus:[
                 {
                     stuNum:"100001",
                     stuName:"张大三",
                     stuGender:"M",
                     stuAge:23
                 },
                 {
                     stuNum:"100002",
                     stuName:"张中三",
                     stuGender:"M",
                     stuAge:22
                 },
                 {
                     stuNum:"100003",
                     stuName:"张小三",
                     stuGender:"F",
                     stuAge:20
                 }
             ]
         }
     })
 </script>
</body>
</html

v-bind绑定标签属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-bind:value='str'/><br>
        <!-- v-bind可以省略 -->
        <input type="text" :value='str'/><br>
    </div>
    <script src="plugins/vue.js"></script>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                str:'vue好傻比'
            }
        })
    </script>
</body>
</html>

v-model

表单的双向绑定

  • 只能使用在表单输入标签
  • v-model:value 可以简写为 v-model
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        {{msg}}<br>
        <input type="text" v-model:value='msg'>
    </div>
    <script src="plugins/vue.js"></script>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                msg:"hello-vue"
            }
        })
    </script>    
</body>
</html>

Vue实例

每个使用vue进行数据渲染的网页文档都需要创建一个Vue实例 —— ViewModel

Vue实例的生命周期

vue实例生命周期——vue实例从创建到销毁的过程

  • 创建vue实例(初始化data、加载el)

  • 数据挂载(将vue实例data中的数据渲染到网页HTML标签)

  • 重新渲染(当vue的data数据发生变化,会重新渲染到HTML标签)

  • 销毁实例

钩子函数

为了便于开发者在vue实例生命周期的不同阶段进行特定的操作,vue在生命周期四个阶段的前后分别提供了一个函数,这个函数无需开发者调用,当vue实例到达生命周期的指定阶段会自动调用对应的函数。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- v-once仅仅会渲染一次 -->
        <label v-once>{{msg}}</label>
        <label>{{msg}}</label>
        <input type="text" v-model:value="msg"></input>
    </div>
    <script src="plugins/vue.js"></script>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                msg:'hello-vue'
            },
            beforeCreate:function(){
                //1. data初始化之前,不能操作data
                console.log("beforeCreate...");
            },
            created:function(){
                //2. data初始化之后,模板加载之前,可以修改/获取data的值
                console.log(this.msg);
                this.msg='created';
            },
            beforeMount:function(){
                //3.模板加载之后,数据初始渲染(挂载)之前,可以修改/获取data中的值
                //this.str = "庙里有口井";
                console.log("beforeMount");
                this.msg='beforeMount';    
            },
            mounted:function(){
                //4. 数据初始渲染(挂载)之后,可以对data中的变量进行修改,但是不会影响v-once的渲染
                console.log("mounted");
                this.msg='mounted';  
            },
            beforeUpdate:function(){
                //5. 数据渲染之后,当data中的数据发生变化触发重新渲染,渲染之前执行此函数
                console.log("beforeUpdate===="+this.msg);
                this.msg='beforeUpdate';
            },updated:function(){
                //6.data数据被修改之后,重新渲染到页面之后
                //this.str = "从前有座山3";
            },
            beforeDestroy:function() {
                //vue实例销毁之前...
                console.log("beforeDestroy...")
            },
            destroyed:function() {
                //vue实例销毁之后
                console.log("destroyed..");
            }
        })
    </script>
</body>
</html>

Vue计算属性和侦听器

计算属性

  • data中的属性可以通过声明获得,也可以通过在computed通过计算获得

  • 特性:计算属性所依赖的属性值发生变化会影响计算属性的值同时发生变化

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model:value='count1'>
        <input type="text" v-model:value='count2'>
        {{count3}}
    </div>
   
    <script src="plugins/vue.js"></script>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                count1:1,
                count2:2
            },
            computed:{
                count3:function(){
                    return parseInt(this.count1) + parseInt(this.count2);
                }
            }
        })
    </script>
</body>
</html>

侦听器

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
</head>

<body>
 <div id="app">
     <input type="text" v-model:value='count1'>
     <input type="text" v-model:value='count2'>
     {{count3}}
 </div>
 <script src="plugins/vue.js"></script>
 <script>
     var vue = new Vue({
         el:"#app",
         data:{
             count1:1,
             count2:2,
             count3:3
         },
         watch:{
             count1:function(){
                 this.count3 = parseInt(this.count1)+parseInt(this.count2)
             },
             count2:function(){
                 this.count3 = parseInt(this.count1)+parseInt(this.count2)
             }
         }
     })
 </script>
</body>
</html>

class与style绑定

我们可以使用mustache语法将vue中data的数据绑定到HTML标签及标签的属性,如何将data中的值绑定到标签的class及style属性呢?

class绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .mystyle1{
            width: 200px;
            height: 100px;
            background: orange;
        }
        .mystyle3{
            width: 200px;
            height: 100px;
            background: black;
        }
        .my-style2{
            border-radius: 10px;
        }
    </style>
</head>
<body>
    <div id="app">
        <!--如果b1为true就加载 mystyle1;如果b2为true,则加载my-style2-->
        <!-- 注意如果样式名是xx-yy,需要加上单引号进行包裹'xx-yy' -->
        <div :class="{mystyle1:b1,'my-style2':b2}"></div>
        <!--为class属性加载多个样式名 -->
        <hr>
        <div :class="[chooseStyle1,chooseStyle2]"></div>
        <br>
        <!--如果b3为true,则class='mystyle3'; 否则class='mystyle1'
            如果在三目运算中使用样式名则需加单引号,不加单引号则表示从data变量中获取样式名-->
        <div :class="[b1?'mystyle1':'my-style2']"></div>
        <br>
        <div :class="[b1?chooseStyle1:chooseStyle2]"></div>
    </div>

    <script src="plugins/vue.js"></script>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                b1:true,
                b2:true,
                chooseStyle1:"mystyle1",
                chooseStyle2:"my-style2"
            }
        })
    </script>
</body>
</html>

style绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!--当使用v-bind绑定内联样式时:
                1. 使用{}定义style样式,才能获取data中的值,{}要遵循JSON格式
                2. {}中不在使用style样式属性名“font-size”,而要使用对应的js属性名
                border-style-width ---  borderStyleWidth
            -->
        <div :style="{color:colorname,fontSize:fontsize+'px'}">亲爱的小管</div>

        <!--我们可以直接为style属性绑定一个data中定义好的内联样式的字符串-->
        <div :style="mystyle1">亲爱的小管</div>

        <!--我们可以直接为style属性绑定一个data中定义好的内联样式的对象-->
        <div :style="mystyle2">亲爱的小管</div>

        <!--可以在同一个style上通过数组引用多个内联样式的对象-->
        <div v-bind:style="[mystyle2,mystyle3]">亲爱的小管</div>

        
    </div>    

    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                colorname:'red',
                fontsize:30,
                mystyle1:"color:green;font-size:30px",
                mystyle2:{
                    color:"blue",
                    fontSize:"50px"
                },
                mystyle3:{
                    textShadow:"orange 3px 3px 5px"
                }
            }
        })
    </script>
</body>
</html>

条件与列表渲染

条件渲染

1. v-if使用

在html标签可以添加v-if指令指定一个条件,如果条件成立则显示此HTML标签,如果不成立则不显示当前标签;

条件可以是一个表达式也可以是一个具体的bool类型值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h3 v-if="code==1">可以看见我是可爱的小管</h3>
        <h3 v-if="b">看不到我</h3>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                code:1,
                b:false
            }
        })
    </script>
</body>
</html>

3. v-else使用

注意点:v-else标签需要紧跟在v-if的标签之后,中间不能有其他标签

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h3 v-if="code==1">可以看见我是可爱的小管</h3>
        <h3 v-if="b">看不到我</h3>
         <!--v-else标签需要紧跟在v-if的标签之后,中间不能有其他标签-->
        <h3 v-else>嘿嘿</h3>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                code:1,
                b:false
            }
        })
    </script>
</body>
</html>

3. v-else-if

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h3 v-if="code==1">可以看见我是可爱的小管</h3>
        <h3 v-if="b">看不到我</h3>
         <!--v-else标签需要紧跟在v-if的标签之后,中间不能有其他标签-->
        <h3 v-else>嘿嘿</h3>
        <hr>
        <h3 v-if="level >= 90">优秀</h3>
        <h3 v-else-if="level >= 80">良好</h3>
        <h3 v-else-if="level >= 70">中等</h3>
        <h3 v-else-if="level >= 60">及格</h3>
        <h3 v-else>不想理你</h3>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                code:1,
                b:false,
                level:85
            }
        })
    </script>
</body>
</html>

4. v-if和v-show区别

从功能上将v-show和v-if作用是相同的,渲染过程有区别

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

列表渲染

将集合数据以表格、列表的形式显示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
    <title>Document</title>
    <link rel="stylesheet" href="plugins/bootstrap/css/bootstrap.min.css"></link>
    <style>
        img{
        
            height: 30px;
        }
    </style>
</head>
<body>
    <div id="app">
        <ol>
            <li v-for="c in catagories">
                <a :href="'query?cid='+c.cid">{{c.cname}}</a>
            </li>
        </ol>
        <hr>
        <table class="table table-bordered">
            <tr>
                <th>序号</th>
                <th>学号</th>
                <th>照片</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>操作</th>
            </tr>
            <template v-for="s,index in stus">
                <tr :id="'tr'+s.stuNum">
                    <td>{{index+1}}</td>
                    <td>{{s.stuNum}}</td>
                    <td><img :src="'imgs/'+s.stuImg"></td>
                    <td>{{s.stuName}}</td>
                    <td>
                        <!--{{s.stuGender=='M'?'男':'女'}}-->
                        <img v-if="s.stuGender=='M'" src="imgs/m.bmp">
                        <img v-else src="imgs/f.bmp">
                    </td>
                    <td>{{s.stuAge}}</td>
                    <td>
                        <a class="btn btn-danger btn-xs" :href="'stu/delete?cid='+s.stuNum">删除</a>
                        <a class="btn btn-success btn-xs" :href="'stu/update?cid='+s.stuNum">修改</a>
                    </td>
                </tr>
            </template>
        </table>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                catagories:[{
        
                    cid:1,
                    cname:"华为"
                },
                {
                    cid:2,
                    cname:"小米"
                },
                {
                    cid:3,
                    cname:"OPPO"
                },
                {
                    cid:4,
                    cname:"VIVO"
                        
                }],
                stus:[
                    {
                        stuNum:"10010",
                        stuImg:"01.jpg",
                        stuName:"Tom",
                        stuGender:"M",
                        stuAge:20
                    },
                    {
                        stuNum:"10011",
                        stuImg:"02.jpg",
                        stuName:"LiLei",
                        stuGender:"M",
                        stuAge:20
                    },
                    {
                        stuNum:"10012",
                        stuImg:"03.jpg",
                        stuName:"Lucy",
                        stuGender:"F",
                        stuAge:20
                    },
                    {
                        stuNum:"10013",
                        stuImg:"04.jpg",
                        stuName:"Polly",
                        stuGender:"F",
                        stuAge:20
                    }
                ]
            }
        })
    </script>
    <script src="plugins/jquery/jquery.min.js"></script>
    <script src="plugins/bootstrap/js/bootstrap.js"></script>
</body>
</html>

事件处理

  • 在使用vue进行数据渲染时,如果使用原生js事件绑定(例如onclick),如果需要获取vue实例中的数据并传参则需要通过拼接来完成
  • vue提供了v-on指令用于绑定各种事件(v-on:click),简化了从vue取值的过程,但是触发的方法需要定义在vue实例的 methods中
  • v-on:click可以缩写为@click`

hello案例

<div id="app">
  <button v-on:click="counter+=1">计数</button>
  <label>{{counter}}</label>
</div>

<script src="plugins/vue.js"></script>
<script>
  var vue = new Vue({
    el:"#app",
    data:{
      counter:1
    }
  })
</script>

原生js函数传值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <button @click="add('admin',100)">原生js函数传参</button>
        <button @click="add(name,age)">原生js函数传参</button>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                name:'tom',
                age:18
            },
            methods:{
                add:function(name,age){
                    console.log(name+"->"+age);
                }
            }
        })
    </script>
</body>
</html>

使用dataset对象传值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <button @click="add" :data-name='name' :data-age='age'>dataset对象传参</button>
        <button @click="add" :data-name="'admin'" :data-age='18'>dataset对象传参</button>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                name:'tom',
                age:18
            },
            methods:{
                add:function(event){
                    // //如果v-on绑定的js函数没有参数,调用的时候可以省略(),同时可以给js函数一个event参数(事件对象)
                     // 1. event 表示触发当前函数的事件
                     // 2. event.srcElement 表示发生事件的元素---修改按钮
                    // 3. event.srcElement.dataset 表示按钮上绑定的数据集(data-开头的属性)
                    let result = event.srcElement.dataset;
                    console.log(result)
                    console.log(result.name+":"+result.age)
                }
            }
        })
    </script>
</body>
</html>

混合使用

js函数传值和dataset对象传值,俩者混合使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
       <button type="button" @click="add(name,age,$event)" :data-sno="sno">混合使用</button>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                name:'tom',
                age:18,
                sno:"1001"
            },
            methods:{
                add:function(name,age,event){
                    console.log(name+"->"+age)
                    // //如果v-on绑定的js函数没有参数,调用的时候可以省略(),同时可以给js函数一个event参数(事件对象)
                     // 1. event 表示触发当前函数的事件
                     // 2. event.srcElement 表示发生事件的元素---修改按钮
                    // 3. event.srcElement.dataset 表示按钮上绑定的数据集(data-开头的属性)
                    let result = event.srcElement.dataset;
                    console.log(result)
                    
                }
            }
        })
    </script>
</body>
</html>

事件修饰符

当使用v-on进行事件绑定的时候,可以添加特定后缀,设置事件触发的特性

事件修饰符使用示例

<button type="submit" @click.prevent="事件函数">测试</button>
  1. .prevent 消除元素的默认事件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="plugins/bootstrap/css/bootstrap.min.css">
    </head>
    <body>
        <div id="app">
            <form action="http://www.baidu.com">
                <button type="submit" class="btn btn-success btn-xs" @click.prevent='test'>prevent</button>
            </form>
        </div>
        <script src="plugins/vue.js"></script>
        <script>
            var vue=new Vue({
                el:"#app",
                methods: {
                    test:function(){
                        console.log("prevent...");
                    }
                }
            })
        </script>
    </body>
    </html>
    
  2. 阻止事件冒泡(阻止子标签向上冒泡)

  3. 设置只能自己触发事件(子标签不能触发)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="plugins/bootstrap/css/bootstrap.min.css">
    </head>
    <body>
        <div id="app">
            <form action="http://www.baidu.com">
                <button type="submit" class="btn btn-success btn-xs" @click.prevent='test'>prevent</button>
            </form>
            <hr>
            <div style="width: 200px; height: 200px; background: red;" @click.self="method1">
                <div style="width: 150px; height: 150px; background: green;" @click='method2'>
                    <button type="button" @click.stop="method3">测试</button>
                </div>
            </div>
        </div>
        <script src="plugins/vue.js"></script>
        <script>
            var vue=new Vue({
                el:"#app",
                methods: {
                    test:function(){
                        console.log("prevent...");
                    },
                    method1:function(){
                        alert(1);
                    },
                    method2:function(){
                        alert(2);
                    },
                    method3:function(){
                        alert(3);
                    }
                }
            })
        </script>
    </body>
    </html>
    
  1. .once - 限定事件只触发一次

按键修饰符

按键修饰符就是针对键盘事件的修饰符,限定哪个按键会触发事件

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名

.enter

.tab

.delete (捕获“删除”和“退格”键)

.esc

.space

.up

.down

.left

.right

<div id="app">
  <!-- 光标在文本框中时输入enter键可以触发test01函数 -->
  <input type="text" @keyup.enter='test01'>
</div>
<script src="plugins/vue.js"></script>
<script>
  var vue = new Vue({
    el:"#app",
    methods: {
      test01:function(){
        console.log("enter...")
      }
    }
  })
</script>

修饰符别名

除了以上vue提供按钮的别名之外,我们还可以根据键盘为按键自定义别名

你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- 光标在文本框中时输入enter键可以触发test01函数 -->
        <input type="text" @keyup.enter='test01'>

        <!--2.使用自定义的按键别名aaa作为修饰符--> 
        <input type="text" @keyup.aaa='test02'>
    </div>
    <script src="plugins/vue.js"></script>
    <script>
        //为按键a定于别名为 aaa
        Vue.config.keyCodes.aaa=65;
        var vue = new Vue({
            el:"#app",
            methods: {
                test01:function(){
                    console.log("enter...")
                },
                test02:function(){
                    console.log('修饰符别名');
                }
            }
        })
    </script>
</body>
</html>

系统修饰符

组合键

  • .ctrl
  • .alt
  • .shift
  • .meta windows键
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- 1 - 光标在文本框中时输入enter键可以触发test01函数 -->
        <input type="text" @keyup.enter='test01'>

        <!--2.使用自定义的按键别名aaa作为修饰符--> 
        <input type="text" @keyup.aaa='test02'>

        <!-- 3 - 系统修饰符 - ctrl+a -->
        <input type="text" @keyup.control.aaa='test03'>
    </div>
    <script src="plugins/vue.js"></script>
    <script>
    
        //为按键a定于别名为 aaa
        Vue.config.keyCodes.aaa=65;

        var vue = new Vue({
            el:"#app",
            methods: {
                test01:function(){
                    console.log("enter...")
                },
                test02:function(){
                    console.log('修饰符别名');
                },
                test03:function(){
                    console.log('系统修饰符');
                }
            }
        })
    </script>
</body>
</html>

表单输入绑定

表单输入绑定,即双向绑定:就是能够将vue实例的data数据渲染到表单输入视图(input\textarea\select),也能够将输入视图的数据同步更新到vue实例的data中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="plugins/bootstrap/css/bootstrap.min.css">
</head>
<body>
    <div id="app">
        <input type="text" v-model="msg">{{msg}}
        <hr>
        <div id="example-4">
            <input type="radio" id="one" value="One" v-model="picked">
            <label for="one">One</label>
            <br>
            <input type="radio" id="two" value="Two" v-model="picked">
            <label for="two">Two</label>
            <br>
            <span>Picked: {{ picked }}</span>
        </div>
        <hr>
        <div>
            <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
                <label for="jack">Jack</label>
                <input type="checkbox" id="john" value="John" v-model="checkedNames">
                <label for="john">John</label>
                <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
                <label for="mike">Mike</label>
                <br>
            <span>Checked names: {{ checkedNames }}</span>
        </div>
        <hr>
        <!--下拉菜单select:绑定一个字符串-->
        <select v-model="city">
            <option value="BJ">北京</option>
            <option value="SH">上海</option>
            <option value="GZ">广州</option>
            <option value="SZ">深圳</option>
        </select>
        {{city}}
    </div>

    <script src="plugins/vue.js"></script>
    <script>
        var vue = new Vue({
            el:"#app",
            data:{
                msg:"msg",
                picked:"Two",//此处如果写值,代表默认勾选value="Two"的按钮
                //picked:""
                //checkedNames:[]
                checkedNames:["John"],//代表默认选中value='John'的复选框
                city:"GZ"
            }
        })
    </script>
</body>
</html>

组件介绍和使用

组件介绍及示例

组件,就是将通用的HTML模块进行封装——可复用

自定义组件的结构

  • data 定义组件的模板渲染的数据
  • template 组件的HTML模块(HTML标签\css样式)
  • methods 定义组件中的标签事件绑定的JS函数

全局组件注册

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="plugins/bootstrap/css/bootstrap.min.css">
</head>
<body>

    <div id="app">
        <header-bar></header-bar>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script>
        const Feature = Vue.component('header-bar',{
            data:function(){
                return {
                    title:"亲爱的小管"
                }
            },
            template:`<div style="width: 100%; height: 80px; background: lightyellow;">
                <table width="100%">
                    <tr>
                        <td width="200" align="right" valign="middle">
                            <img src="img/logo.png" height="80">
                        </td>
                        <td>
                            <label style="color: deepskyblue;font-size:32px; font-family: 华文行楷; margin-left: 30px;">
                            {{title}}
                            </label>
                        </td>
                        <td>
                            <button @click="test">组件中的按钮</button>
                        </td>
                    </tr>
                </table>
            </div>`,
            methods:{
                test:function(){
                    alert("组件中定义的函数")
                }
            }
        }
    );
    var vm = new Vue({
        el:"#app"
    })
    </script>
</body>
</html>

私有组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <login></login>
    </div>

    <template id="tmp1">
        此处必须要有一个根元素
        <div>
            <h3>我是一个私有组件</h3>
        </div>
    </template>
    
    <script src="plugins/vue.js"></script>
    <script>
        
        var vm = new Vue({
            el:"#app",
            components:{
                login:{
                    template:"#tmp1"
                }
            }
        })
    </script>
</body>
</html>

切换组件

Vue提供了component来展示对应名称的组件 component是一个占位符 :is属性用来指定要显示的组件的名称

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
    <div id="app">
        <a href="" @click.prevent="cname='login'">登录</a>
        <a href="" @click.prevent="cname='register'">注册</a>
        
        <!-- Vue提供了component来展示对应名称的组件
        component是一个占位符
        :is属性用来指定要显示的组件的名称 -->
        <component :is="cname"></component>
    </div>
    <script src="plugins/vue.js"></script>
    <script>
        Vue.component('login',{
            template:'<h3>登录组件</h3>'
        })

        Vue.component('register',{
            template:'<h3>注册组件</h3>'
        })

        new Vue({
            el:"#app",
            data:{
                cname:"login"
            }
        })
    </script>
</body>
</html>

组件通信

vue实例本身就是一个组件(模板就是el指定容器 ,data就是组件数据,methods就是组件的事件函数)
在vue实例指定的el容器中引用的组件称为子组件 ,当前vue实例就是父组件

父传子

vue实例引用组件的时候,传递数据到引用的组件中,示意图

代码示例父中代码

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
</head>
<body>
 <div id="app">
     <header-bar :title=str></header-bar>
 </div>
 
 <script src="plugins/vue.js"></script>
 <script src="js/tmp.js"></script>
 <script>
     var vm = new Vue({
         el:"#app",
         data:{
             "str":"父传子"
         }
     })
 </script>
</body>
</html>

子组件示例

props:[“title”]

const Feature = Vue.component('header-bar',{
 data:function(){
     return {
         //title:"亲爱的小管"
     }
 },
 template:`<div style="width: 100%; height: 80px; background: black;">
     <table width="100%">
         <tr>
             <td width="200" align="right" valign="middle">
                 <img src="imgs/logo.png" height="80">
             </td>
             <td>
                 <label style="color: deepskyblue;font-size:32px; font-family: 华文行楷; margin-left: 30px;">
                 {{title}}
                 </label>
             </td>
             <td>
                 <button @click="test">组件中的按钮</button>
             </td>
         </tr>
     </table>
 </div>`,
 props:["title"],
 methods:{
     test:function(){
         alert("组件中定义的函数")
     }
 }
}
);

子传父

通过子组件的按钮“调用”父组件的函数,通过函数传值.示意图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <header-bar @my-event='parentMethod'></header-bar>
        从子组件传递过来的数据{{str1}} - {{str2}}
    </div>
    <script src="plugins/vue.js"></script>
    <script>
        //子组件定义
        Vue.component('header-bar',{
            data:function(){
                return{
                    msg1:"子组件数据msg1",
                    msg2:"子组件数据msg2"
                }
            },
            template:'<button type="button" @click="childMethod">子传父</button>',
            methods:{
                childMethod:function(){
                    this.$emit('my-event', this.msg1,this.msg2);
                }
            }
        });
        var vm = new Vue({
            el:"#app",
            data:{
                str1:"",
                str2:""
            },
            methods:{
                parentMethod:function(m1,m2){
                   this.str1 = m1;
                   this.str2 = m2;
                }
            }
        })
    </script>
</body>
</html>

组件插槽

当我们自定义vue组件时,允许组件中的部分内容在调用组件时进行定义——插槽

  1. 插槽的使用

    在自定义组件时通过slot标签在组件的模版中定义插槽

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
          
        <div id="app">
            <header-bear :title="title">
                <label style="color: red;">填充到slot插槽位置中的内容</label>
            </header-bear>
        </div>
              
        <script src="plugins/vue.js"></script>
        <script>
            const Feature = Vue.component('header-bear',{
                data:function(){
                    return {
                       // title:"子组件中的数据"
                    }
                },
                template:`
                    <div>
                        <h3>此处下方有插槽</h3>
                        <slot></slot>
                        <h3>此处上方有插槽=>{{title}}</h3>
                    </div>
                     `,
                props:["title"]
            });
            var vm = new Vue({
                el:"#app",
                data:{
                    title:"父组件中的数据"
                }
            })
        </script>
    </body>
    </html>
    
  1. 具名插槽

    当组件中的插槽数量>1时,需要给组件中的slot标签添加name属性指定插槽的名字

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
          
        <div id="app">
            <header-bear :title="title">
                <template slot="s1">
                    <label style="color: red;">填充到slot01插槽位置中的内容</label>
                </template>
                <template slot="s2">
                    <label style="color: yellow;">填充到slot02插槽位置中的内容</label>
                </template>
            </header-bear>
        </div>
              
        <script src="plugins/vue.js"></script>
        <script>
            const Feature = Vue.component('header-bear',{
                data:function(){
                    return {
                       // title:"子组件中的数据"
                    }
                },
                template:`
                    <div>
                        <h3>此处下方有插槽</h3>
                        <slot name='s1'></slot>
                        <h3>此处下方有插槽=>{{title}}</h3>
                        <slot name='s2'></slot>
                    </div>
                     `,
                props:["title"]
            });
            var vm = new Vue({
                el:"#app",
                data:{
                    title:"父组件中的数据"
                }
            })
        </script>
    </body>
    </html>
    
  1. 插槽作用域

    定义组件时,将组件中的数据绑定到slot标签

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
          
        <div id="app">
            <header-bear :title="title">
                <template slot="s1" slot-scope="res">
                    <label style="color: red;">填充到slot01插槽位置中的内容</label>
                     <!--在使用模版填充组件插槽时,可以使用slot-scope属性获取组件插槽绑定的数据的集合 -->
                    {{res.stus}}
                </template>
                      
                <template slot="s2">  
                    <label style="color: yellow;">填充到slot02插槽位置中的内容</label>
                </template>
            </header-bear>
        </div>
              
        <script src="plugins/vue.js"></script>
        <script>
            const Feature = Vue.component('header-bear',{
                data:function(){
                    return {
                       // title:"子组件中的数据"
                       students:[{
                            id:1,
                            name:"admin"
                        },{
                            id:2,
                            name:"tom"
                        }]
                    }
                },
                template:`
                    <div>
                        <h3>此处下方有插槽</h3>
                        <slot name='s1' :stus="students"></slot>
                        <h3>此处下方有插槽=>{{title}}</h3>
                        <slot name='s2'></slot>
                    </div>
                     `,
                props:["title"]
            });
            var vm = new Vue({
                el:"#app",
                data:{
                          
                }
            })
        </script>
    </body>
    </html>
    

axios

vue可以实现数据的渲染,但是如何获取数据呢?

vue本身不具备通信能力,通常结合axios—一个专注于异步通信的js框架来使用

  • axios 数据通信
  • vue 数据渲染

axios入门

  • 原生ajax — 实现步骤复杂
  • jQuery 笨重
  • axios 简洁、高效,对RESTful支持良好

案例

  1. get请求 - 查询所有

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="app">
          
            <button type="button" v-on:click='search'>get查所有</button>
            <label>{{user}}</label>
        </div>
        <script src="plugins/vue.js"></script>
        <script src="plugins/axios.min.js"></script>
        <script>
            var vm = new Vue({
                el:"#app",
                data:{
                    user:''
                },
                methods:{
                    search:function(){
                        axios.get('http://localhost:8888/axios').then(function(res){
                            console.log(res.data.data)
                            vm.user = res.data.data
          
                        })
                    }
                }
            })
        </script>
    </body>
    </html>
    

    后端

    @CrossOrigin
    @Api(value = "axios",tags = "axios交互接口")
    @RestController
    @RequestMapping("/axios")
    public class AxiosController {
        @ApiOperation("查询所有")
        @GetMapping
        public ResultVO hello(){
            Users users = new Users();
            users.setNickname("梦中人");
            users.setRealname("亲爱的小管");
            users.setUserBirth(new Date());
            return new ResultVO(200,"get请求",users);
          
        }
    }
    
  1. get请求传参- 使用params

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="app">
          
            <button type="button" v-on:click='search'>get查所有</button>
            <button type="button" v-on:click='search2("admin",18)'>get传参</button>
            <label>{{user}}</label>
        </div>
        <script src="plugins/vue.js"></script>
        <script src="plugins/axios.min.js"></script>
        <script>
            var vm = new Vue({
                el:"#app",
                data:{
                    user:''
                },
                methods:{
                    search:function(){
                        axios.get('http://localhost:8888/axios').then(function(res){
                            console.log(res.data.data)
                            vm.user = res.data.data
          
                        })
                    },
                    search2:function(name,id){
                        axios.get('http://localhost:8888/axios',{
                            params:{
                                name:name,
                                id:id
                            }
                        }).then(function(res){
                            console.log(res.data.data)
                            vm.user = res.data.data
          
                        })
                    },
                }
            })
        </script>
    </body>
    </html>
    

    后端

    @ApiOperation("传参")
    @GetMapping
    public ResultVO hello2(String name,Integer id){
      Users users = new Users();
      users.setNickname(name);
      users.setUserId(id);
      users.setUserBirth(new Date());
          
      return new ResultVO(200,"get请求接受参数",users);
    }
    
  1. get请求传参-字符串拼接形式

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="app">
    
            <button type="button" v-on:click='search'>get查所有</button>
            <button type="button" v-on:click='search2("admin",18)'>get传参</button>
            <label>{{user}}</label>
        </div>
        <script src="plugins/vue.js"></script>
        <script src="plugins/axios.min.js"></script>
        <script>
            var vm = new Vue({
                el:"#app",
                data:{
                    user:''
                },
                methods:{
                    search:function(){
                        axios.get('http://localhost:8888/axios').then(function(res){
                            console.log(res.data.data)
                            vm.user = res.data.data
    
                        })
                    },
                    // search2:function(name,id){
                    //     axios.get('http://localhost:8888/axios',{
                    //         params:{
                    //             name:name,
                    //             id:id
                    //         }
                    //     }).then(function(res){
                    //         console.log(res.data.data)
                    //         vm.user = res.data.data
    
                    //     })
                    // },
                    search2:function(name,id){
                        axios.get('http://localhost:8888/axios?name='+name+'&id='+).then(function(res){
                            console.log(res.data.data)
                            vm.user = res.data.data
    
                        })
                    }
                }
            })
        </script>
    </body>
    </html>
    

    后端

    @ApiOperation("传参")
    @GetMapping
    public ResultVO hello2(String name,Integer id){
      Users users = new Users();
      users.setNickname(name);
      users.setUserId(id);
      users.setUserBirth(new Date());
    
      return new ResultVO(200,"get请求接受参数",users);
    }
    
  2. get请求传参restful

    search2:function(name,id){
      axios.get('http://localhost:8888/axios/'+name+'/'+id).then(function(res){
      console.log(res.data.data)
      vm.user = res.data.data
          
      })
    }
    
    @ApiOperation("传参")
    @GetMapping("/{name}/{id}")
    public ResultVO hello2(@PathVariable("name") String name, @PathVariable("id") Integer id){
      Users users = new Users();
      users.setNickname(name);
      users.setUserId(id);
      users.setUserBirth(new Date());
          
      return new ResultVO(200,"get请求接受参数restful",users);
          
    
  1. post请求

    search3:function(name,id){
      axios.post('http://localhost:8888/axios/'+name+'/'+id).then(function(res){
      console.log(res.data.data)
      vm.user = res.data.data
      })
    }
    

    或者

    search3:function(name,id){
      axios.post('http://localhost:8888/axios?name='+name+'&id='+id).then(function(res){
        console.log(res.data.data)
        vm.user = res.data.data
      })
    }
    
  1. post请求注意点

    如果前端发送参数是这样写的

    search3:function(name,id){
      axios.post('http://localhost:8888/axios',{
        username:name,
        userId:id
    
      }).then(function(res){
        console.log(res.data.data)
        vm.user = res.data.data
    
      })
    }
    

    那么后端接受数据的时候需要配合使用@RequestBody

    @ApiOperation("传参")
    @PostMapping
    public ResultVO hello3(@RequestBody Users users){
      System.out.println(users);
    
      return new ResultVO(200,"get请求接受参数",users);
    }
    
  2. delete请求

    axios.delete('http://localhost:8888/axios',{
      params:{
        username:name,
        userId:id
      }
    或者
    search4:function(name,id){
      axios.delete('http://localhost:8888/axios/'+name+'/'+id)
        .then(function(res){
        console.log(res.data.data)
        vm.user = res.data.data
          
      })
    }
    或者使用字符串拼接
    

执行多个并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));

箭头函数

//箭头函数
search4:function(name,id){
  axios.delete('http://localhost:8888/axios/'+name+'/'+id)
    .then(res=>{
    console.log(res);
    vm.user = res.data.data
  })

}

路由router

单页面应用中使用场景居多

router是由vue官方提供的用于实现组件跳转的插件

下载

路由插件的引用

离线使用

<script type="text/javascript" src="plugins/vue.js" ></script>
<script type="text/javascript" src="plugins/vue-router.js"></script>

在线CDN

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

入门案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div>
            <router-link to="/a">登录</router-link>
            <router-link to="/b">注册</router-link>
        </div>
        <hr>
        <div>
            <router-view></router-view>
        </div>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {template:`<p>login</p>`}
        const t2 = {template:`<p>register</p>`}

        const myrouter = new VueRouter({
            routes:[
                {
                    path:"/a",
                    component:t1
                },
                {
                    path:'/b',
                    component:t2
                }
            ]
        });

        var vm = new Vue({
            el:"#app",
            router:myrouter
        })
    </script>
</body>
</html>

动态路由匹配

通配符*可以匹配任意路径

例如:

  • /user-* 匹配所有以user-开头的任意路径
  • /* 匹配所有路径

注意如果使用通配符定义路径,需要注意路由声明的顺序

示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div>
            <router-link to="/user-login">登录</router-link>
            <router-link to="/register">注册</router-link>
        </div>
        <hr>
        <div>
            <router-view></router-view>
        </div>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {template:`<p>login</p>`}
        const t2 = {template:`<p>register</p>`}

        const myrouter = new VueRouter({
            routes:[
                {
                    path:"/user-*",
                    component:t1
                },
                {
                    path:'/*',
                    component:t2
                }
            ]
        });

        var vm = new Vue({
            el:"#app",
            router:myrouter
        })
    </script>
</body>
</html>

路由传参

/a/:id 可以匹配 /a/开头的路径

用于获取参数

示例如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-link to="/a/100">删除</router-link>
        <router-view></router-view>
    </div>
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {template:`<label>{{$route.params.id}}</label>`}

        const myrouter = new VueRouter({
            routes:[{
                path:"/a/:id",
                component:t1
            }]
        })
        var vm = new Vue({
            el:"#app",
            router:myrouter
        })
    </script>
</body>
</html>

通过props传参

<div id="container">
    <router-link to="/a/102">路径A</router-link>
    <router-view></router-view>
</div>
<script type="text/javascript">
    const t1 = {
        props:["id"],
        template:`<div style='width:400px; height:200px; border:blue 1px solid'>
                index:{{id}}
                </div>`
    };

    const myrouter = new VueRouter({
        routes:[
            {
                path:"/a/:id",
                props:true,
                component:t1

            }
        ]
    });

    var vm = new Vue({
        el:"#container",
        router:myrouter
    });
</script>

嵌套路由

在一级路由的组件中显示二级路由

示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-link to="/a">首页</router-link>
        <router-link to="/a/c1">首页-c1</router-link>
        <router-link to="/a/c2">首页-c2</router-link>
        <router-view></router-view>
    </div>
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {template:`<div style='border:1px solid red;width:500px;height:120px'>首页
            
                <h3>下面是子路由</h3>
                <router-view></router-view>
            </div>`}
        const t2 = {template:`<div>index-c1</div>`}
        const t3 = {template:`<div>index-c2</div>`}

        const myrouter = new VueRouter({
            routes:[{
                path:"/a",
                component:t1,
                children:[{
                    path:"c1",
                    component:t2
                },
                {
                        path:"c2",
                        component:t3
                }
                ]
            }]
        })
        var vm = new Vue({
            el:"#app",
            router:myrouter
        })
    </script>
</body>
</html>

编程式导航

hello示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <button type="button" @click='test'>push</button>
        <router-view></router-view>
    </div>
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {template:`<div>index</div>`}
        const myrouter = new VueRouter({
        routes:[
            {
                path:"/a",
                component:t1
            }
        ]
    });
        var vm = new Vue({
            el:"#app",
            router:myrouter,
            methods:{
                test:function(){
                //js代码实现路由跳转:编程式导航
                myrouter.push("/a");
                }
            }
        })
    </script>
</body>
</html>

push参数

  1. 字符串

    myrouter.push(“/a”);

  2. 对象

    myrouter.push({path:”/a”})

  3. 命名路由

    // myrouter.push({
    //     name:"r1",
    //     params:{id:100}
    // })
    
    const myrouter = new VueRouter({
    routes:[
     {
       path:"/a/:id",
       name:"r1",
       component:t1
     }
    ]
    });
    

    给路由取个名字 - 路由的命名

    params传参 - 接受参数如下

    const t1 = {template:`<div>index=>{{$route.params.id}}</div></div>`}
    
  1. url传参 相当于/a?id=101

    // myrouter.push({
    //     name:"r1",
    //     query:{
    //         id:101
    //     }
    // })
    

    query传参,接受参数如下

    const t1 = {template:`<div>index=>{{$route.query.id}}</div></div>`}
    
  1. restful传参 相当于/a/100

     myrouter.push({
       path:"/a/200"
     })
    
    routes:[
      {
        path:"/a/:id",
        name:"r1",
        component:t1
      }
    ]
    

    restful接受参数如下

     const t1 = {template:`<div>index=>{{$route.params.id}}</div></div>`}
    

示例代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <button type="button" @click='test'>push</button>
        <router-view></router-view>
    </div>
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {template:`<div>index=>{{$route.params.id}}</div></div>`}
        const myrouter = new VueRouter({
        routes:[
            {
                path:"/a/:id",
                name:"r1",
                component:t1
            }
        ]
    });
        var vm = new Vue({
            el:"#app",
            router:myrouter,
            methods:{
                test:function(){
                //js代码实现路由跳转:编程式导航
                //1. 字符串
                //myrouter.push("/a");

                //2. 对象
                //myrouter.push({path:"/a"})

                //3. 命名的路由
                // myrouter.push({
                //     name:"r1",
                //     params:{id:100}
                // })

                //4. url传参 相当于/a?id=101
                // myrouter.push({
                //     name:"r1",
                //     query:{
                //         id:101
                //     }
                // })

                //5. restful
                myrouter.push({
                    path:"/a/200"
                })
             }
            }
        })
    </script>
</body>
</html>

replace()

功能与push一致,区别在于replace()不会向history添加新的浏览记录

go()

参数为一个整数,表示在浏览器历史记录中前后/后退多少步 相当于window.history.go(-1)的作用

命名路由

命名路由:在定义路由的时候可以给路由指定name,我们在进行路由导航时可以通过路由的名字导航

示例如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="sname">
        <button @click='test'>命名路由</button><br>
        <router-link :to="{name:sname}">login</router-link>
        <router-link :to="{name:sname}">register</router-link>
        <router-view></router-view>
    </div>
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {template:"<div>login</div>"};
        const t2 = {template:"<div>register</div>"};
        const myrouter = new VueRouter({
            routes:[{
                path:'/a',
                name:'login',
                component:t1
            },{
                path:'/b',
                name:'register',
                component:t2
            }]
        });
        var vm = new Vue({
            el:"#app",
            data:{
                sname:"register"
            },
            router:myrouter,
            methods:{
                test:function(){
                    myrouter.push({
                        name:vm.sname
                    })
                }
            }

        })
    </script>
</body>
</html>

命名路由视图

如果在HTML中有一个以上的路由视图router-view,需要给router-view指定name,在路由中使用components映射多个组件根据name设置组件与router-view绑定关系

示例如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-link to="/a">t1</router-link>
        <router-link to="/b">t2</router-link>

           <!--路由视图-->
    <!--如果在HTML中有一个以上的路由视图router-view,需要给router-view指定name,在路由中使用components映射多个组件根据name设置组件与router-view绑定关系-->
        <router-view name="v1"></router-view>
        <router-view name="v2"></router-view>
    </div>
    
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>

    <script>
         const t11 = {
            template:"<div style='width:400px; height:200px; border:blue 1px solid'>t11</div>"
        };
        const t12 = {
            template:"<div style='width:400px; height:200px; background:pink'>t12</div>"
        };

        const t21 = {
            template:"<div style='width:400px; height:200px; border:red 1px solid'>t21</div>"
        };
        const t22 = {
            template:"<div style='width:400px; height:200px; background:yellow'>t22</div>"
        };

        const myrouter = new VueRouter({
            routes : [
                {   path: '/a', 
                    components:{
                        v1:t11,
                        v2:t12
                    }
                 },

                {   path: '/b', 
                    components:{
                        v1:t21,
                        v2:t22
                    }
                 }
            ]
        })

        var vue = new Vue({
            el:"#app",
            router:myrouter
        })

    </script>
</body>
</html>

重定向和别名

  1. 根据路由路径重定向
  2. 根据路由name重定向
  3. 根据路由别名重定向

演示重定向

访问/b,重定向到/a

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-link to="/a">路径A</router-link>
        <router-link to="/b">路径B</router-link>
        <router-view></router-view>
    </div>
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {
         template:"<div style='width:400px; height:200px; border:blue 1px solid'>index</div>"
        };

        const myrouter = new VueRouter({
        routes:[
            {
                path:"/a",
                component:t1
            },
            {
                path:"/b",
                redirect:"/a"
            }
        ]
    });

    var vm = new Vue({
        el:"#app",
        router:myrouter
    });
    </script>
</body>
</html>

根据路由命名重定向

routes:[
  {
    path:"/a",
    name:"r1",
    component:t1
  },
  {
    path:"/b",
    //根据路径重定向
    //redirect:"/a"

    //根据路由命名重定向
    redirect:{name:"r1"}
  }
]

根据路由别名重定向

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-link to="/a">路径A</router-link>
        <router-link to="/b">路径B</router-link>

        <!-- 根据别名重定向 -->
        <router-link to="/guan">路由别名</router-link>
        <router-view></router-view>
    </div>
    <script src="plugins/vue.js"></script>
    <script src="plugins/vue-router.js"></script>
    <script>
        const t1 = {
         template:"<div style='width:400px; height:200px; border:blue 1px solid'>index</div>"
        };

        const myrouter = new VueRouter({
        routes:[
            {
                path:"/a",
                name:"r1",
                alias:"/guan",
                component:t1
            },
            {
                path:"/b",
                //根据路径重定向
                //redirect:"/a"

                //根据路由命名重定向
                redirect:{name:"r1"}
            }
        ]
    });

    var vm = new Vue({
        el:"#app",
        router:myrouter
    });
    </script>
</body>
</html>

ElementUI

官网-https://element.eleme.io/#/zh-CN

CDN在线引入

<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

离线方式 - 下载上述俩个文件,在html文件中引入即可


文章作者: 码农耕地人
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 码农耕地人 !
  目录