Vue组件

定义组件的两种方式

  1. 全局定义组件
  2. 局部定义组件
 <div id="demo">
     <!--使用组件-->
     <my-component></my-component>
 </div>

Vue.component("my-component",{     // 全局定义组件
    template:`<div>my-component是组件名;第二个参数是对象,描述了组件的内容</div>`
});
new Vue({
    el:"#demo"
    components:{       //局部定义组件
        "my-component2":{
            template:`<div>my-component2是组件名,局部组件</div>`
        }
    }
})

此处定义组件使用了HTML模板,需要遵循html的规则。
例如table标签内不能有div标签,如果写了vue引擎就会把div标签放在table标签上面!
但如果我就想让div放在table标签里面呢?不遵循HTML的既有规则呢
使用is关键字,等于组件名,如下:

<div id="demo">
    <table>
        <tr is="my-component"></tr>
    </table>
</div>

则vue引擎生成的html如下:

<div id="demo">
    <table>
        <tbody>
        <div>my-component是组件名;第二个参数是对象,描述了组件的内容</div>
        </tbody>
    </table>
</div>
而当直接使用字符串模板时,不会遵循HTML的规则。如下:
<div id="demo">
</div> 
new Vue({
    el:"#demo",
    template:`<table>
    <div>my-component是组件名;第二个参数是对象,描述了组件的内容</div>
</table>`,
})

则vue引擎生成的html如下:

<table>
    <div>my-component是组件名;第二个参数是对象,描述了组件的内容</div>
</table>

因此,再不同的模板下组件有不同的行为

在Vue实例中(new Vue({})),会有一个data用来绑定数据,而组件同样作为Vue的实例,也同样可以绑定数据。只不过data并不是一个直接的对象,而是以函数的方式,返回一个对象,如下:

    <div id="demo">
        <my-component></my-component>
    </div>
    Vue.component("my-component",{     // 全局定义组件
   		 template:`<div>我是一个{{name}}</div>`,
   		 data:function(){
        	return {name:"组件"}
    	}
	});
	new Vue({
   		el: "#demo"
	})
这是因为如果直接把data写成一个对象,就会是全局的,组件间会相互改变data值,而函数的形式,使其不会是全局的变量,组件间不会相互影响data值。

组件的自定义

组件是为了满足可复用的需求,如上面所写的组件demo,就太过单一,无法满足多样化的需求。
在使用组件的时候,是以标签的形式插入在HTML中,在标签中可以写一些自定义属性,然后在组件中使用props接收该属性。

    <div id="demo">
        <my-component name="tanjw"></my-component>
    </div>
Vue.component("my-component",{     // 全局定义组件
    template:`<div>我叫{{name}}</div>`,
    props:["name"]
});
new Vue({
    el: "#demo"
})

props简单使用时,是一个数组,内只有变量名。
但需要对变量添加权限时,是一个对象的形式。如:

Vue.component("my-component",{     // 全局定义组件
    template:`<div>我叫{{name}}</div>`,
    props:{
        name:{
            type:String,  //规定其类型
            default:"tanjw", //默认值
            required:true  //是否必须传递name的值
        }
    }
});
new Vue({
    el: "#demo"
})

注意与v-band的区别,<my-component :name="name" name="tanjw"></my-component>
:name="name"中,属性值name是data中的变量,而在name="tanjw"中,属性值tanjw是字符串。

我们现在就可以使用组件的自定义特性来进行组件的父子通信。
要注意的是,我们要避免直接改变props的值,通过组件的data:function(){},来间接改变,否则在发生某些重新渲染的情况下,会取到原来的值,而不是直接改变后的值。

组件的自定义事件

上面说了,我们不能直接改变父组件传递过来的属性值即props,那么就想直接使用传递得属性值呢?
利用组件的自定义事件。

上面说了,可以利用props从父组件向子组件传值,
而子组件向父组件传递可以利用自定义事件。
下例演示了点击子组件的按钮,父组件改变显示的总值。

    <div id="demo">
        {{total}}
        <component1 v-on:addtotal="addTotal"></component1>
        <component1 v-on:addtotal="addTotal"></component1>
    </div>
Vue.component("component1", {
    template: `
        <div>
            <button @click="addCount">{{count}}</button>
        </div>
    `,
    data: function(){
        return {count:0};
    },
    methods:{
        addCount:function(){
            this.count++;
            this.$emit("addtotal");   //count每改变一次,就触发一次自定义事件
        }
    }
});

new Vue({
    el: "#demo",
    data: {
        total: 0
    },
    methods:{
        addTotal:function(){
            this.total++;
        }
    }
})

内容分发(插槽)

作用:改变组件内的内容节点

    <div id="demo">
        <component1>
            <div>我是被插进来的div</div>
        </component1>
    </div>
Vue.component("component1", {
    template: `
    <div>
        <slot>
            <p>我是组件内的p标签</p>
        </slot>
    </div>`
});
new Vue({
    el: "#demo"
})

如上,在组件内使用slot标签作为内容分发的入口,当调用组件时,如果在组件标签内写了元素标签,则组件内slot的内容不会被渲染出来,只有在调用组件时没有写元素标签,solt的内容才会被渲染出来。其中,slot不能作为根标签。

//  而写作下面这样的形式时,甚至根据组件内`slot`的顺序,对调用组件的内容标签进行排序。
    <div id="demo">
        <component1>
            <div slot="one">我是被插进来的div1</div>
            <div slot="two">我是被插进来的div2</div>
        </component1>
    </div>
Vue.component("component1", {
    template: `
    <div>
        <slot name="one">
            <p>我是组件内的p1标签</p>
        </slot>
        <slot name="two">
            <p>我是组件内的p2标签</p>
        </slot>        
    </div>`
});
new Vue({
    el: "#demo"
})
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值