• vue学习-day04(路由)


    目录

        1.组件传值-父组件向子组件传值和data与props的区别
        2.组件传值-子组件通过事件调用向父组件传值        
        3.案例:发表评论。使用ref获取DOM元素和组件引用
        4.路由-前端路由和后端路由的概念
        5.路由-vue-router的基本使用
        6.路由-路由redirect重定向的使用
        7.路由-设置选中路由高亮的两种方式
        8.路由-为路由切换启动动画
        9.路由传参-使用query方式传递参数
        10.路由传参-使用params方式传递路由参数
        11.路由-使用children属性实现路由嵌套
        12.路由-使用命名视图实现经典布局

    1.组件传值-父组件向子组件传值和data与props的区别    <--返回目录

      父组件向子组件传值

    <!DOCTYPE html>
    <html>
    <head>
        <title>标题</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue的包 -->
        <script type="text/javascript" src="vue2.js"></script>
        <style type="text/css">
            div {
                background-color: #ccc;
            }
            /*自定义样式,来控制元素动画样式*/
            .my-enter, .my-leave-to {
                opacity: 0;
                transform:translateX(150px);
            }
            .my-enter-active,  /*入场动画的时间段*/
            .my-leave-active {  /*离场动画的时间段*/
                transition: all 0.4s ease;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <a href="" @click.prevent="comName='com1'">组件1</a>
            <a href="" @click.prevent="comName='com2'">组件2</a>
            <!-- 通过mode属性,设置组件切换时的模式,out-in表示上一个组件离场动画后,新组件才开始入场动画-->
            <transition name="my" mode="out-in">
                <!-- 父组件,可以在引用子组件的时候,通过属性绑定的形式,传递数据
                注意:定义属性名称全部小写 -->
                <!-- [Vue tip]: Prop "parentmsg" is passed to component <Anonymous>, 
                but the declared prop name is "parentMsg". Note that HTML attributes 
                are case-insensitive and camelCased props need to use their kebab-case 
                equivalents when using in-DOM templates. You should probably use 
                "parent-msg" instead of "parentMsg". -->
                <component :is="comName" :parentmsg="msg" @parentshow="show"></component>
            </transition>
        </div>
    
        <script type="text/javascript">  
            //创建一个vue实例
            var vm = new Vue({
                el: '#app',
                data: {
                    comName: 'com1',
                    msg: "父组件的msg"
                },
                methods: {
                    show() {
                        console.log("调用了父组件的show方法");
                    }
                },
                components: {
                    com1: {
                        template: '<h1 @click="mymethod">这是子组件1----{{parentmsg}}</h1>',
                        //把父组件传递过来的parentMsg属性,在props数组中定义,这样才能使用该属性
                        props: ['parentmsg'],
                        methods: {
                            mymethod() {
                                this.$emit('parentshow');
                            }
                        }
                    },
                    com2: {
                        template: '<h1>这是子组件2</h1>'
                    }
                }    
            });
        </script>
    </body>
    </html>

      data与props的区别:

        1)子组件中所有props中的数据,都是通过父组件传递给子组件的。数据只是可读
        2)子组件data中的数据是自身私有的,数据可读可写


    2.组件传值-子组件通过事件调用向父组件传值    <--返回目录

    <!DOCTYPE html>
    <html>
    <head>
        <title>标题</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue的包 -->
        <script type="text/javascript" src="vue2.js"></script>
        <style type="text/css">
            div {
                background-color: #ccc;
            }
            /*自定义样式,来控制元素动画样式*/
            .my-enter, .my-leave-to {
                opacity: 0;
                transform:translateX(150px);
            }
            .my-enter-active,  /*入场动画的时间段*/
            .my-leave-active {  /*离场动画的时间段*/
                transition: all 0.4s ease;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <a href="" @click.prevent="comName='com1'">组件1</a>
            <a href="" @click.prevent="comName='com2'">组件2</a>
            <!-- 通过mode属性,设置组件切换时的模式,out-in表示上一个组件离场动画后,新组件才开始入场动画-->
            <transition name="my" mode="out-in">
                <!-- 父组件,可以在引用子组件的时候,通过属性绑定的形式,传递数据
                注意:定义属性名称全部小写 -->
                <!-- [Vue tip]: Prop "parentmsg" is passed to component <Anonymous>, 
                but the declared prop name is "parentMsg". Note that HTML attributes 
                are case-insensitive and camelCased props need to use their kebab-case 
                equivalents when using in-DOM templates. You should probably use "parent-msg" instead of "parentMsg". -->
                <component :is="comName" :parentmsg="msg" @parentshow="show"></component>
            </transition>
            <br/>
            <h1>{{msg}}</h1>
        </div>
    
        <script type="text/javascript">  
            //创建一个vue实例
            var vm = new Vue({
                el: '#app',
                data: {
                    comName: 'com1',
                    msg: "父组件的msg"
                },
                methods: {
                    show(data) {
                        console.log("调用了父组件的show方法---" + data );
                        this.msg = data;
                    }
                },
                components: {
                    com1: {
                        template: '<h1 @click="mymethod">这是子组件1----{{parentmsg}}</h1>',
                        data: function(){
                            return {
                                sonmsg: '子组件的msg'
                            }
                        },
                        //把父组件传递过来的parentMsg属性,在props数组中定义,这样才能使用该属性
                        props: ['parentmsg'],
                        methods: {
                            mymethod() {
                                this.$emit('parentshow', this.sonmsg);//调用父组件传递过来的方法
                            }
                        }
                    },
                    com2: {
                        template: '<h1>这是子组件2</h1>'
                    }
                }    
            });
        </script>
    </body>
    </html>


    3.案例:发表评论。使用ref获取DOM元素和组件引用    <--返回目录

      案例:添加评论部分是子组件;父组件对所有评论进行列表展示。评论保存在本地存储localStorage

    <!DOCTYPE html>
    <html>
    <head>
        <title>标题</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue的包 -->
        <script type="text/javascript" src="vue2.js"></script>
    <link rel="stylesheet" type="text/css" href="bootstrap.min.css"> </head> <body> <div id="app"> <com1></com1> <div class="container"> <ul class="list-group"> <li class="list-group-item" v-for="item in list" :key="item.id"> <span class="badge">{{item.user}}</span> {{item.comments}} </li> </ul> </div> </div> <template id="temp1"> <div class="container"> <div class="row"> <div class="col-md-3"></div> <div class="col-md-6"> <form> <div class="form-group"> <label for="user">用户名</label> <input type="text" name="user" placeholder="输入用户名" class="form-control" v-model="user"> </div> <div class="form-group"> <label for="comments">评论</label> <input type="text" name="comments" placeholder="输入评论" class="form-control" v-model="comments"> </div> <button class="btn btn-primary" @click="postCommets">发表评论</button> </form> </div><!-- /.col-md-6 --> </div><!-- /.row --> </div><!-- /.container --> </template> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { list: [] }, methods: { loadComments() { var list = JSON.parse(localStorage.getItem("cmts") || '[]'); this.list = list; } }, created() { this.loadComments(); }, components: { com1: { template: '#temp1', data(){ return { user: '', comments: '' } }, methods: { postCommets() { var obj = {id:Date.now(), user: this.user, comments: this.comments}; var list = JSON.parse(localStorage.getItem("cmts") || '[]'); list.unshift(obj); localStorage.setItem("cmts", JSON.stringify(list)); this.user = ''; this.comments = ''; } } } } }); </script> </body> </html>

      

      // 问题1:我这个案例里面不需要将父组件的loadComments()方法传递给子组件;点击发表按钮后,评论列表自动更新。
      // 问题2:我没有手动给输入框注册enter键盘事件,但是也有这个功能,猜测是bootstrap本身自带的。

      使用ref获取DOM元素和组件引用

    // vue获取dom元素
    <!DOCTYPE html>
    <html>
    <head>
        <title>vue获取dom元素</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue的包 -->
        <script type="text/javascript" src="vue2.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="button" value="获取h3标签里面的文本" @click="getEle">
            <h3 ref="h3Ele">这是一个h3标签</h3>
        </div>
    
        <script type="text/javascript">  
            //创建一个vue实例
            var vm = new Vue({
                el: '#app',
                data: {
                },
                methods: {
                    getEle() {
                        // this.$refs.h3Ele:得到一个原生DOM对象
                        alert(this.$refs.h3Ele.innerText);
                    }
                }
            });
        </script>
    </body>
    </html>
    
    // vue获取子组件
    <!DOCTYPE html>
    <html>
    <head>
        <title>vue获取dom元素</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue的包 -->
        <script type="text/javascript" src="vue2.js"></script>
        <!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
    </head>
    <body>
        <div id="app">
            <input type="button" value="获取h3标签里面的文本" @click="getEle">
            <com1 ref="com1ref"></com1>
        </div>
    
        <script type="text/javascript">  
            //创建一个vue实例
            var vm = new Vue({
                el: '#app',
                data: {
                },
                methods: {
                    getEle() {
                        console.log(this.$refs.com1ref.sonmsg);
                        this.$refs.com1ref.show();
                    }
                },
                components: {
                    com1: {
                        template: '<div></div>',
                        data() {
                            return {
                                sonmsg: '子组件的msg'
                            }
                        },
                        methods: {
                            show() {
                                console.log("调用子组件的show方法:" + this.sonmsg);
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>


    4.路由-前端路由和后端路由的概念    <--返回目录

        * 后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上的资源
        * 前端路由:对应单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,
          同时,hash有一个特点:HTTP请求中不会包含hash相关的内容。所以,单页面程序中页面跳转主要用hash实现
        * 在单页面应用程序中,这种通过hash改变类切换页面的方式,称做前端路由
        * 路由:在URL中采用#号来作为当前视图的地址,改变#号后的参数,页面并不会重载。
        * 单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,
          是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。


    5.路由-vue-router的基本使用    <--返回目录

    <!DOCTYPE html>
    <html>
    <head>
        <title>vue获取dom元素</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue.js -->
        <script type="text/javascript" src="vue2.js"></script>
        <!-- 安装 vue-router 路由模块 -->
        <script type="text/javascript" src="vue-router.js"></script>
    </head>
    <body>
        <div id="app">
            <h1>Hello App!</h1>
            <p>
            <!-- 使用 router-link 组件来导航. -->
            <!-- 通过传入 `to` 属性指定链接. -->
            <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
            <router-link to="/login">Go to login</router-link>
            <router-link to="/register">Go to register</router-link>
            <!-- 下面的方式也可以,但是不推荐注意使用 -->
            <a href="#/login">登录</a>
            <a href="#/register">注册</a>
            </p>
            <!-- 路由出口 -->
            <!-- 路由匹配到的组件将渲染在这里 -->
            <router-view></router-view>
        </div>
    
        <script type="text/javascript"> 
            // 组件的模板对象
            var login = {
                template: '<h1>登录组件</h1>'
            };
            var register = {
                template: '<h1>注册组件</h1>'
            };
    
            // 创建一个路由对象
            var routerObj = new VueRouter({
                routes: [  // 路由匹配规则
                    {path: '/login', component: login},
                    {path: '/register', component: register}
                ]
            });
    
            // 创建一个vue实例
            var vm = new Vue({
                el: '#app',
                data: {      
                },
                methods: { 
                },
                //将路由规则对象,注册到vm实例上,用来监听URL地址的变化,然后展示对应的组件
                router: routerObj  
            });
        </script>
    </body>
    </html>    


    6.路由-路由redirect重定向的使用    <--返回目录

    routes: [  // 路由匹配规则
                {path: '/', redirect: '/login'},
                {path: '/login', component: login},
                {path: '/register', component: register}
            ]


    7.路由-设置选中路由高亮的两种方式    <--返回目录

      // 第一种方式

    <style type="text/css">
        .router-link-active { // vue-router默认的
            color: red;
            background-color: #ccc;
        }
    </style>

      // 设置链接激活时使用的CSS类名。默认值可以通过路由的构造选项linkActiveClass来全局配置。

    var routerObj = new VueRouter({
        routes: [  // 路由匹配规则
            {path: '/', redirect: '/login'},
            {path: '/login', component: login},
            {path: '/register', component: register}
        ],
        linkActiveClass: 'myActive'
    });
    
    /*修改链接激活使用的CSS类名:myActive*/
    .myActive {
        color: #fff;
        background-color: #ff3300;
    }


    8.路由-为路由切换启动动画    <--返回目录

    /*自定义样式,来控制元素动画样式*/
    .my-enter, .my-leave-to {
        opacity: 0;
        transform:translateX(150px);
    }
    .my-enter-active,  /*入场动画的时间段*/
    .my-leave-active {  /*离场动画的时间段*/
        transition: all 0.4s ease;
    }
    
    <!-- 路由匹配到的组件将渲染在这里 -->
    <transition mode="out-in" name="my">
        <router-view></router-view>
    </transition>    


    9.路由传参-使用query方式传递参数    <--返回目录

    <router-link to="/login?id=10">Go to login</router-link>
    
    var login = {
        template: '<h1>登录组件---{{$route.query.id}}</h1>'
    };


    10.路由传参-使用params方式传递路由参数    <--返回目录

    <router-link to="/register/20">Go to register</router-link>
    
    var register = {
        template: '<h1>注册组件---{{$route.params.id}}</h1>'
    };
    
    // 创建一个路由对象
    var routerObj = new VueRouter({
        routes: [  // 路由匹配规则
            {path: '/', redirect: '/login'},
            {path: '/login', component: login},
            {path: '/register/:id', component: register}
        ],
        linkActiveClass: 'myActive'
    });


    11.路由-使用children属性实现路由嵌套    <--返回目录

    <!DOCTYPE html>
    <html>
    <head>
        <title>使用children属性实现路由嵌套</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue.js -->
        <script type="text/javascript" src="vue2.js"></script>
        <!-- 安装 vue-router 路由模块 -->
        <script type="text/javascript" src="vue-router.js"></script>
        <style type="text/css">
            /*链接激活默认使用的CSS类名:router-link-active*/
            .router-link-active {
                color: red;
                background-color: #ccc;
            }
            /*修改链接激活使用的CSS类名:myActive*/
            .myActive {
                color: #fff;
                background-color: #ff3300;
            }
            /*自定义样式,来控制元素动画样式*/
            .my-enter, .my-leave-to {
                opacity: 0;
                transform:translateX(150px);
            }
            .my-enter-active,  /*入场动画的时间段*/
            .my-leave-active {  /*离场动画的时间段*/
                transition: all 0.4s ease;
            }
    
            .parent {
                border:1px dashed #000;
                width: 300px;
                height: 500px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <h1>Hello App!</h1>
            <p>
            <!-- 使用 router-link 组件来导航. -->
            <!-- 通过传入 `to` 属性指定链接. -->
            <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
            <router-link to="/account">go to account</router-link>
            </p>
            
            <!-- 路由出口,路由匹配到的组件将渲染在这里 -->
            <transition mode="out-in" name="my">
                <router-view class="parent"></router-view><!-- 给父组件留的坑 -->
            </transition>
        </div>
    
        <template id="temp">
            <div>
                <h2>account--父组件</h2>
                <router-link to="/account/login">登陆</router-link>
                <router-link to="/account/register">注册</router-link>
                <router-view></router-view><!-- 给子组件留的坑 -->
            </div>
        </template>
    
        <script type="text/javascript"> 
            // 组件的模板对象
            var account = {
                template: '#temp'
            };
            var login = {
                template: '<h1>login组件</h1>'
            };
            var register = {
                template: '<h1>register组件</h1>'
            };
    
            // 创建一个路由对象
            var routerObj = new VueRouter({
                routes: [  // 路由匹配规则
                    //{path: '/', redirect: '/account'},
                    {path: '/account', component: account, children: [
                        {path: 'login', component: login},
                        {path: 'register', component: register}
                    ]}
                ],
                linkActiveClass: 'myActive',        
            });
    
            // 创建一个vue实例
            var vm = new Vue({
                el: '#app',
                data: {    
                },
                methods: {
                },
                //将路由规则对象,注册到vm实例上,用来监听URL地址的变化,然后展示对应的组件
                router: routerObj  
            });
        </script>
    </body>
    </html>


    12.路由-使用命名视图实现经典布局    <--返回目录

    <!DOCTYPE html>
    <html>
    <head>
        <title>使用命名视图实现经典布局</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <!-- 导入vue.js -->
        <script type="text/javascript" src="vue2.js"></script>
        <!-- 安装 vue-router 路由模块 -->
        <script type="text/javascript" src="vue-router.js"></script>
        <style type="text/css">
            .header {
                background-color: #abc;
                height: 80px;
            }
            .container {
                display: flex;
                height: 600px;
            }
            .left {
                flex: 2;
                background-color: #ccc;
            }
            .main {
                flex: 8;
                background-color: blue;
            }
            body {
                margin: 0;
                padding: 0;
            }
            h1 {
                margin: 0;
                padding: 0;
                font-size: 16px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <!-- 路由出口,路由匹配到的组件将渲染在这里 -->
            <router-view class="header"></router-view>
            <div class="container">
                <router-view name="left" class="left"></router-view>
                <router-view name="main" class="main"></router-view>
            </div>
        </div>
    
        <script type="text/javascript"> 
            // 组件的模板对象
            var header = {
                template: '<h1>header组件</h1>'
            };
            var left = {
                template: '<h1>left组件</h1>'
            };
            var main = {
                template: '<h1>main组件</h1>'
            };
    
            // 创建一个路由对象
            var routerObj = new VueRouter({
                routes: [  // 路由匹配规则
                    {path: '/', components: {
                        'default': header,
                        'left': left,
                        'main': main
                    }}
                ]        
            });
    
            // 创建一个vue实例
            var vm = new Vue({
                el: '#app',
                data: {    
                },
                methods: {
                },
                //将路由规则对象,注册到vm实例上,用来监听URL地址的变化,然后展示对应的组件
                router: routerObj  
            });
        </script>
    </body>
    </html>
  • 相关阅读:
    react中useContext实现父子组件传值
    react中异步action的使用
    react中redux原理图
    react中antd按需引入+自定义主题
    react中修改antd主题色?
    程序员哀叹工资低:二本计算机毕业,四年前端开发,年包才四十万!薪资真的和学历挂钩吗?
    C++学到什么程度可以面试找工作?
    一个风骚的C语言操作引起的轩然大波!
    如何比较两种截然不同的编程语言的性能!路人甲:这怎么比较?
    为啥码了十年代码,做到了高级工程师,但还是单身?
  • 原文地址:https://www.cnblogs.com/xy-ouyang/p/11192499.html
Copyright © 2020-2023  润新知