组件化思想
将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易。
组件化是vue中的重要思想
- 它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。
- 任何应用都会被抽象成一颗组件树。
注册组件的步骤
- 创造组件构造器:通过调用Vue.extend()方法
- 注册组件:通过调用Vue.component()方法
- 使用组件:在Vue实例作用范围内
组件对象的data属性
- data属性必须是一个函数:多次调用时,返回的都是一个新对象,组件间不会相互影响。
组件间的通信
- 父组件通过props属性向子组件传递数据
- 子组件是不能引用父组件或者Vue实例的数据的,但是在开发中 有些数据确实需要从上层传递到下层的。比如在一个页面中,从服务器请求数据,需要在子组件中显示,这时需要从父组件传递数据给子组件。
components: {
cpn: {
template: '#cpn',
// 形式一:字符串数组,数组中的字符串就是传递时的名称
// props: ['prop']
// 形式二:对象(常用)
props: {
// 1. 类型限制
propA: Array
// 2. 提供默认值,必传值required为true时,propB就是必传的
propB: {
type: String,
default: 'xxxx',
required: true
}
// 3. 类型为对象或数组,默认值必须为函数
propC: {
type: Array,
default() {
return []
}
}
// 4. 自定义验证函数
propD: {
validator(value){
return ['success','warning','danger'].indexOf(value) != -1
}
}
// 5. 自定义类型,将变量类型定义为该类型
propF: Person
}
}
}
- 子组件中自定义事件通过$emit向父组件发送消息,父组件中通过v-on监听事件
- 比如:购物网站分类页,点击其中一个小分类后,父组件接受到信号后去请求对应的商品列表
<div id="app">
<cpn @itemclick="cpnClick"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {},
methods: {
cpnClick() {
console.log('click')
}
},
components: {
cpn: {
template: '#cpn',
data() {
return {
categories: [{
id: 1,
name: '热门推荐'
},
{
id: 2,
name: '手机数码'
},
{
id: 3,
name: '家用家电'
},
{
id: 4,
name: '电脑办公'
},
]
}
},
methods: {
btnClick(item) {
this.$emit('itemclick')
}
}
}
}
})
</script>
注:1. 在template标签内必须要用一个根标签把子组件的布局包起来
2. 目前,子组件变量在父组件模板中使用时不支持驼峰命名法
3. 子组件最好避免直接修改props的内容,可以在data修改
-
父组件通过 c h i l d r e n ( 不 常 用 ) / children(不常用)/ children(不常用)/refs访问子组件,可以直接调用子组件的属性和方法
-
this.$children 是一个数组类型
-
this.$refs 是一个对象类型,子组件使用时定义一个属性,如
<cpn ref = "xxx"></cpn>
xxx相当于是子组件的名字,父组件访问:this.$refs.xxx
-
- 子组件通过$parent访问父组件(开发中不建议使用)
- 子组件通过$root访问根组件即vue实例
slot(插槽)
抽取共性,保留不同:将共性抽取到组件中,将不同暴露为插槽
-
为什么要使用slot?
- 在生活中很多地方都有插槽,电脑的USB插槽,插板中的电源插槽
- 插槽的目的是让我们原有的设备具备扩展性
- 组件的插槽也是为了让我们封装的组件具有更高的扩展性
- 让使用者决定组件内部内容要填充什么。比如移动网站的导航栏
-
插槽的使用
- 插槽的基本使用:
<slot></slot>
- 插槽的默认值使用:
<slot><button></button></slot>
- 替换插槽的默认值:直接用标签替换
- 具名插槽:
<slot name = "xxxx"></slot>
-
编译作用域:
-
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
-
作用域插槽:
-
父组件替换插槽的标签,但是内容由子组件来提供
- 在子组件的slot标签中定义属性,绑定子组件中的数据。父组件中在template标签中用v-slot拿到slot对象,通过定义的属性获取子组件绑定的数据。