什么是组件呢?
1.简单的理解,UI层组件可以是一个按钮,可以是一个轮播图等等;逻辑方面,就是可复用的代码块;
2.更简单粗暴的理解,因为vue做的是单页应用,意味着只有一个HTML文件,那每一个页面其实就是组成这个HTML文件的一部分,而每个页面又是通过不同的部分组成;所以一个页面可以理解成一个大的组件,页面里的每一个部分,都是一个一个小组件;
什么是组件化开发和模块化开发呢?
1.模块化和组件化想要达成的目的都是一样的,组件化是包含了UI和页面逻辑处理在一起;而模块化只是将可以重复使用的逻辑代码提取成一个个模块,方便随时使用;
2.两者都是一种开发思想,为了更好的开发效率
怎么在vue中创建并注册一个组件呢?(暂时不包括模块开发)
1.在vue中全局创建组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
<script> Vue.component('btn',{ template:'<button @click="hint">clickme</button>', data(){ return{ name:'全局组件' } }, methods:{ hint:function(){ alert(this.name); } } }); </script> // 使用该组件 <btn></btn>
|
2.创建一个局部组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| // 注册后才能使用 <div id='app'> <btn></btn> </div>
<script> let btn={ template:'<button @click="hint">clickme</button>', data(){ return{ name:'局部组件' } }, methods:{ hint:function(){ alert(this.name); } } }; new Vue({ le:'#app', data:{ name:'组件练习' }, components:{ btn:btn } }) </script>
|
3.两种组件创建的区别:
- 全局组件不需要注册,可以直接使用,所以可以再任意的vue实例中使用;
- 局部组件需要在要使用它的vue实例里注册后,才能使用
什么是组件通信?
在每一个组件内部,都有一份属于该组件的data,页面显示的数据也依赖于此,我们也可以通过函数等来改变data中的数据
正因为每一个组件维护属于自己的data,所以在一个组件中想要使用其他组件的data数据就需要进行组件通信
组件通信有哪些类型呢?
1.父子组件之间传递
2.子父组件之间传递
3.兄弟组件之间传递
4.跨级组件之间传递
关于父子组件通信
1.在父组件中使用子组件时,在子组件上通过v-bind(缩写为 :)绑定要传递的数据
2.在子组件中,使用props来接受父组件传递过来的数据
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
<div id='app'>
<one v-bind:name='name'></one> </div> <script> let one={ template:'<div>{{name}}</div>', props:{ name:{ type:String} } }; new Vue({ le:'#app', data:{ name:'父组件' }, components:{ one:one } }) </script>
|
关于子父组件通信
1.子组件通过$emit监听一个自定义事件,传递数据给父组件
2.父组件通过v-on(缩写为@)监听该自定义事件,然后该事件会触发一个函数来获取子组件传递的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <div id="app"> {{name}} <one v-on:ok='get'></one> </div> <script>
let one={ template:'<div><button @click="start">click</button></div>', data(){ return{ name:'子组件' } }, methods:{ start:function(){ this.$emit('ok',this.name); } } } new Vue({ el:'#app', data:{ name:'parent' }, components:{ one }, methods:{ get:function(e){ this.name=e; } } }) </script>
|
使用全局事件管理中心进行跨级组件通信(父子,子父,跨级也可以用)
1.重新创建一个vue对象
2.在需要传递参数的组件内部通过$emit绑定触发一个自定义事件,并传递要传递的数据
3.在需要接受数据的组件通过$on绑定被emit触发的事件,然后在回调函数中接受传递过来的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <div id="app"> <one></one> <two></two> </div> <script>
let event=new Vue();
let one={ template:'<div>{{name}}<button @click="start">发送</button></div>', data(){ return{ name:'one' } }, methods:{ start(){ event.$emit('recive',this.name); } } } let two={ template:'<div>{{name}}</div>', data(){ return{ name:'two' } }, mounted(){ event.$on('recive',(data)=>{ this.name=data; }); } } new Vue({ el:'#app', data:{ name:'event' }, components:{ one, two } }) </script>
|
跨级组件(父组件和子孙组件)通信
假设父组件是A,子组件是B,孙子组件是C
1.A组件通过v-bind绑定要传递数据
2.在B中不使用props接收,而是在B组件中的C组件上通过v-bind=’$attrs’ 来转发A组件传递过来的数据
3.在C组件内部可以通过this.$attrs获取到A组件传递过来的数据(获取到的是对象格式)
tips:
- 在C组件中设置inheritAttrs: false;
- 这个属性是为了C组件在B中使用v-bind=’$attrs’时,该属性不会被当做HTML的属性渲染到页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <div id="app"> <one :name='name'></one> </div> <script> let two = { template: '<div>{{name}}</div>', data() { return { name: 'two' } }, mounted() { this.name = this.$attrs['name']; }, inheritAttrs: false,
} let one = { template: '<div>{{msg}} <two v-bind="$attrs"></two> </div>', data() { return { msg :'one' } }, components: { two } } new Vue({ el: '#app', data: { name: 'app' }, components: { one } }) </script>
|
使用provide(对象/函数内部返回一个对象)和inject(数组/字符数组格式)进行跨级通信
1.在父组件通过provide提供要所有子组件可继承的属性
2.所有的子组件都可以用inject来进行继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <div id="app"> {{name}} <one></one> </div> <script> let one = { template: '<div>{{msg}} </div>', data() { return { msg: 'one' } }, inject: ['name'], mounted() { console.log(this.name); this.msg = '继承的'+this.name; } } new Vue({ el: '#app', data: { name: 'app' }, provide() { this.name = this.name; return { name: this.name } }, components: { one } }) </script>
|
$parent和$childern和ref进行父子组件通信
获取子组件数据
- 在子组件绑定ref=’属性名’ 获取时通过this.$refs.属性名 获取到该组件实例
获取父组件
- this.$parent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <div id="app"> {{name}} <one ref='one'></one> </div> <script> let one = { template: '<div>one</div>', data() { return { name: 'one' } }, mounted(){ console.log(this.$parent.name); } } new Vue({ el: '#app', data: { name: 'app' }, components: { one }, mounted() { console.log(this.$refs.one.name); } }) </script>
|