• vue组件原生事件以及路由


    1.组件

    组件就是可以扩展HTML元素,封装可重用的HTML代码,可以将组件看作自定义的HTML元素

    1.1组件注册

    全局注册:

    组件注册时,需要给他一个名字,如下:

    Vue.component('my-component-name', { /* ... */ })

    # 组件名使用kebab-case (短横线分隔命名)定义时,引用这个元素时使用 <my-component-name>

    # 组件名使用 PascalCase (驼峰式命名) 定义时,引用这个元素时使用<my-component-name> 和 <MyComponentName>都可以

    局部注册:

    通过一个普通的 JavaScript 对象来定义组件

    var ComponentA = { /* ... */ }
    var ComponentB = { /* ... */ }

    然后在component选项中定义想要的组件

    new Vue({
      el: '#app'
      components: {
        'component-a': ComponentA,
        'component-b': ComponentB
      }
    })

    # 局部注册的组件在其子组件中不可用

    全局注册实例:

    组件的复用(主体代码):

    <body>
        <div id="app">
            <buttons></buttons>
            <buttons></buttons>
            <buttons></buttons>
        </div>
        <hr>
        <div id="app2">
            <buttons></buttons>
        </div>
    </body>
    <script>
        // 组件中data必须是一个函数,第一个参数是我们的定义标签
        Vue.component('buttons',{
            data:function(){
                return{
                    count:0
                }
            },
            template:`<button v-on:click='count++'>biubiubiu{{ count }}</button>`
        })
    
        var app = new Vue({
            el:"#app"
        })
    
        var app2 = new Vue({
            el:"#app2"
        })
    </script>

    效果:

    局部注册实例:

    (父组件往子组件传值)

    <body>
        <div id="app">
            <bts v-bind:name='fir'></bts>    
            <bts v-bind:name='sec'></bts>    
            <bts v-bind:name='thi'></bts>    
            <hr>
            <bts v-for='nums in list' v-bind:name='nums'></bts>
        </div>
    </body>
    <script>
        // 这里的buttons属于我们的自定义标签,通过props向子组件传递数据
        var myComponent = {
            template:`<button v-on:click="cli">{{name}}+{{count}}</button>`,
        // 使用props声明,组件需要外边从data给传一个字符串格式的name变量
            props:{
                name:String
            },    
            data:function(){
                return{
                    count:0,
                }
            },
            methods:{
                cli:function(){
                    this.count += 1
                }
            }
        }
    
        // 自定义局部组件
        new Vue({
            el:'#app',
            data:{
                list:[
                '1',
                '2',
                '3',
                ],
                fir:'first',
                sec:'second',
                thi:'third',
            },
            components:{
                bts:myComponent    
            }
        })
    </script>

    效果:

    1.2props

    官网链接

    2.组件组织:

    该图很好的表明了组件的组织关系对应图,或者说是层级关系

    Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,只要先在父级应用中写好各种组件标签,并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现,然后整个应用就算做完了

    3.组件中的数据传递(props)

    <body>
        <div id="app">
            <!-- 写死了 -->
            <buttons title="My journey with Vue"></buttons>
            <buttons title="Blogging with Vue"></buttons>        
        </div>
        <hr>
        <!-- 动态传递 -->
        <div id="app2">
            <buttons
            v-for="post in posts"
              v-bind:key="post.id"
              v-bind:title="post.title"
            ></buttons>
        </div>
    </body>
    <script>
        Vue.component('buttons', {
                  props: ['title'],
                  template: '<h3>{{ title }}</h3>'
        })
    
        var app = new Vue({
            el:"#app",
        })
    
        var app2 = new Vue({
            el:"#app2",
            // 动态传递一个数组
            data: {
            posts: [
                  { id: 1, title: 'My journey with Vue' },
                  { id: 2, title: 'Blogging with Vue' },
                ]
          }
        })
    </script>

     子组件往父组件传值:

    <body>
        <div id="app">
            <p>总数:{{total}}</p>
            <bts v-for='nums in list' v-bind:name='nums' v-on:zhi="add"></bts>
        </div>
    </body>
    <script>
        // 这里的bts属于我们的自定义标签,通过props向子组件传递数据
        var myComponent = {
            template:`
            <div>
            <button v-on:click="cli">{{count}}{{name}}</button>       
            </div>
            `,
        // 使用props声明,组件需要外边从data给传一个字符串格式的name变量
            props:{
                name:String
            },    
            data:function(){
                return{
                    count:0,
                }
            },
            methods:{
                cli:function(){
                    this.count += 1;
                // 在组件中通过触发自定义事件向外传递信息
                this.$emit('zhi')
                }
            }
        }
    
        // 自定义局部组件
        new Vue({
            el:'#app',
            data:{
                total:0,
                list:[
                '只猪','只狗','只兔子',
                ]    
            },
            components:{
                bts:myComponent    
            },
            methods:{
                add:function(){
                    this.total += 1
                }
            }
        })
    </script>

    效果:

    组件间传值(生成一个空vue对象bus):

    各个组件内部要传输的数据或者要执行的命令信息,靠bus来通信。

    <body>
    <div id="app">
        <bt></bt>
        <hr>
        <nums></nums>
    </div>
    
    </body>
    <script>
        var bus = new Vue();
        var app = new Vue({
            el:'#app',
            data:{
                name:'bt'
            },
            components:{
                bt:{
                    template:`<button v-on:click='check'>点我</button>`,
                    methods:{
                check(){
                    bus.$emit('things')
                }
            }
        },
            nums:{
                template:`<div>{{num}}</div>`,
                data:function(){
                    return {
                        num: 0
                    }
                    
                },
                mounted:function(){
                    // 该组件中this指num实例
                    var _this = this;
                    console.log(_this);
                    // 监听bus
                    bus.$on('things', function(){
                            // 在这个作用域中 this 指的是 bus
                            console.log(this.num)  // undefined
                            // 修改num组件中的num值
                            // 此时this是谁?
                            // this.num += 1;  // 有问题
                            _this.num += 1;
                        })
                    }
    
                }
            }
            
        })
    </script>

    在第一个组件中的methods方法里,通过bus.$emit()方法发射事务

    在第二个组件实例化的钩子中(mounted)中,通过bus.$on监听自家$emit触发的事件

    4.插槽:(使用自定义标签<slot>元素达到目的的)

    官网链接

    插槽是占位置的!!!
    插槽多了可以起名字,进行区分! --> <span slot='heihei'>嘿嘿!</span>

    <body>
        <div id="app">
            <alert-box>
                Something bad happened.
            </alert-box>
        </div>
    </body>
    <script>
        Vue.component('alert-box', {
            template: `
            <div class="demo-alert-box">
            <strong>Error!</strong>
            <slot></slot>
            </div>
            `
        })
        new Vue({
            el:"#app"
        })    
    </script>

    效果:

    5.将原生事件绑定到组件(.naive修饰符)

      如果想在一个组件的根元素上直接监听一个原生事件,这时候就可以使用v-on的.naive修饰符

    实例0(不推荐使用):

    <body>
    <div id="app">
        <ztzsb v-on:click='hehe'></ztzsb>
    </div>
    </body>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                name: 'ztz',
                age: 24
            },
            components: {
                ztzsb: {
                    template: `<button v-on:click='shangkele'>赵天柱 逃课!</button>`,
                    methods:{
                        shangkele:function(){
                            this.$emit('click')
                        }
                    }
                }
            },
            methods:{
                hehe:function(){
                    alert(123);
                }
            }
        })
    </script>
    </html>

    实例1:

    <body>
        <div id="app">
            <ztz v-on:click.native='hehe'></ztz>
        </div>
    </body>
    <script>
        var app = new Vue({
            el:"#app",
            data:{},
    
            components:{
                ztz:{
                    template:`<button>赵天柱 逃课!</button>`
                },
            },
            methods:{
                hehe:function(){
                    alert(123);
                }
            }
        })
    </script>
    </html>

    再看看下面的实例2:

    <body>
        <div id="app">
            <ztz></ztz>
        </div>
    </body>
    <script>
        var app = new Vue({
            el:"#app",
            data:{},
            components:{
                ztz:{
                    template:`<button v-on:click='hehe'>赵天柱 逃课!</button>`,
                    methods:{
                        hehe(){
                            alert(123);
                        }
                    }
                },    
            }
        })
    </script>

    ## 实例1和2两者效果一模一样,一个是在根元素上进行事件绑定,一个是在局部组件上进行绑定  

    6.总结

    1. Vue组件
    0. 组件注意事项!!!
    	data属性必须是一个函数!
    
    1. 注册全局组件
    	Vue.component('组件名',{
    		template: ``
    	})
    	
    	var app = new Vue({
    		el: '#app'
    	})
    2. 注册局部组件
    	var app = new Vue({
    		el: '#app',
    		components:{
    			局部组件名:{
    				template: `...`
    			}
    		}
    	})
    3. 传值
    	1. 父组件 --> 子组件
    		1. 父组件通过 v-bind:变量='值'
    		2. 子组件需要通过props 声明我需要的变量
    	2. 子组件 --> 父组件
    		子组件通过触发自定义事件的方式向外传递信息
    		1. 子组件: this.$emit('自定义事件')
    		2. 父组件: v-on:自定义事件='方法名'
    		
    	3. 组件间传值
    		1. 补充:Vue实例的生命周期钩子函数(共8个)
    			1. beforeCreate    --> 数据属性声明但没有赋值
    			2. created         --> 数据属性赋值
    			3. beforeMount     --> 页面上的 {{name}} 还没有被渲染
    			4. mounted         --> 页面上的 {{name}} 被替换成真正的内容
    			...
    			
    		2. 基于bus对象实现
    	
    4. 插槽(slot)
    	插槽是占位置的!!!
    	插槽多了可以起名字,进行区分!   --> <span slot='heihei'>嘿嘿!</span>
    	<alert>根本不显示</alert>
    	
    		
    5. 组件的注意事项:
    	1. 特殊的组件需要使用is语法声明一下 比如 table、select、ul等内部使用的组件
    	2. 捕获子组件的原生事件

    7.Vue.Router

      Vue Router 是 Vue.js 官方的路由管理器

      将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们,实现异步ajax界面切换效果(页面不刷新)

    # 例,注意vue-router.js的引入方式

    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <body>
    	<div id="app">
    		<!-- 路由入口 -->
    		<router-link to='/index'>index页面</router-link>	
    		<router-link to='/home'>home页面</router-link>
    		<hr>
    		<!-- 路由出口 -->
    		<router-view></router-view>	
    	</div>
    </body>
    	<script>
    		// 路由,数组包含两个路由
    		const routess = [
    		{path:'/index',component:{template:`<div><h2>index页面</h2></div>`}},
    		{path:'/home',component:{template:`<div><h2>home页面</h2></div>`}},
    		]
    		// 生成实例,routes是关键字,它的值必须是一个数组
    		const routerObj = new VueRouter({
    			routes:routess
    		})
    
    		new Vue({
    			el:'#app',
    			// 路由实例挂载到vue实例中,router是关键字
    			router:routerObj
    		})
    	</script>  
    </body>
    </html>

     效果:

    7.1路由动态匹配 

    我们有一个 User 组件,对于 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个目的

    一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,如下

     

    实例:

    <body>
    <div id="app">
        <!--路由的入口-->
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/user/index">index页面</router-link>
        <router-link to="/user/home">home页面</router-link>
        <hr>
        <p>666</p>
        <!--路由的出口-->
        <!-- 路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
        <p>999</p>
    </div>
    <script>
        //写路由
        const routeArray = [
            { path: '/user/:name',
                component: {template: `<h3>这是{{$route.params.name}}的主页页面!</h3>`}
            }
        ]
        //生成路由实例
        const routerObj = new VueRouter({
            routes: routeArray
        })
        var app = new Vue({
            el:'#app',
            //router是关键字,它的值必须是数组
            router:routerObj  //将路由实例挂载到vue实例中
        })
    </script> 

      效果:

    7.2嵌套路由(子路由)

     URL 中各段动态路径按某种结构对应嵌套的各层组件,如下:

      

    实例(关键点在于使用append拼接路由):

    <div id="app">
        <router-link to="/user/index">index</router-link>
        <router-link to="/user/home">home</router-link>
        <hr>
        <router-view></router-view>
    </div>
    <script>
    	// 生成路由数组
        const routeArray = [
            {
                path: '/user/:name',
                component: {
                    //append表示当前路由拼接url,比如/user/home/info
                    //router-view对应子路由的template的内容
                    template: `<div>
                        <h3>这是{{$route.params.name}}的主页页面!</h3>
                        <hr>
                        <router-link to='info' append>用户详细信息</router-link>
                        <router-view></router-view>
                    </div>`
                },
                // 定义子路由
                children:[
                    {
                        path: 'info',
                        component:{
                            template: `
                                <div>
                                    <h1>大傻逼</h1>
                                </div>
                            `
                        }
                    },
                ]
            }
        ]
        //生成VueRouter实例
        const routerObj = new VueRouter({
            //routes是关键字参数,它必须对应一个数组
            routes: routeArray
        })
        var app = new Vue({
            el:'#app',
            data:{},
            //router是关键字,它的值必须是数组
            router:routerObj  //将路由实例挂载到vue实例中
        })
    </script>

    效果:

    总结:

    1. Vue全家桶
    	Vue + VueRouter + VueX
    2. VueRouter  https://router.vuejs.org/zh/
    	1. 基本使用
    		1. 必须导入vue-router.js文件
    		2. 要有VueRouter()实例
    		3. 要把VueRouter实例挂载到Vue实例中
    		
    		4. 路由的入口
    			<router-link to='/index'>index页面</router-link>
    		5. 路由的出口
    			<router-view></router-view>
    	2. 路由的参数
    		1. path: '/user/:name' --> 匹配路由
    		$route.params.name     --> 取值
    		
    		2. /user/alex?age=9000 --> url中携带参数
    		$route.query.age       --> 取出url的参数
    		
    	3. 子路由
    		children:[
    			{
    				path: '',
    				component: {
    					template: `...`
    				}
    			}
    		]
    		
    		<router-link to='info' append></router-link>
    

      

  • 相关阅读:
    python基本数据类型及其使用方法
    爬虫基础
    HTML标签marquee实现滚动效果
    Python学习之路_day_32(基于tcp协议的套接字/粘包问题)
    Python学习之路_day_31(tcp协议/socket)
    Python学习之路_day_30(单例模式,网络编程)
    Python学习之路_day_29(异常处理,元类)
    Python学习之路_day_25(面向对象之封装/多态/组合)
    Python学习之路_day_24(面向对象之继承)
    Python学习之路_day_23(面向对象)
  • 原文地址:https://www.cnblogs.com/LearningOnline/p/9367717.html
Copyright © 2020-2023  润新知