[亲测]Vue组件
1.组件化在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航、尾部信息模块。但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。1.1.定义全局组件我们可以使用 Vue.component 来定义一个组件:Vue.component(组件...
1.组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航、尾部信息模块。
但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
1.1.定义全局组件
我们可以使用 Vue.component 来定义一个组件:
Vue.component(组件名称, Vue对象)
在 Vue 对象中我们需要使用 template 来定义组件的 HTML 部分。
(提示:在 ES6 中我们可以使用 模板字符串` 符号来定义多行字符串)
示例:
Vue.component('hello', {
template: `<p>Hello World !</p>`
})
注意:template 中的 HTML 代码必须要写在一个根元素中。
什么是根元素呢?看下图:
根元素:最外层要有一个标签。
- 案例:
- 案例实现
<script src="../vue-2.5.17.js"></script>
<div id="app">
<counter></counter>
</div>
<script>
// 定义全局组件,两个参数,组件名称和组件参数
Vue.component("counter",{
template:`<button v-on:click="count++" >{{count}}</button>`,
data(){
return {
count:0
}
}
})
var vm = new Vue({
el:"#app",
});
</script>
- 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
- 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
- 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
- data的定义方式比较特殊,必须是一个函数。
总结一下:
- 全局组件只能有一个根元素
- 组件中有data、methods、created、computed
- data一定要定义成方法,而且必须要有返回值
1.2.组件的复用
定义好的组件,可以任意复用多次:
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>
效果:
你会发现每个组件互不干扰,都有自己的count值。怎么实现的?
组件的data属性必须是函数!
当我们定义这个 <counter>
组件时,它的data 并不是像这样直接提供一个对象:
data: {
count: 0
}
取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
count: 0
}
}
如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!
案例:
<script src="../vue-2.5.17.js"></script>
<div id="app">
<!-- 组件肯定使用在页面中
组件的使用方式:以组件名为标签访问
-->
<counter></counter><br>
<counter></counter><br>
<list></list><br>
<list></list><br>
</div>
<script>
// 全局组件挂在到Vue对象中
// 第一个参数:组件名字
// 第二个参数:组件内容,需要是一个对象
Vue.component("counter",{
// 在组件中也必须要有模板,模板要写在一个根元素中,在vue中,只能有一个最大的父元素绑定el
// 模板内容需要使用 模板字符串
template:`<button @click="num++">加{{num}}</button>`,
// 模板中,data只能定义成方法格式,不能定义属性
// data方法必须要有返回值
data(){
return {
num:0
}
},
methods:{
}
});
// 继续写
Vue.component("list",{
template:`<ul>
<li v-for="user in users">{{user.name}} - {{user.age}}</li>
</ul>`,
data(){
return {
users:[{name:"lucy",age:12},
{name:"tom",age:12},
{name:"lily",age:12}
]
}
}
})
var vm = new Vue({
el:"#app"
})
</script>
1.2.局部注册
一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。
因此,对于一些并不频繁使用的组件,我们会采用局部注册。
我们先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:
const counter = {
template:'<button v-on:click="count++">点击 {{ count }} </button>',
data(){
return {
count:0
}
}
};
然后在Vue中使用它:
var app = new Vue({
el:"#app",
components:{
counter:counter // 将定义的对象注册为组件
}
})
- components就是当前vue对象子组件集合。
- 其key就是子组件名称
- 其值就是组件对象的属性
- 效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用
1.3.组件通信
通常一个页面会以一棵嵌套的组件树的形式来组织:
- 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
- 左侧内容区又分为上下两个组件
- 右侧边栏中又包含了3个子组件
各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
1.3.1.父向子传递props
父组件是通过props属性给子组件通信的来看下代码:
父组件:
<parent>
<child :child-com="content"></child> //注意这里用驼峰写法哦
</parent>
data(){
return {
content:'lixin'
};
}
子组件通过props来接受数据
第一种方法
props: ['childCom']
第二种方法
props: {
childCom: String //这里指定了字符串类型,如果类型不一致会警告的哦
}
第三种方法
props: {
childCom: {
type: String,
default: 'lixin'
}
}
1.3.2.子向父传递$emit
vue2.0只允许单向数据传递,我们通过出发事件来改变组件的数据,废话少说,上干货
子组件代码
<template>
<div @click="open"></div>
</template>
methods: {
open() {
this.$emit('showbox','the msg'); //触发showbox方法,'the msg'为向父组件传递的数据
}
}
父组件
<child @showbox="toshow" :msg="msg"></child> //监听子组件触发的showbox事件,然后调用toshow方法
methods: {
toshow(msg) {
this.msg = msg;
}
}
1.3.3.兄弟传递$emit $on
我们可以实例化一个vue实例,相当于一个第三方
let vm = new Vue(); //创建一个新实例
组件他哥
<div @click="ge"></div>
methods: {
ge() {
vm.$emit('blur','lixin'); //触发事件
}
}
组件小弟接受大哥命令
<div></div>
created() {
vm.$on('blur', (arg) => {
this.test= arg; // 接收
});
}
更多推荐
所有评论(0)