• Vue -组件


    组件的出现是为了拆分Vue实例的代码量,以不同的组件来划分不同的功能模块,需要什么功能直接调用对应组件即可

    组件化和模块化的区别:

    模块化是从代码逻辑的角度进行划分,方便代码分层开发,保证每个功能模块的职能单一

    组件化是从UI界面的角度进行划分,前端的组件化是为了方便UI组件的重用

     

    定义全局组件

    定义全局组件都是要用Vue.component来定义,只是模板创建上有些不同所以有三种方式

    方式1,模板的创建使用Vue.extend

    <body>
    <div id="app">
        <my-temp></my-temp>
    </div>
    <script>
        var template = Vue.extend({
            //通过template属性指定了组件要展示的html结构
            template:'<h3>Hello</h3>'
        })
    
        //Vue.component('组件名',创建出来的组件模板对象)
        Vue.component('myTemp',template)
    
        var vm = new Vue({
            el:'#app'
        })
    </script>
    </body>

    如果使用Vue.component定义全局组件时,组件名使用了驼峰命名,则在引用组件时大写的驼峰要改为小写,并且使用-连接,如果不使用驼峰,则直接使用

    组件的使用就是直接当作标签来用

    //Vue.component('组件名',创建出来的组件模板对象)
    Vue.component('myTemp',Vue.extend({
      template:'<h3>Hello</h3>'
    }))

     

    方式2,用一个对象代替Vue.extend

    不管是哪种方式创建的组件,template属性指向的模板内容,必须有且只有一个根元素

    //Vue.component('组件名',创建出来的组件模板对象)
    Vue.component('myTemp',{
      template:'<div><h3>Hello</h3><p>Hi</p></div>'
    })

     

    方式3,模板写在script标签内没有书写提示,可把模板抽出来放在template标签内(只能是放在template标签内),注意template标签要放在el控制的范围外

    <body>
    <div id="app">
        <my-temp></my-temp>
    </div>
    <template id="temp">
        <div>
            <h3>Hello</h3>
            <p>Hi</p>
        </div>
    </template>
    <script>
        //Vue.component('组件名',创建出来的组件模板对象)
        Vue.component('myTemp',{
            template:'#temp' //template元素的选择器
        })
        var vm = new Vue({
            el:'#app',
        })
    </script>
    </body>

     

    定义私有组件

    全局组件可以被所有的Vue实例使用,而私有组件在实例内部定义只能被该实例使用,套路和私有过滤器、私有指令一样,在构造函数里有个components属性 

    var vm = new Vue({
        el:'#app',
        components:{
            login:{
                template:'<h1>Hello~</h1>'
            }
        }
    })

     

    组件的data

    组件的data必须是一个方法,并且方法要返回一个对象,data定义后使用方式和实例的data一模一样

    Vue.component('myTemp',{
        template:'<h1>Hello,{{ msg }}</h1>',
        data:function () {
            return {
                msg:'这是组件data中的数据'
            }
        }
    })

     

    组件切换

    方式1,使用v-if和v-else,缺点是只能切换两个组件

    <body>
    <div id="app">
        <a href="#" @click.prevent="flag = true">登录</a>
        <a href="#" @click.prevent="flag = false">注册</a>
        <login v-if="flag"></login>
        <register v-else></register>
    </div>
    
    <script>
        Vue.component('login',{
            template:'<h3>登录界面</h3>'
        })
        Vue.component('register',{
            template:'<h3>注册界面</h3>'
        })
    
        var vm = new Vue({
            el: '#app',
            data:{
                flag:false
            }
        })
    </script>
    </body>

     

    方式2,使用Vue提供的component标签实现组件切换,component标签是个占位符,将:is属性设置为对应的组件名后,该组件会替换component标签

    <body>
    <div id="app">
        <a href="#" @click.prevent="comName='fruit'">水果</a>
        <a href="#" @click.prevent="comName='sock'">零食</a>
        <a href="#" @click.prevent="comName='cartoon'">漫画</a>
        <component :is="comName"></component><!--注意comName是个变量,不是字符串'comName'-->
    </div>
    
    <script>
        Vue.component('fruit',{
            template:'<h3>西瓜葡萄木菠萝</h3>'
        })
        Vue.component('sock',{
            template:'<h3>薯片辣条棒棒糖</h3>'
        })
        Vue.component('cartoon',{
            template:'<h3>火影死神海贼王</h3>'
        })
        var vm = new Vue({
            el: '#app',
            data:{
                comName:'fruit'
            }
        })
    </script>
    </body>

     

    实现组件切换的动画效果很简单,只需要把component用transition标签包起来即可,其他照旧

    mode为切换模式,out-in表示要等当前组件离开了,下一个组件才进入

     

    组件传值

    父组件向子组件传值,Vue实例对象可看成是一个组件,里面定义的私有组件是其子组件,子组件无法访问父组件data里的数据和methods里的方法

    这时候父组件可以在引用子组件时,通过属性绑定(v-bind)的形式,把数据传递到子组件内部

    <body>
    <div id="app">
        <son v-bind:parentmsg="msg"></son>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: '力量'
            },
            components: {
                son: {
                    template: '<div>请赐予我力量 {{ parentmsg }}</div>',
                    //把父组件的自定义属性在props数组中定义一下,才能使用这个数据
                    //props数组里的数据都是通过父组件传递来的
                    props: ['parentmsg']
                }
            }
        })
    </script>

    这里有个坑,parentmsg用驼峰写法的话会报错,所以可用parentmsg或parent-msg,不可用parentMsg

    子组件中的data数据是子组件私有的,子组件可以直接使用,props数据是父组件传递的,子组件通过ajax请求回来的数据都可放在自己的data身上

    另外data数据是可读可写的,props数据是只读

     

    若父组件要向子组件传递方法,麻烦,要用事件绑定机制,之后定义一个子组件自己的方法,在这方法内调用父组件传来的方法

    <body>
    <div id="app">
        <son @func="show"></son><!--事件绑定,把父组件方法传递给子组件-->
    </div>
    <template id="temp">
        <div>
            <input type="button" value="触发父组件传来的func方法" @click="myclick" >
        </div>
    </template>
    <script>
        new Vue({
            el: '#app',   
            methods:{
              show(){
                  console.log('父组件的方法')
              }
            },
            components: {
                son: {
                    template: '#temp',
                    methods:{
                        myclick(){
                //当点击子组件的按钮的时候,调用emit方法触发父组件传递过来的func方法,
                            this.$emit('func') 
                        }
                    }
                }
            }
        })
    </script>
    </body>

    调用父组件方法时可以传参,this.$emit('func',arg) 第二个参数开始就是要传给父组件方法的数据,同时show要写形参

    要把子组件data里的数据传给父组件方法,用this.来获取子组件data数据 


    Vue实例中还有个render方法,可将模板渲染到页面,component是将模板渲染到el控制的区域内,而render是替代整个el指定的区域

    <body>
    <div id="app">
    </div>
    <script>
        var login = {
            template:'<h3>登录</h3>'
        }
        new Vue({
            el: '#app',
            data:{},
            methods:{},
            render:function (createElements) { //createElements是个方法,可把指定组件模板渲染为html结构
                return createElements(login)
            }
        })
    </script>
  • 相关阅读:
    UVA
    shell 之for循环几种写法
    关于用户的一些操作(useradd与adduser的区别)
    shell 大小关系 -eq -ne
    shell之seq
    脚本函数写法
    Springboot将数据存储到数据库当中
    后端传输数据到前端
    前端传输数据到后端
    JS onFocus和onBlur
  • 原文地址:https://www.cnblogs.com/Grani/p/9637499.html
Copyright © 2020-2023  润新知