组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可
组件化和模块化的不同:
<div id="app">
<mycom>mycom>
div>
<script>
// 1.创建组件构造器
const com = Vue.extend({
template: '这是使用Vue.extend创建的组件
'
})
// 2.注册组件
Vue.component('mycom', com)
// 也可以合并来写
// Vue.component('mycom', Vue.extend({
// template: '这是使用Vue.extend创建的组件
'
// }))
var vm = new Vue({
el: '#app'
})
script>
Vue.extend():
Vue.component():
Vue.component('mycom',{
template: '这是直接使用Vue.component创建的组件
'
})
这是一种比较方便的写法,实际内部还是会调用extend方法
<template id="com">
<div>
<h2>这是使用template标签定义的组件h2>
div>
template>
<script>
var vm = new Vue({
el: '#app',
components:{
'mycom':{
template:'#com'
}
}
})
script>
全局组件可以在任意vue实例下使用,如果我们注册的组件是挂载在某个实例中,那么它就是一个局部组件
var vm = new Vue({
el: '#app',
components:{
'mycom':com
}
})
子组件是不能引用父组件或者vue实例的数据的,但是在开发中一些数据确实需要从上层传递到下层。比如在一个页面中,我们从服务器请求到了大量数据,其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。这个时候,并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)
<div id="app">
<mycom :cmovies="movies">mycom>
div>
<template id="com">
<div>
<ul>
<li v-for="movie in cmovies">{{movie}}li>
ul>
div>
template>
<script>
var vm = new Vue({
el: '#app',
// 1.父组件中的数据(这里把根组件看成父组件)
data: {
movies: ['aaa', 'bbb', 'ccc'],
},
components: {
'mycom': {
template: '#com',
// 2.使用pros声明从父组件接收到的数据
props: ['cmovies']
},
}
})
script>
props的值有两种方式:
props: {
cmovies:{
type:Array,
default(){
return []
},
required:true
}
}
<div id="app">
<mycom @itemclick="clickOp">mycom>
div>
<template id="com">
<div>
<button v-for="option in options" @click="btnClick(option)">{{option.name}}button>
div>
template>
<script>
const mycom = {
template: '#com',
// 1.子组件中的数据
data() {
return {
options: [{
id: 1,
name: 'aaa'
}, {
id: 2,
name: 'bbb'
}, {
id: 3,
name: 'ccc'
}]
}
},
methods: {
btnClick(option) {
// 2.将自定义事件发射出去,第一个参数是自定义事件的名称,可以传递参数
this.$emit('itemclick', option)
}
}
}
var vm = new Vue({
el: '#app',
components: {
mycom
},
// 4.父组件处理自定义事件,对传递过来的数据进行处理
methods: {
clickOp(option) {
console.log(option)
}
}
})
script>
this.$children
访问,这种方式获取到的是父组件下所有的子组件实例,一般在需要获取所有子组件实例的时候才使用这种方法,可以使用数组下标操作指定实例this.$ref
访问指定子组件实例,需要在使用子组件时声明ref属性
,父组件访问该组件时使用this.$ref.aaa
获取该实例通过this.$parent
访问指定父组件实例
组件的插槽是为了让我们封装的组件更加具有扩展性,让使用者可以决定组件内部的一些内容到底显示什么
<div id="app">
<mycom>mycom>
<mycom><button>我是拓展的内容111button>mycom>
<mycom><b>我是拓展的内容222b>mycom>
div>
<template id="com">
<div>
<h2>我是一个组件h2>
<slot>slot>
div>
template>
当子组件的功能复杂时,子组件的插槽可能并非一个。当存在多个插槽,想要替换指定的某个插槽中的内容,使用具名插槽比较方便。
<div id="app">
<mycom>
<button slot="left">返回button>
mycom>
div>
<template id="com">
<div>
<slot name="left">左边slot>
<slot name="center">中间slot>
<slot name="right">右边slot>
div>
template>
概括地说,作用域插槽是使用父组件替换插槽的标签,但是内容由子组件提供
<div id="app">
<mycom>
<div slot-scope="myslot">
<span v-for="item in myslot.cdata">{{item}} - span>
div>
mycom>
div>
<template id="com">
<div>
<slot :cdata="options">
<ui>
<li v-for="option in options">{{option}}li>
ui>
slot>
div>
template>
<script>
var vm = new Vue({
el: '#app',
components: {
'mycom': {
template: '#com',
data() {
return {
options:['aaa','bbb','ccc']
}
},
},
}
})
script>