• Vue.js使用-组件(下篇)


    上一节,我们定义了组件的基本使用,下面我们看看组件其他的一些特性。
    1.组件作用域
    同时在Vue对象和组件中定义一个属性,显示结果是怎样的呢?

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            {{ msg }}
            <my-component></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'hello world'
            },
            components: {
                'my-component':{
                    template: '<div>{{ msg }}</div>',
                    data: function () {
                        return {
                            msg: 'hello shijingjing'
                        }
                    }
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    可见,都在各自的作用域内有效,且组件不影响Vue定义的属性。
    如何让组件使用Vue定义的属性呢,上节已经提到过,使用props属性。如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component v-bind:my-msg="msg"></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'hello world'
            },
            components: {
                'my-component':{
                    template: '<div>{{ myMsg }}</div>',
                    props: ['myMsg']
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    2.slot占位符
    slot的意思是卡槽,也就是一个占位符,内容由组件包含的内容而定。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component>
                <div>这是组件里面真正包含的内容</div>
            </my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            components: {
                'my-component':{
                    template: '<div>hello world</div><slot>这只是一个占位符,具体内容由component包含的内容来定</slot>'
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    如果组件里面没有包含内容呢?

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component>
            </my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            components: {
                'my-component':{
                    template: '<div>hello world</div><slot>这只是一个占位符,具体内容由component包含的内容来定</slot>'
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    可以再组件中包含占位符,来定义更为通用的组件。如一个对话框组件,不同时候弹出的标题不同,那么标题可以使用slot定义,真正内容放到组件内部。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component>
                <header slot="header">
                    你好吗
                </header>
                <div slot="body">
                    是的
                </div>
                <footer slot="footer">
                    再见
                </footer>
            </my-component>
            ------------------------------------------------------
            <my-component>
                <header slot="header">
                    早上好
                </header>
                <div slot="body">
                    中午好
                </div>
                <footer slot="footer">
                    晚上好
                </footer>
            </my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            components: {
                'my-component':{
                    template: '<div>hello world</div><slot name="header"></slot><slot name="body"></slot><slot name="footer"></slot>'
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    3.组件之间数据访问
    1)父组件访问子组件属性 $children

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            components: {
                'my-component':{
                    template: '<div>hello world</div><child-component1></child-component1><button v-on:click="showChildData">显示组件</button>',
                    components:{
                        'child-component1':{
                            template: '<div>hello child 1</div>',
                            data: function () {
                                return {
                                    msg: 'child 1'
                                }
                            }
                        }
                    },
                    methods:{
                        showChildData: function () {
                            console.log(this.$children[0].msg);
                        }
                    }
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    除了$children,还可以使用v-ref:c1来给组件指定一个索引名称c1,查询子组件时,使用$refs.c1找到这个子组件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            components: {
                'my-component':{
                    template: '<div>hello world</div><child-component1 v-ref:c1></child-component1><button v-on:click="showChildData">显示子组件</button>',
                    components:{
                        'child-component1':{
                            template: '<div>hello child 1</div>',
                            data: function () {
                                return {
                                    msg: 'child 1'
                                }
                            }
                        }
                    },
                    methods:{
                        showChildData: function () {
                            console.log(this.$refs.c1.msg);
                        }
                    }
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    2)子组件访问父组件属性 $parent

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            components: {
                'my-component':{
                    template: '<div>hello world</div><child-component1></child-component1>',
                    components:{
                        'child-component1':{
                            template: '<div>hello child 1</div><button v-on:click="showParentData">显示父组件</button>',
    
                            methods:{
                                showParentData: function () {
                                    console.log(this.$parent.msg);
                                }
                            }
                        }
                    },
                    data: function () {
                        return {
                            msg: 'parent'
                        }
                    }
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    3)子组件访问根组件属性 $root

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <my-component></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'root'
            },
            components: {
                'my-component':{
                    template: '<div>hello world</div><child-component1></child-component1>',
                    components:{
                        'child-component1':{
                            template: '<div>hello child 1</div><button v-on:click="showRootData">显示根组件</button>',
    
                            methods:{
                                showRootData: function () {
                                    console.log(this.$root.msg);
                                }
                            }
                        }
                    }
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    可见,根元素指的是Vue对象

    由$children,$parent,$root可以实现父子组件,以及Vue对象间的数据交互,但是还是尽量使用props属性来传递数据,
    可以避免父子组件的过度耦合,以及子组件修改了父组件中的数据。

    4.组件之间事件传递
    1)派发事件$dispatch,事件沿着父链冒泡

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            {{ message }}
            <my-component></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: ''
            },
            components: {
                'my-component':{
                    template: ' <input v-model="msg" /><button v-on:click="notify">dispatch</button>',
                    data: function () {
                        return {
                            msg: ''
                        }
                    },
                    methods:{
                        notify: function () {
                            this.$dispatch('child-msg', this.msg);
                        }
                    }
                }
            },
            events:{
                'child-msg': function (msg) {
                    this.message = msg;
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    $.dispatch会将事件派发到父组件的events事件,父组件接收到子组件的派发后,调用child-msg事件。

    2)broadcast广播事件,事件向下传导给所有的子组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="message"/>
            <button v-on:click="notify">broadcast</button>
            <my-component></my-component>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: ''
            },
            components: {
                'my-component':{
                    template: '{{msg}}',
                    data: function () {
                        return {
                            msg: ''
                        }
                    },
                    events:{
                        'parent-msg': function (msg) {
                            this.msg = msg;
                        }
                    }
                }
            },
            methods:{
                notify: function () {
                    this.$broadcast('parent-msg', this.message);
                }
            }
        })
    </script>
    </html>
    

    运行结果:

    $.broadcast会将事件广播到子组件的events事件,子组件接收到父组件的广播后,调用parent-msg事件。

  • 相关阅读:
    rem适配布局(rem+less+媒体查询 和 rem+flexible.js)
    flex布局(弹性布局)
    移动端技术选型
    移动端(视口(meta),像素比,二倍图(图片,背景图,精灵图),css初始化(normalize.css),特殊样式,常见屏幕尺寸)
    案例-3D旋转木马
    CSS新特性(3D转换,perspective(透视),transfrom-style(子元素是否开启三维环境))
    css3 新特性(动画)
    案例-2D会旋转的盒子(rotate), 会缩放的盒子(scale),动画(animation)
    listener启动与关闭
    Oracle在Linux内核参数的修改
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/8378899.html
Copyright © 2020-2023  润新知