Bootstrap

Vue组件及路由

image.png

1.回顾

  • vuejs基础 - 补充

    • once  @click.once

    • capture

    • prevent 阻止事件默认行为

    • self

    • 事件修饰符

    • v-if 和 v-show 布尔变量

    • vueDevTools安装

  • vuejs进阶

    • {{ }} -  v-bind="txt|filter1 | filter2|"

    • 全局与局部

      Vue.filter('xxx',function(){})
    • var vm = new Vue({
         el:'',
         data:{},
         methods:{},
         filters:{
             xxx:function(){
                 
             }
         }
      });
    • 键盘修饰符与自定义指令

    • Vue实例生命周期

    • axios请求数据,加载到页面中模板元素显示

    • 局部:只能是当前所注册的vue实例所管理的模板可以使用

    • 全局: 所有的vue实例所管理的模板HTML标签 {{}}

    • 针对按键的一些细节来进行事件的处理

    • created() 常用

    • 过滤器filter 格式化文本  使用管道符调用过滤器

  • vuejs高级

    • 创建组件对象

      let login = Vue.extend({});

      let login ={
         属性名:值,
         ...
         template:"#id",
         data:
         methods:
      };
    • 注册组件

      全局注册
        Vue.component('组件名',组件对象);


      局部注册
        var vm = new Vue({
            el:,
            data:
            methods:
            filters:
            components:{
                  '组件名':组件对象
            }
        });
    • 使用组件

      <login></login>
    • 让哪个父组件可以使用定义的子组件

    • 界面组件化

    • 组件 - 拆分VUE实例代码

    • 定义组件

2.组件

2-1 定义组件 - 展示数据和响应事件

  • 在子组件中,data需要被定义一个方法

<template id="templ">
   <!-- 组件的模板元素必须只能有一个根元素 -->
   <div>
       <h2>登录组件 -{{msg}}</h2>
       <form action="login" method="post">
          用户:<input type="text" name="uname" /><br>
          密码:<input type="password" name="upass" /><br>
              <input type="submit" value="登录" @click.prevent="func()" />
         </form>
  </div>
</template>

<script>
       //1.定义组件对象
       let login = {
           template: "#templ", //模板
           data(){
               return {
                   msg:'hello,我是子组件login'
               }
           },
           methods:{
               func(){
                   alert('点击了登录!')
               }
           }
       };

       //2.注册全局子组件
       Vue.component('login', login);
</script>


//3.在父组件的模板中,使用子组件

<div id="app">
       <h1>我是父组件!</h1>
       <!-- 3引用子组件 -->
       <login></login>
</div>

注意:

 //注意:如果组件的命名采用的是驼峰命名法,则在引用组件时需要使用-分隔,比如:user-Login
Vue.component("userLogin",login);

<div id="app">
    <h1>我是父组件!</h1>
    <!-- 3引用子组件 -->
    <user-login></user-login>
</div>

2-2 定义局部子组件

  • 注册到哪个父组件中,则该子组件只能在这个父组件中引用

  • 子组件与父组件中的data数组 - 不能相互访问

<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
   <!-- 引入vuejs -->
   <script src="js/vue-2.6.12.js"></script>
</head>

<body>
   <div id="app">
       <h1>我是父组件!</h1>
       <!-- 3引用子组件 -->
       <account>
           <!-- <login></login>  此用法无效 -->
       </account>
   </div>


   <!--account子组件的模板-->
   <template id="accountTempl">
       <div>
           <h2>Account组件</h2>
           <login></login>
       </div>
   </template>

   <!--login子组件的模板-->
   <template id="loginTempl">
       <div>
           <h3>登录组件</h3>
           <button type="button" @click="func_login">按钮</button>
       </div>
   </template>


   <script>
       //1.定义组件对象
       // let account = {
       //     template:'#accountTempl'
       // };

       // let login = {
       //     template: "#loginTempl", //模板
       // };
       
       
       // 创建Vue实例对象
       var vm = new Vue({ //根组件
           el: '#app',
           data: {

           },
           methods: {

           },
           components: {
               //account  //如果组件的名称与组件对象名相同,可以只写一个

               //注册局部子组件
               account: {
                   template: '#accountTempl',
                   data(){
                       return {
                           msg:'我是account组件中的msg消息'
                       }
                   },
                   components:{
                       login:{
                           template: "#loginTempl", //模板
                           methods:{
                               func_login(){
                                   console.log(this); //表示当前登录login子组件vue对象
                                    //子组件不能访问父组件中的data数据
                                   console.log(this.msg);
                               }
                           }
                       }
                   }
               }
           }
       });
   </script>
