组件注意事项
1.组件里面的data 必须是一个函数 这个函数必须要return
2.组件里面的template 只能由1个根元素
3.件的使用:如果定义的时,是大写驼峰,那么使用的时候把驼峰拆成,加短横线的写法
4.组件有的版本可以嵌套,有的不可以
定义组件
1.全局组件
<div id="app">
<com1></com1>
</div>
// 全局组件
<script>
//Vue.component('组件名','组件')
Vue.component('mycom', {
template: `<div><h1>我是一个全局组件</h1></div>`,
methods:{
},
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
</script>
- 局部组件
局部组件需要挂载到一个Vue实例中,如代码第18行
<div id="app">
<com1></com1>
</div>
// 局部组件
<script>
var mycom = {
template: `<div><h1>我是一个局部组件</h1></div>`,
methods:{
},
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
components:{
mycom //es6写法
}
});
</script>
组件的data
必须写成data函数形式,返回值必须是一个对象。
<div id="app">
<com1></com1>
</div>
<script>
Vue.component('com1',{
data() {
return {msg:'msg',num:0}
},
template:'<div><h1>{{msg}}</h1></div>'
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
</script>
组件模板拆开来写
将组件模板从组件中抽离出来,用id
绑定对应的模板
<div id="app">
<com1></com1>
</div>
<template id='com1'>
<div>
<h1>{{msg}}</h1>
</div>
</template>
<script>
Vue.component('com1',{
data() {
return {msg:'com1'}
},
template:'#com1'
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
</script>
组件嵌套
局部组件可以嵌套全局组件,但是全局组件不能嵌套局部组件,在jubu1的模板中实现了嵌套,如代码第17行
<div id="app">
<!-- 局部组件嵌套全局组件 可以 -->
<jubu1></jubu1>
</div>
<script>
Vue.component('quanju',{
data() {
return {msg:'全局组件'}
},
template:`<h1>{{msg}}</h1>`
})
var jubu1 = {
data() {
return {msg:'局部组件'}
},
template:`<h2>{{msg}}<quanju></quanju></h2>`
}
var vm = new Vue({
el: '#app',
components:{
jubu1,
}
});
</script>
父组件向子组件传值
1.我们知道,每一个组件都是一个Vue实例对象,所以这里的父组件向子组件传值时,父组件时vm实例,子组件是com1。
2.主要是通过属性绑定
的方式,如代码第2行,给局部组件com1动态绑定val属性,传入vm实例中的数据father。
3.在子组件中用props
数组接受一下自定义属性val,就可以作为一个变量在局部组件中使用了。
<div id="app">
<com1 :val='father'></com1>
</div>
<template id='com1'>
<div>
<h1>{{msg}}</h1>
<h2>{{val}}</h2>
</div>
</template>
<script>
var com1 = {
props:['val'],
data() {
return {
msg:'com1',
}
},
template:'#com1'
}
var vm = new Vue({
el: '#app',
data: {
father:'我是父组件的值,我要传给子组件'
},
components:{
com1,
}
});
</script>
子组件向父组件传值
子组件向父组件传值(本质上:是向父组件传递的一个自定义的方法 顺便把值带过去)
<div id="app">
<h1>{{rval}}</h1>
<com1 @receive-from-son='receive'></com1>
</div>
<template id='com1'>
<div>
<h1>{{msg}}</h1>
<button @click='tofather'>点我传值给父组件</button>
</div>
</template>
<script>
var com1 = {
data() {
return {
msg:'com1',
val:'我是子组件的值,我想传给父组件'
}
},
methods:{
tofather() {
// this.$emit() 固定写法
// this.$emit('第一个参数自定义方法名','第二个参数需要传递的值')
//这叫子组件向父组件发送自定义方法
this.$emit('receive-from-son',this.val)
}
},
template:'#com1'
}
var vm = new Vue({
el: '#app',
data: {
rval:''
},
methods: {
receive(val) {
this.rval= val;
}
},
components:{
com1,
}
});
</script>
单向数据流
在vue中,允许父子组件之间传值,但是父亲传给子组件的值是不允许子组件修改的,这样能保证数据的安全性。
这里定义一个变量:
this.changef
,用mounted钩子函数一开始自动执行第25行代码,将父组件的值复制了一份
,在第20行修改的其实是this.changef的值,单向数据流依然存在,只不过,我们点击看起来好像父组件的值被修改了一样。
<div id="app">
<com :fmsg='fathermsg'></com>
</div>
<script>
var com = {
props:['fmsg'],
data() {
return {
msg:'com',
changef:''
}
},
methods:{
// 不允许轻易修改父组件传过来的值
// changef() {
// this.fmsg='哈哈哈哈'
// }
changefather() {
this.changef='哈哈哈我改了父组件的值了'
}
},
// 利用changef中间变量接一下,改的是changef
mounted(){
this.changef=this.fmsg
},
template:`
<div>
<h1>{{fmsg}}</h1>
<h1>{{changef}}</h1>
<button @click='changefather'>点我修改子组件传给父组件的值</button>
</div>`
}
var vm = new Vue({
el: '#app',
data: {
fathermsg:'我是父组件的值,我要传给子组件,不要随便修改我的值哦'
},
components:{
com
}
});
</script>
兄弟组件之间传值
用到事件总线的思想,eventBus.$emit()
,将要传的值发送到事件总线上,通过eventBus.$on()
从事件总线上获取值。核心代码:第22行,第32行,第46行。
<div id="app">
<com1></com1>
<com2></com2>
</div>
<template id="com1">
<div>
<h1>{{msg}}</h1>
<button @click='tocom2'>点我向com2传值</button>
</div>
</template>
<template id="com2">
<div>
<h1>{{msg}}</h1>
<h2>{{mycom2}}</h2>
<button >点我向com1传值</button>
</div>
</template>
<script>
// 事件总线
var eventBus = new Vue() ;
var com1 = {
data() {
return {
msg:'我是组件1',
msg1:'我是com1传过来的值',
}
},
methods:{
tocom2() {
eventBus.$emit("mycom1",this.msg1)
}
},
template:'#com1'
}
var com2 = {
data() {
return {
msg:'我是组件2',
msg2:'我是com2传过来的值',
mycom2:''
}
},
mounted() {
eventBus.$on("mycom1",(val)=> {
this.mycom2=val;
})
},
template:'#com2',
}
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
components:{
com1,
com2
}
});
</script>