vue组件

组件使用三个步骤:

需要在vue实例中使用

  • 创建组件构造器
  • 注册组件
  • 使用组件
<body>
    <div id="app">
        <!--3.使用组件-->
        <my-cpn></my-cpn>
        <my-cpn></my-cpn>
        <my-cpn></my-cpn>
    </div>
    <script>
        //1.创建组件构造器
        const cpnC = Vue.extend({
            template: `
        <div>
            <h2>I am title</h2>
            <p>I am content</p>
            <p>I am content</p>
        </div>
    `
        })
        //2.注册组件(全局组件,意味着可以在多个Vue实例中使用)
        Vue.component('my-cpn', cpnC)
        //创建Vue实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            //局部组件
            components: {
                'cpn': cpnC,
            },
        });
    </script>
</body>
  • 全局组件:可以在多个vue实例中被使用
  • 局部组件:只可以在被注册的vue实例中使用

父组件和子组件

组件之间的层级关系
vue实例可以看作是一个根组件

    //父组件
    const cpn2 = Vue.extend({
        template: `
    <div>
        <h2>I am title222</h2>
        <p>I am 哈哈哈哈哈哈</p>
        <p>I am conte哈哈哈nt</p>
        <cpn11></cpn11>
    </div>
`,
//子组件
        components: {
            cpn11: cpn1
        }
    })

注册组件的语法糖

全局组件:

  <script>

        Vue.component('my-cpn', {
            template: `
            <div>
                <h2>I am title</h2>
                <p>I am 哈哈哈哈哈哈</p>
                <p>I am conte哈哈哈nt</p>
            </div> `
        })
        //创建Vue实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            //局部组件
            components: {
                'cpn': {
                    template: `
                    <div>
                        <h2>I am title222</h2>
                        <p>I am 哈哈哈哈哈哈</p>
                        <p>I am conte哈哈哈nt</p>
                    </div> `
                }
            },
        });
    </script>

省去了vue.extend()的步骤

模板的分离写法

    <script type="text/x-template" id='cpn'>
        <div>
            <h2>I am title</h2>
            <p>I am 哈哈哈哈哈哈</p>
            <p>I am 模板的分离写法</p>
        </div> 
    </script>
    <script>
        Vue.component('my-cpn', {
            template: `#cpn`
        })
    <template id="cpn2">
        <div>
            <h2>I am title</h2>
            <p>I am template</p>
            <p>I am 模板的分离写法</p>
        </div>
    </template>

组件的data要为一个函数:

    <template id="cpn">
        <div>
            <h2>I am {{title}}</h2>
            <p>I am template</p>
            <p>I am 模板的分离写法</p>
        </div>
    </template>
    <script>
        Vue.component('my-cpn', {
            template: `#cpn`,
            data() {
                return {
                    title: 'aaaaaaaaaaa'
                }
            }
        })

为什么要为函数:
防止组件间的数据相互干扰,保证数据独立。

父子组件的通信

父传子:通过props
子传父:通过$emit:events

父传子-props使用

<body>
    <div id="app">
        <button @click="changeData">change</button>
        <!--使用组件-->
        <my-cpn :name="myName" :age="myAge"></my-cpn>
        <my-cpn></my-cpn>
    </div>
    <template id="cpn">
        <div>
            <h2>{{name}}</h2>
            <h2>{{age}}</h2>
            <h2>{{info}}</h2>
        </div>
    </template>
    <script>
        Vue.component('my-cpn', {
            template: `#cpn`,
            // props: ['name', 'age'],
            props: {
                name: {
                    type: String,
                    default: 'laaa'
                },
                age: {
                    //类型为对象或数组时,默认值必须为函数
                    type: Number,
                    default: 18,
                    //required为true表示必须传入
                    //required:true
                },
                info: {
                    //类型为对象或数组时,默认值必须为函数
                    type: Object,
                    default: function () {
                        return {
                            name: 'luo',
                            age: 22
                        }
                    }
                }
            }
        })
        //创建Vue实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {
                myName: 'luo',
                myAge: 24
            },
            methods: {
                changeData() {
                    this.myAge++
                }
            }
        });
    </script>
</body>

子传父-$emit


<body>
    <div id="app">
        <!--使用组件-->
        <my-cpn :name="myName" :age="myAge" @inc="myCounter" @dec="myCounter"></my-cpn>
    </div>
    <template id="cpn">
        <div>
            <button @click="inc">+</button>
            <button @click="dec">-</button>
        </div>
    </template>
    <script>
        Vue.component('my-cpn', {
            template: `#cpn`,
            props: {
            },
            data() {
            },
            methods: {
                inc() {
                    this.counter++
                    this.$emit('inc', {
                        name: 'lai',
                        age: 66,
                        counter: this.counter
                    })
                },
                dec() {
                    this.counter--
                    this.$emit('dec', {
                        name: 'hua',
                        age: 88,
                        counter: this.counter
                    })
                }
            }
        })
        //创建Vue实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {
            },
            methods: {
                myCounter(info) {
                    console.log(info);
                }
            },

    </script>
</body>

父子组件的访问方式

  • 父访问子:$children或者 $refs (reference)
  • 子访问父:$parent

$children–数组类型

包含所有子组件对象


<body>
    <div id="app">
        <button @click="getChildren">test</button>
        <!--使用组件-->
        <my-cpn @inc="myCounter" @dec="myCounter"></my-cpn>
        <my-cpn></my-cpn>
    </div>


    <template id="cpn">
        <div>
            <button @click="inc">+</button>
            <button @click="dec">-</button>
        </div>
    </template>
    <script>
        Vue.component('my-cpn', {
            template: `#cpn`,
            // props: ['name', 'age'],
            props: {
                }
            },
            data() {
                return {
                    title: 'aaaaaaaaaaa',
                    counter: 0
                }
            },
            methods: {
                showMessage() {
                    console.log('test.......');
                },
                inc() {
                    this.counter++
                    this.$emit('inc', {
                        name: 'lai',
                        age: 66,
                        counter: this.counter
                    })
                },
                dec() {
                    this.counter--
                    this.$emit('dec', {
                        name: 'hua',
                        age: 88,
                        counter: this.counter
                    })
                }
            }
        })
        //创建Vue实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {
                myName: 'luo',
                myAge: 24,
                counter: 0
            },
            methods: {
                getChildren() {
                    console.log(this.$children);
                    this.$children[0].inc()
                    this.$children[0].showMessage()
                }
            },

        });
    </script>
</body>

$children返回的是个数组,取特定组件数据时是按照排列顺序编号,在有许多组件的情况下不方便。

$refs

 <my-cpn ref='a' :name="myName" :age="myAge" @inc="myCounter" @dec="myCounter"></my-cpn>
 <my-cpn ref='b'></my-cpn>
                getChildren() {
                    console.log(this.$refs);
                    this.$refs.a.showMessage()
                    this.$refs.b.showMessage()
                },

首先给组件添加ref="name"属性,然后在父组件方法中调用该名称的组件即可。

子访问父-$parent

console.log(this.$parent);

不建议使用,降低了组件的复用性

slot 插槽

让封装的组件更具有拓展性
基本使用:

    <div id="app">
        <cpn>
            <!--可以放置多个值-->
            <button>test</button>
            <h2>test</h2>
        </cpn>
        <cpn></cpn>
        <cpn></cpn>
        <cpn></cpn>
    </div>
    <template id="cpn">
        <div>
            <h2>我是组件</h2>
            <p>hhhhhhhhhh</p>
            <slot>
                <!--插槽默认值-->
                <h2>slot default</h2>
            </slot>
        </div>
    </template>

具名插槽

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值