</body>
</html>

2-4 组件的切换 - [了解]

示例1: 使用按钮控制flag属性,适用于两个组件之前切换

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
</head>

<body>
    <div id="app">
        <h1>我是父组件!</h1>
        <hr>
        <input type="button" value="切换" @click="flag=!flag"><br>
        <!-- 3引用子组件 -->
        <login v-if="flag"></login>
        <register v-else="flag"></register>
    </div>


    <template id="loginTempl">
        <div>
            <h2>登录组件</h2>
        </div>
    </template>

    <template id="registerTempl">
        <div>
            <h2>注册组件</h2>
        </div>
    </template>


    <script>
        //1.定义组件对象
        let login = {
            template: "#loginTempl", //模板
        };

        let register = {
            template: '#registerTempl'
        };

        // 创建Vue实例对象 
        var vm = new Vue({ //根组件
            el: '#app',
            data:{
                flag:true
            },
            components: {
                //注册局部子组件
                login,
                register
            }
        });
    </script>
</body>
</html>

示例2: 使用:is属性切换不同的子组件

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
    <!--组件切换时的过渡动画效果-->
    <style>
        .v-enter,
        .v-leave-to {
          opacity: 0;
          transform: translateX(30px);
        }
    
        .v-enter-active,
        .v-leave-active {
          position: absolute;
          transition: all 0.3s ease;
        }
      </style>
</head>

<body>
    <div id="app">
        <h1>我是父组件!</h1>
        <hr>
        <a href="#" @click.prevent="comName='login'">登录</a>
        &nbsp;|&nbsp;
        <a href="#" @click.prevent="comName='register'">注册</a>
        <hr>
        <transition mode="out-in">
            <!-- component显示指定名称的组件 -->
            <component :is="comName"></component>
        </transition>
    </div>


    <template id="loginTempl">
        <div>
            <h2>登录组件</h2>
        </div>
    </template>

    <template id="registerTempl">
        <div>
            <h2>注册组件</h2>
        </div>
    </template>


    <script>
        //1.定义组件对象
        let login = {
            template: "#loginTempl", //模板
        };

        let register = {
            template: '#registerTempl'
        };

        // 创建Vue实例对象 
        var vm = new Vue({ //根组件
            el: '#app',
            data:{
               comName:''  //指定组件名
            },
            components: {
                //注册局部子组件
                login,
                register
            }
        });
    </script>
</body>
</html>

2-5 组件间数据传递

  • 父组件向子组件传值

    • 1.在引用子组件时,使用一个动态属性 xx[名称随意],将父组件中的消息传给子组件

    • 2.在子组件,通过一个props属性接收动态属性传来的值

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
</head>
<body>
    <div id="app">
        <h1>我是父组件</h1>

        <!--
         父组件需要向子组件传值:
            1.在引用子组件时,使用一个动态属性 xx[名称随意],将父组件中的消息传给子组件
            2.在子组件,通过一个props属性接收动态属性传来的值
        -->
        <son :xx="msg"></son>
    </div>

    <template id="sonTempl">
        <h2>我是子组件,接收到父组件的消息: <span style='color:red'>{{xx}}</span></h2>
    </template>
    
    
    <script>
         //定义子组件对象
         let son = {
             template:'#sonTempl',
             data(){
                return {
                   
                }
             },
             props:['xx']   //使用props接收父组件传来的动态属性值
         }


        // 创建Vue实例对象 
        var vm = new Vue({
           el:'#app', 
           data:{  
                msg:'Hello,我是来自父组件的消息'  
           },
           methods:{
           },
           components:{  //注册子组件
                son
           }
        });
   </script>
</body>
</html>
  • 子组件向父组件传值

    • 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去

      a.通过引用子组件时,将父组件方法getMsg的引用传给子组件 @方法名="父组件方法名" b.子组件在内部调用父组件传来的方法:  this.$emit('方法名', 要传递的数据) 方式

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
</head>

