美文网首页
深入理解vue组件

深入理解vue组件

作者: i高安 | 来源:发表于2020-11-25 09:15 被阅读0次

    一、使用组件的细节点
    当使用table、select等标签时,组件标签化可能会有bug,此时应该使用 is 接受组件。

    <div id="app">
                <table>
                    <tbody>
                        <tr is="row"></tr>
                        <tr is="row"></tr>
                        <tr is="row"></tr>
                    </tbody>
                    
                </table>
            </div>
            
            <script type="text/javascript">
                Vue.component('row', {
                    template:'<tr><td>This is a row</td></tr>'
                })
                var app = new Vue({
                    el:"#app"
                })
            </script>
    

    在子组件定义data时,data必须是一个函数,不能是一个对象。
    在vue中如果要操作dom,需要使用 ref 引用,从而获取dom节点。
    需求:定义一个子组件,使其数字自加,在父组件中对子组件的数字求和。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>组件中的细节点</title>
            <script src="../vue.js"></script>
        </head>
        <body>
            <div id="app">
                <counter ref='number1' @change="changeClick"></counter>
                <counter ref='number2' @change="changeClick"></counter>
                <div>{{total}}</div>
            </div>
            
            <script>
                //定义一个子组件
                Vue.component('counter', {
                    template:"<div @click='handleClick'>{{count}}</div>",
                    data:function() {
                        return {
                            count: 0
                        }
                    },
                    methods:{
                        handleClick: function() {
                            this.count++;
                            //通过$emit 让父组件监听到状态变化
                            this.$emit('change');
                        }
                    }
                    
                })
                var app = new Vue({
                    el:"#app",
                    data:{
                        total:0
                    },
                    methods:{
                        changeClick: function() {
                            this.total = this.$refs.number1.count + this.$refs.number2.count;
                        }
                    }
                })
            </script>
        </body>
    </html>
    

    二、父子组件之间的数据传递
    单向数据流:父组件可以向子组件传递参数,传递的参数父组件可以任意修改。子组件不能修改父组件传来的参数,只能使用。
    父组件向子组件传值:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>父子组件传值</title>
            <script src="../vue.js"></script>
        </head>
        <body>
            <div id="app">
                <counter :count="0"></counter>
                <counter :count="1"></counter>
            </div>
            
            <script type="text/javascript">
                //定义一个局部组件
                var counter = {
                    //使用props接受父组件的值
                    props: ['count'],
                    data: function(){
                        return {
                            number: this.count
                        }
                    },
                    template: '<div @click="handleClick">{{number}}</div>',
                    methods: {
                        handleClick: function() {
                            this.number++;
                        }
                    }
                }
                
                var app = new Vue({
                    el:"#app",
                    //注册组件
                    components:{
                        counter: counter
                    }
                })
            </script>
        </body>
    </html>
    

    子组件向父组件传值:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>父子组件传值</title>
            <script src="../vue.js"></script>
        </head>
        <body>
            <div id="app">
                <counter :count="8" @incnumber="handleChangeClick"></counter>
                <counter :count="2" @incnumber="handleChangeClick"></counter>
                <div>{{total}}</div>
            </div>
            
            <script type="text/javascript">
                //定义一个局部组件
                var counter = {
                    //使用props接受父组件的值
                    props: ['count'],
                    data: function(){
                        return {
                            number: this.count
                        }
                    },
                    template: '<div @click="handleClick">{{number}}</div>',
                    methods: {
                        handleClick: function() {
                            this.number++;
                            //通过事件向父组件传值
                            this.$emit('incnumber', 1)
                        }
                    }
                }
                
                var app = new Vue({
                    el:"#app",
                    data:{
                        total: 10
                    },
                    //注册组件
                    components:{
                        counter: counter
                    },
                    methods:{
                        handleChangeClick: function(step) {
                            this.total += step
                        }
                    }
                })
            </script>
        </body>
    </html>
    

    三、给组件绑定原生事件
    使用native修饰符监听:

    <div id="app">
                <child @click.native="handleClick"></child>
            </div>
            <script>
                Vue.component('child', {
                    template:"<div>Child</div>"
                })
                var app = new Vue({
                    el:"#app",
                    methods:{
                        handleClick: function() {
                            alert(222)
                        }
                    }
                })
            </script>
    

    四、非父子组件之间的传值(Bus/总线/发布订阅模式/观察者模式)

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>非父子组件之间的传值(Bus/总线/发布订阅模式/观察者模式)</title>
            <script src="../vue.js"></script>
        </head>
        <body>
            <div id="app">
                <child content="xiao"></child>
                <child content="mo"></child>
            </div>
            
            <script>
                Vue.prototype.bus = new Vue()
                
                Vue.component('child', {
                    data: function() {
                        return {
                            selfContent : this.content
                        }
                    },
                    props:{
                        content: String
                    },
                    template:'<div @click="handleClick">{{selfContent}}</div>',
                    methods:{
                        handleClick: function() {
                            this.bus.$emit('change', this.selfContent)
                        }
                    },
                    mounted: function() {
                        var this_ = this
                        this.bus.$on('change', function(msg) {
                            this_.selfContent = msg
                        })
                    }
                })
                
                var app = new Vue({
                    el:"#app"
                })
            </script>
        </body>
    </html>
    

    五、Vue中的插槽(slot)

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>Vue中的插槽(slot)</title>
            <script src="../vue.js"></script>
        </head>
        <body>
            <div id="app">
                <child>
                    <h1>Xiaomo</h1>
                </child>
            </div>
            
            <script>
                
                Vue.component('child', {
                    template:`<div>
                    <p>Hello</p>
                    <slot>可以定义默认值</slot>
                    </div>`
                })
                
                var app = new Vue({
                    el:"#app"
                })
            </script>
        </body>
    </html>
    

    局部插槽需要使用template标签括起来。
    六、动态组件
    <component>标签表示动态组件,根据is值判断加载不同的组件。
    v-once 可以有效提高静态页面展示效率。

    相关文章

      网友评论

          本文标题:深入理解vue组件

          本文链接:https://www.haomeiwen.com/subject/buriiktx.html