前言
首先,本篇文章是由一串错误的代码引出的…
//需求:实现父组件向子组件传递数据
<body>
<div id="app">
<child :message="parentMsg"></child>
</div>
<template id="child">
<div>
{
{
message}}
</div>
</template>
<script>
// 最初写法================================报错
// Vue.component('child', {
// template: '#child',
// data() {
// return {}
// },
// props: {
// message: {
// type: String,
// default: 'aaaaaa'
// }
// }
// })
// ================================报错
// 正确写法================================
const child = Vue.extend({
template: '#child',
data() {
return {
}
},
props: {
message: {
type: String,
default: 'aaaaaa'
}
}
})
// 正确写法================================
const app = new Vue({
el: "#app",
data: {
parentMsg: '我是父组件parentMsg'
},
methods: {
},
components: {
child },
})
</script>
</body>
毫不意外,按照最初写法将出现的结果是一串爆红——vue.js:634 [Vue warn]: Failed to mount component: template or render function not defined.
,意思是mount组件失败:模板或渲染函数没有定义。不要慌,有错误就会有解决办法,我们来研究一番!
先来解释一下我最初为什么会这么写,有两点原因:
- 我知道
Vue.component
是创建组件的方式之一,但是我误以为它是简写方式(我写的时候还在寻思着,这也不简写吧,还是那么复杂,甚至有一瞬间我分不清这是组件还是组件构造器)——涉及知识范围:组件和组件构造器的区分。 - 我分明清楚可以通过
Vue.component
来创建全局组件,而且全局组件不是所有组件都能使用的嘛?那么我就在根组件中components它为什么不可以嘞(我甚至还超级“理直气壮”!)——涉及知识范围:全局组件和局部组件的使用。
我承认,有些离谱儿了~
OK,分析完错误原因之后,我们就来理一理它们之间的关系!
组件:Vue.component()
我们先来写一个组件的案例:
<body>
<div id="app">
<!-- 3、使用组件 -->
<my-cpn></my-cpn>
</div>
<script>
// 1、创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>早上好!</h2>
<p>中午好!</p>
<p>晚上好!</p>
</div>`
})
// 2、注册组件
Vue.component('my-cpn', cpnC)
//根组件
const app = new Vue({
el: "#app",
data: {
},
methods: {
},
})
</script>
</body>
vue.js中创建组件有三大步骤:
-
定义组件 ——
- 方式1:调用
Vue.extend()
创建的是一个组件构造器, 通常在创建组件构造器时,传入template
代表我们自定义组件的模板,即const cpnC = Vue.extend({ template:' ' })
; - 方式2:使用
Vue.component('组件名称',{ 组件构造器 })
直接创建组件(全局组件)。
- 方式1:调用
-
注册组件 ——
- 全局组件:通过
Vue.component('标签名', 组件名)
注册组件时,组件的注册是全局的; - 局部组件:注册的组件是挂载在某个实例中,即:
- 全局组件:通过
const app = new Vue({
el: "#app",
// 注册局部组件
components: {
// cpn使用组件时的标签名,cpnC组件名
cpn: cpnC
}
})
- 使用组件 —— 在Vue实例的作用范围内使用组件。
组件构造器:Vue.extend()
extend创建的是一个组件构造器,而不是一个具体的组件实例,所以直接使用无法生效。
组件构造器相当于Vue.component()方法的第二个参数部分扫描二维码关注公众号,回复: 15031120 查看本文章
组件构造器的正确打开方式(有效使用):
用法一:注册
用法二:挂载
组件构造器的简写形式:
//正常写法:
const child = Vue.extend({
template: '#child',
data() {
return {
}
},
props: {
message: {
type: String,
default: 'aaaaaa'
}
}
})
//简写形式:
const child = {
template: '#child',
data() {
return {
}
},
props: {
message: {
type: String,
default: 'aaaaaa'
}
}
}
全局组件
方式一:通过构造器创建组件,通过Vue.component('标签名', 组件名)
注册组件
<body>
<div id="app">
<!-- 3、使用组件 -->
<my-cpn></my-cpn>
</div>
<script>
// 1、创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>早上好!</h2>
<p>中午好!</p>
<p>晚上好!</p>
</div>`
})
// 2、注册全局组件
Vue.component('my-cpn', cpnC)
//根组件
const app = new Vue({
el: "#app",
data: {
},
methods: {
},
})
</script>
</body>
方式二:使用Vue.component('组件名称',{ 组件构造器 })
直接创建组件(全局组件)
<body>
<div id="app">
<cpn1></cpn1>
</div>
<script>
// 1.创建组件构造器对象
// const cpnC1 = Vue.extend()
// 2.注册组件
Vue.component('cpn1', {
template: `
<div>
<h2>你好吗</h2>
<p>你好嘛</p>
<p>你好么</p>
</div>`
})
// 根组件
const app = new Vue({
el: "#app",
data: {
},
methods: {
},
})
</script>
</body>
注意:
- 全局注册要写在创建Vue实例对象前面;
- 全局组件可以在vue实例绑定的dom节点下,直接写成自定义标签;
- 全局组件可以在其他组件中直接使用,不需要引入,也不需要注册!!!
局部组件
<body>
<div id="app">
<!-- 3、使用组件 -->
<cpn></cpn>
</div>
<script>
// 1、创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>早上好!</h2>
<p>中午好!</p>
<p>晚上好!</p>
</div>`
})
//根组件
const app = new Vue({
el: "#app",
data: {
},
methods: {
},
// 2、注册全局组件
components: {
// cpn使用组件时的标签名
cpn: cpnC
}
})
</script>
</body>
注意: 使用局部组件时,需要在components属性中注册才能使用!!!
如有误,请指正!