<body>
    <div id="app">
        <h1>我是父组件,接收到子组件传来的消息:<span style="color:red;">{{msg}}</span></h1>

        <!--
         子组件需要向父组件传值:
            原理:父组件将方法的引用,传递到子组件内部,
            子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去

            1.通过引用子组件时,将父组件方法getMsg的引用传给子组件 @方法名="父组件方法名"
            2.子组件在内部调用父组件传来的方法:  this.$emit('方法名', 要传递的数据) 方式
        -->
        <son @func="getMsg"></son>
    </div>

    <template id="sonTempl">
        <div>
            <h2>我是子组件</h2>
            <input type="button" value="发送" @click="sendMsg"/>
        </div>
    </template>


    <script>
        //定义子组件对象
        let son = {
            template: '#sonTempl',
            data() {
                return {
                    msg: 'Hello,我是来自子组件的消息'
                }
            },
            methods:{
                sendMsg(){ //发送消息到父组件
                    //通过this.$emit() 调用父组件的方法,同时将子组件中的消息传递
                    this.$emit('func',this.msg);   //此时 this.msg作为func指向方法的参数 
                }
            }
        }


        // 创建Vue实例对象 
        var vm = new Vue({
            el: '#app',
            data: {
                msg:''
            },
            methods: {
                getMsg(msg) { //用于接收子组件传来的消息
                    this.msg = msg;
                }
            },
            components: { //注册子组件
                son
            }
        });
    </script>
</body>
</html>

2-6 使用$refs获取元素和组件

 通过元素或组件标识ref属性,再使用this.$refs. xxx获取元素或组件

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
</head>
<body>
    <div id="app">
        <input type="button" value="获取元素内容" @click="getElement" />
        <!-- 使用 ref 获取元素 -->
        <h1 ref="myh1" id="myh1">这是一个大大的H1</h1>

        <!-- 使用 ref获取组件 -->
        <login ref="myLogin" id="myLogin"></login>
    </div>
    
   
     <script>
        //全局注册
        Vue.component('login',{
            template:'<h2>我是login组件</h2>',
            data(){
                return {
                    msg:'Hello'
                }
            }
        });


        // 创建Vue实例对象 
        var vm = new Vue({
           el:'#app', 
           data:{     
            
           },
           methods:{
                getElement(){
                    let objH1 = document.getElementById("myh1");
                    console.log(objH1.innerText);
                    let refH1 = this.$refs.myh1;
                    console.log(refH1.innerText);
                    //console.log(h1.innerText);
                    console.log("-------------------------------------------");
                    let objLogin = document.getElementById('myLogin'); 
                    console.log(objLogin.msg); //undefined
                    let comLogin = this.$refs.myLogin; //获取由ref属性标识的组件或元素
                    console.log(comLogin);
                    console.log("访问获取的组件对象的属性:"+comLogin.msg);
                }
           }
        });
   </script>
</body>
</html>

3.路由

3-1 路由简介

路由的作用: 就是控制组件的显示

什么是路由:

Vue路由是指根据url分配到对应的处理程序;作用就是解析URL,调用对应的控制器(的方法,并传递参数)。

Vue路由有助于在浏览器的URL或历史记录与Vue组件之间建立链接,从而允许某些路径渲染与之关联的任何一个视图。

3-2 在vue中使用vue-router

实现 :

image-20220701170043211

首先加载路由js库

 <!-- 引入router库 -->
<script src="js/vue-router-3.0.1.js"></script>

示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
    <!-- 引入router库 -->
    <script src="js/vue-router-3.0.1.js"></script>
</head>
<body>
    <div id="app">
        <!-- 
            1.路由入口
             router-link

            2.创建路由-配置路由
                |-路由属性配置
                var router = new VueRouter({
                    //配置路由规则
                })

            3.注册路由 -将当前路由对象与 Vue实例关联
               router:路由对象名

            4.路由出口 router-view
         -->
         <!-- <a href="#/login">登录</a> 
           step1: 路由入口
         -->
        <router-link to="/login">登录</router-link>  
         &nbsp;|&nbsp;
        <router-link to="/register">注册</router-link>
        <hr>

        <!--step4: 指定路由出口 -->
        <router-view></router-view>
    </div>
    
   
     <script>

        //创建组件对象
        let login = {
            template:'<h2>登录组件</h2>'
        };

        let register = {
            template:'<h2>注册组件</h2>'
        };

     
        //step2.创建路由对象-配置路由
        var router = new VueRouter({
            //配置路由规则
            routes:[
                {path:'/login',component:login},
                {path:'/register',component:register}
            ]
        });


        // 创建Vue实例对象 
        var vm = new Vue({
           el:'#app', 
           data:{     
            
           },
           methods:{
           },
           //router:router  //当路由对象名与router属性名相同时,可以省略
           router  //step3: 注册路由
        });
   </script>
</body>
</html>

3-3 路由的高亮

针对于使用<router-link to="/login">登录</router-link>标签时,激活时的链接样式选择器:router-link-active指定高亮

  <style>
        /* .router-link-active {  //默认的类名
            font-size:20px;
            color:red;
            background-color: yellow;
        } */

        .myLinkActive {
            font-size:20px;
            color:red;
            background-color: yellow;
        }
    </style>


     //step2.创建路由对象-配置路由
        var router = new VueRouter({
            //配置路由规则
            routes:[
                {path:'/login',component:login},
                {path:'/register',component:register}
            ],
            linkActiveClass: 'myLinkActive'  // 注册链接激活的样式
        });

