创建-----------》注册,一般都是局部组件
流程
// 1.创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>我是标题</h2>
<p>我是内容, 哈哈哈哈</p>
<p>我是内容, 呵呵呵呵</p>
</div>`
})
// 2.注册组件
Vue.component('my-cpn', cpnC)
全局组件、局部组件
// 1.创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>我是标题</h2>
<p>我是内容, 哈哈哈哈</p>
<p>我是内容, 呵呵呵呵</p>
</div>`
})
全局组件
Vue.component('my-cpn', cpnC)//调用
局部组件
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
// cpn使用组件时的标签名
cpn: cpnC
}
})
父子组件
// 1.创建第一个组件构造器(子组件)
const cpnC1 = Vue.extend({
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容, 哈哈哈哈</p>
</div>
`
})
// 2.创建第二个组件构造器(父组件)
const cpnC2 = Vue.extend({
template: `
<div>
<h2>我是标题2</h2>
<p>我是内容, 呵呵呵呵</p>
<cpn1></cpn1>
</div>
`,
components: {
cpn1: cpnC1
}
})
Vue实例它会在自己局部里先找,找不到再去全局组件,它本身并不知道cpn1组件内容,未被挂载到app实例中,直接在app 根dom下使用不被认为是一个组件/
root根组件
// root组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn2: cpnC2
}
})
语法糖注册组件,其内部会执行Vue.extend:
//全局
Vue.component('cpn1', {
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容, 哈哈哈哈</p>
</div>
`
})
//局部
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
'cpn2': {
template: `
<div>
<h2>我是标题2</h2>
<p>我是内容, 呵呵呵</p>
</div>
`
}
}
})
组件模板的分离写法
1.script标签, 注意:类型必须是text/x-template
<script type="text/x-template" id="cpn">
<div>
<h2>我是标题</h2>
<p>我是内容,哈哈哈</p>
</div>
</script>
//两个不同script里面
<script>
Vue.component('cpn', {
template: '#cpn',
data() {
return {
title: 'abc'
}
}
})
</script>
注意:组件中的内部不可以直接访问Vue的实例数据,即使能访问也不能这样做,随着体量的增多,不适合直接放到root根组件
组件内部的data属性,其内部必须是函数类型,对象会报错
data(){
return {}
}
这是因为要保证每次返回都是一个新对象,每个组件的data对象都彼此相互不影响
组件通信
const cpn = {
template: '#cpn',
// props: ['cmovies', 'cmessage'],
props: {
// 1.类型限制
// cmovies: Array,
// cmessage: String,
// 2.提供一些默认值, 以及必传值
cmessage: {
type: String,
default: 'aaaaaaaa',
required: true
},
// 类型是对象或者数组时, 默认值必须是一个函数
cmovies: {
type: Array,
default() {
return []
}
}
},
data() {
return {}
},
methods: {
}
}
vue2…17以后默认值需用函数返回
type可以是自定义数据类型,自定义的一个对象
驼峰使用,一般子组件使用直接c+父属性名,cinfo====>info
或者使用驼峰时,在传的过程应-相连,c-info、child-my-message
<div id="app">
<cpn :c-info="info" :child-my-message="message" v-bind:class></cpn>
</div>
<template id="cpn">
<div>
<h2>{{cInfo}}</h2>
<h2>{{childMyMessage}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
props: {
cInfo: {
type: Object,
default() {
return {}
}
},
childMyMessage: {
type: String,
default: ''
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: 'why',
age: 18,
height: 1.88
},
message: 'aaaaaa'
},
components: {
cpn
}
})
子传父
<!--父组件模板-->
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories"
@click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
// 1.子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{id: 'aaa', name: '热门推荐'},
{id: 'bbb', name: '手机数码'},
{id: 'ccc', name: '家用家电'},
{id: 'ddd', name: '电脑办公'},
]
}
},
methods: {
btnClick(item) {
// 发射事件: 自定义事件
this.$emit('item-click', item)
}
}
}
// 2.父组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn
},
methods: {
cpnClick(item) {
console.log('cpnClick', item);
}
}
})
注意:子传父时:需要调用事件this.emit(“itemClick”,item)
//itemClick为父组件自定义事件,非脚手架情况下用驼峰命名父组件事件可能会出现问题,建议一个单词或者‘-’连接
$children:[]
$refs最常用:{}
<div id='app'>
<cpn ref='aaa'></cpn>
<button @click='btnclick'>111</button>
</div>
<template id='cpn'><template>
<script>
const app= new Vue({
el:"#app",
data:{},
methods:{
btnclick(){
console.log(this.$ref.aaa)
}
}
compontents:{
cpn:{
template:"#cpn",
data(){
},
methods:{
showMessage(){
console.log('asas')
}
}
}
})
</script>
子访问父组件
// 1.访问父组件$parent
// console.log(this.$parent);
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data() {
return {
name: '我是cpn组件的name'
}
},
components: {
ccpn: {
template: '#ccpn',
methods: {
btnClick() {
// 1.访问父组件$parent
// console.log(this.$parent);
// console.log(this.$parent.name);
// 2.访问根组件$root
console.log(this.$root);
console.log(this.$root.message);
}
}
}
}
}
}
})
// 2.访问根组件$root
console.log(this.$root);
console.log(this.$root.message);