JavaWEB笔记18 Vue组件
一.组件的介绍:
- 组件:组件式开发:把页面中每一块看成一个单独的某个部分,用户自己进行组装
- 组件化思想:标准,分治,重用,组合
- Vue在设计时实现了部分的组件式开发
定义组件:全局组件和局部组件:
- 定义一个全局组件:
Vue.component('命名',{template: <div...>}) //组件的模板
在上面的页面中进行组件使用时:<命名></命名>
的格式
- 1)组件的数据是一个函数,与位置template并列:
data:function(){ }
,其中return返回这个数据可以是json格式,与之前new Vue时data中写法相同,注意模板template中的标签中的innerText通过包装{{msg}}的形式,但不能进行换行解析 - 2)组件的模板必须有一个根标签:等于说最外层要有一个包裹的标签
- 3)组件中的数据是隔离的:组件被使用多次,数据各是各的,互不影响
- 全局组件的好处在于在全部的Vue实例中都可以使用
- 定义一个局部组件:
在对应new Vue的实例对象中选择
components:{ 组件名:{ template:`组件标签` } }
上述代码位置与methods位置并列,一般来说不定义全局组件,定义局部组件比较灵活,同时在组件的定义中比较灵活,可以在子组件内部继续定义子组件,注意只有根组件有el,子组件有template
代码示例:定义全局组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- 引入vue.js 库文件 -->
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<template id="sb">
<div>
<div id="" style="height: 200px;width: 200px;background: red;">,
<button type="button">一个按钮</button>
{{sonmsg}}
</div><button type="button" @click="add">一个按钮{{num}}</button>
</div>
</template>
<div id="box">
<!-- 使用组件
注意当点击按钮时,每个组件都会各自独立维护它的 count。因为你每用一次组件,就会有一个它的新实例被创建。
-->
<my-component></my-component>
<my-component></my-component>
</div>
</body>
<script type="text/javascript">
//定义全局组件
/* 因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。 */
Vue.component('my-component', {
//注意:组件的数据,是一个函数
data: function() {
return {
sonmsg: '我是子组件的数据',
num: 1
}
},
methods: {
add: function() {
this.num += 1;
}
},
//组件的模板,必须外面有一个根标签
template:'#sb'
})
//根组件
new Vue({
el: '#box',
data: {
msg: 'Hello'
}
})
</script>
</html>
代码示例:定义局部组件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- 引入vue.js 库文件 -->
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="box">
<my-son></my-son>
<my-son2></my-son2>
</div>
</body>
<script type="text/javascript">
new Vue({
el: '#box',
data: {
msg: 'Hello'
},
components:{
'my-son':{
data:function(){
return {
mydata:"hehehhehehe"
}
},
template:`<div>
<h1>
{{mydata}}
<mysonson></mysonson>
</h1>
</div>`,
components:{
'mysonson':{
template:`<div><h1>我是子组件的子组件</h1></div>`
}
}
},
'my-son2':{
data:function(){
return {
mydata:"hehehhehehe222222222222222222"
}
},
template:`<div><h1>{{mydata}}</h1></div>`
}
}
})
</script>
</html>
二.父组件与子组件之间的数据互传:
1)父组件向子组件传递数据:
props:[ ]
数组格式:获取父组件传递过来的数据- 在上面myson标签中对于属性的控制写的格式是:
:键="值"
的形式 - 不要不写前面的冒号,这样会写死值
- 但是在传递的过程中要选取对应的值进行灵活传递
- 代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- 引入vue.js 库文件 -->
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 可以把组件的模板代码放到这个标签里面 -->
<template id="son">
<div>
<h1>子组件{{hehe}}</h1>
<h1>{{num}}</h1>
<h1>{{arr[0]}}</h1>
<h1>{{obj.name}}</h1>
</div>
</template>
<div id="box">
<my-son :hehe="msg" :num="num" :arr='arr' :obj="fujson"></my-son>
</div>
</body>
<script type="text/javascript">
var sonObj =
new Vue({
el: '#box',
data: {
msg: 'Hello',
num: 100,
arr: [10, 20, 30],
fujson: {
'name': 'zhangsan',
'age': 18
}
},
//定义局部组件
components: {
'my-son': {
//组件的数据是个函数
data: function() {
return {
sonmsg: '子组件的数据'
}
},
props: ['hehe', 'num', 'arr', 'obj'], //获取父组件传递过来的数据
template: '#son'
}
}
})
</script>
</html>
2)子组件向父组件传递数据:
- 通过自定义事件传数据:
this.$emit(‘’)
- 两种方式:写括号和不写括号:
<!-- jieshouData($event) 写上括号,括号里面写上$event -->
<son @senddata='jieshouData($event)'></son>
<!--不写括号 -->
<son @senddata='jieshouData'></son>
触发自定义事件,传递数据,如果有多个零碎数据,封装成json对象,把json对象传递过去
this.$emit('senddata', this.sonmsg)
- 代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- 引入vue.js 库文件 -->
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<template id="son">
<div>
<h1>我是子组件</h1>
<button type="button" @click="send()">把子组件的数据传递给父组件</button>
</div>
</template>
<div id="box">
{{msg}}
<!-- jieshouData($event) 写上括号,括号里面写上$event -->
<son @senddata='jieshouData($event)'></son>
<!--不写括号 -->
<son @senddata='jieshouData'></son>
</div>
</body>
<script type="text/javascript">
new Vue({
el: '#box',
data: {
msg: 'Hello'
},
methods: {
jieshouData(value) {
//alert(value);
this.msg=value;
}
},
//定义局部组件
components: {
'son': {
template: '#son',
data: function() {
return {
sonmsg: '我是子组件的数据',
num:100
}
},
//钩子函数
mounted:function(){
this.$emit('senddata', this.sonmsg)
},
methods: {
send() {
//alert("发送数据")
//触发自定义事件,传递数据,如果有多个零碎数据,封装成json对象,把json对象传递过去
this.$emit('senddata', this.sonmsg)
}
}
}
}
})
</script>
</html>
注意:可以把组件的模板代码拿出来:要下上括号
放在上面对应的标签中:<template id="son">
在下面引用时选用:template:'#son'
三.兄弟组件之间传数据:
- 借助事件中心(new一个Vue)进行两组件的数据传递
- 在生命周期函数里面:mounted中绑定监听事件:
hub.$on('event-name',(val形参)=>{ 传递数据监听事件 })
触发组件监听的事件:hub.$emit('event-name',(val)=>{})
- 组件的触发事件在methods中,触发事件是另一个组件的监听事件,也就是说A组件监听为
addA
,B组件监听为addB
,在A触发B有hub.$emit('addB',(val)=>{ })
- 销毁两个组件之间的自定义事件:父组件中使用
hub.$off('event-name')
进行销毁 - 代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="box">
<aaa></aaa>
<bbb></bbb>
<button type="button" @click="xiaohui()">销毁事件</button>
</div>
<script type="text/javascript">
//1.创建事件中心
var hub = new Vue();
Vue.component('aaa', {
data: function() {
return {
anum: 0
}
},
template: `<div>
<h1>A组件</h1>
<h1>{{anum}}</h1>
<button v-on:click='add()'>给B组件传递数据</button>
</div>`,
methods: {
add() {
//alert("给B传递数据")
//触发B组件监听的事件,并传递值给B组件
hub.$emit('addBBB',2);
}
},
//在生命周期函数里面,监听事件
mounted: function() {
//监听事件 val就是兄弟组件传递过来的数据
hub.$on('addAAA', (val) => {
this.anum += val
})
}
})
Vue.component('bbb', {
data: function() {
return {
bnum: 0
}
},
template: `<div>
<h1>B组件</h1>
<h1>{{bnum}}</h1>
<button v-on:click='add()'>给A组件传递数据</button>
</div>`,
methods: {
add() {
//alert("给A传递数据")
hub.$emit('addAAA',3)
}
},
mounted: function() {
//监听被对方触发事件 val就是兄弟组件传递过来的数据
hub.$on('addBBB', (val) => {
this.bnum += val
})
}
})
new Vue({
el: '#box',
data: {
msg: 'Hello'
},
methods:{
xiaohui(){
hub.$off('addAAA');
hub.$off('addBBB');
}
}
})
</script>
</body>
</html>