3-4 路由的嵌套

image-20220701171046534

示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
    <!-- 引入router库 -->
    <script src="js/vue-router-3.0.1.js"></script>
    <style>
        /* .router-link-active {
            font-size:20px;
            color:red;
            background-color: yellow;
        } */

        .myLinkActive {
            font-size:20px;
            color:red;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 
            1.路由入口
             router-link

            2.创建路由-配置路由
                |-路由属性配置
                var router = new VueRouter({
                    //配置路由规则
                })

            3.注册路由 -将当前路由对象与 Vue实例关联
               router:路由对象名

            4.路由出口 router-view
         -->
         <!-- 
           step1: 路由入口
         -->
        <h1>我是父组件</h1><hr>
        <router-link to="/account">进入Account组件</router-link>
        <!--指定路由出口 -->
        <router-view></router-view>
    </div>

    <!-- Account组件的模板 -->
    <template id="accountTempl">
        <div>
            <h2>Account组件</h2>
            <hr>
            <router-link to="/account/login">登录</router-link>  
                &nbsp;|&nbsp;
            <router-link to="/account/register">注册</router-link>
            <hr>
            <!-- 路由出口,用于显示当前account组件的子组件 -->
            <router-view></router-view>
        </div>

    </template>
    
   
     <script>
        //account组件对象
        let account = {
            template:'#accountTempl'
        };


        //创建组件对象
        let login = {
            template:'<h3>登录组件</h3>'
        };

        let register = {
            template:'<h3>注册组件</h3>'
        };
     
        //step2.创建路由对象-配置路由
        var router = new VueRouter({
            //配置路由规则
            routes:[
                {
                    path:'/account',
                    component:account,
                    children:[  //子组件   // 注意,子路由的开头位置,不要加 / 路径符
                        {path:'login',component:login},
                        {path:'register',component:register}
                    ]
                }
            ],
            linkActiveClass: 'myLinkActive'  // 注册链接激活的样式
        });


        // 创建Vue实例对象 
        var vm = new Vue({
           el:'#app', 
           data:{     
            
           },
           methods:{
           },
           //router:router  //当路由对象名与router属性名相同时,可以省略
           router  //step3: 注册路由
        });
   </script>
</body>
</html>

3-5 获取路由中的参数

  • 每当产生一个新的路由都会产生一个新的route对象 用于封装路由信息与参数等

    可以通过this.$route获取路由信息,与参数

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vuejs -->
    <script src="js/vue-2.6.12.js"></script>
    <!-- 引入router库 -->
    <script src="js/vue-router-3.0.1.js"></script>
</head>
<body>
    <div id="app">
        <router-link to="/login?id=1&name=jack">登录</router-link>  
         &nbsp;|&nbsp;
        <router-link to="/register/2/mike">注册</router-link>
        <hr>
        <!--路由出口 -->
        <router-view></router-view>
    </div>
    
    <template id="loginTemp">
        <div>
            <h2>登录组件 -  收到请求路径中的参数:{{id}} - {{name}} </h2>
        </div>
    </template>

    <template id="registerTemp">
        <div>
            <h2>注册组件 - 收到请求路径中的参数:{{id}} - {{name}} </h2>
        </div>
    </template>
   
     <script>

        //创建组件对象
        let login = {
            template:'#loginTemp',
            data(){
                return {
                    id:'',
                    name:''
                }
            },
            created(){
               console.log("login的 created()执行了....");
               console.log(this.$route);
               this.id= this.$route.query.id;
               this.name= this.$route.query.name;
            }
        };

        let register = {
            template:'#registerTemp',
            data(){
                return {
                    id:'',
                    name:''
                }
            },
            created(){
               console.log("register的 created()执行了....");
               console.log(this.$route);
               this.id= this.$route.params.id;
               this.name= this.$route.params.name;
            }
        };

     
        //step2.创建路由对象-配置路由
        var router = new VueRouter({
            //配置路由规则
            routes:[
                {name:'loginRouter',path:'/login',component:login},
                {name:'registerRouter',path:'/register/:id/:name',component:register}
            ]
        });


        // 创建Vue实例对象 
        var vm = new Vue({
           el:'#app', 
           data:{     
            
           },
           methods:{
           },
           //router:router  //当路由对象名与router属性名相同时,可以省略
           router 
        });
   </script>
</body>
</html>
;