By
被删
更新日期:
最近在使用Vue2作为项目中前端的框架,《Vue2使用笔记》系列用于记录过程中的一些使用和解决方法。
本文记录父子间组件的通信方法,以及添加Top组件的过程。
父子组件通信
使用Props传递数据
使用props传递数据,和vue1.x的使用方法一样。
- prop是父组件用来传递数据的一个自定义属性
- 子组件需要显式地用props选项声明“prop”
- 动态Props:用v-bind绑定动态props到父组件的数据。每当父组件的数据变化时,也会传导给子组件
使用自定义事件
上一篇我们简单提到了自定义事件,在vue1.x中,拥有$dispatch、$broadcast事件,这两个事件在vue2.x中被废弃,这里我们可以用到的事件有:
- 使用
$on(eventName)
监听事件
- 使用
$emit(eventName)
触发事件
子组件索引
有时需要在JavaScript中直接访问子组件,为此可以使用ref为子组件指定一个索引ID。
非父子组件通信
vue2.x中提供了一种方法来进行非父子组件间通信,即使用一个空的Vue实例作为中央事件总线:
1 2 3 4 5 6 7
| var bus = new Vue() bus.$emit('id-selected', 1) bus.$on('id-selected', function (id) { })
|
在更多复杂的情况下,你应该考虑使用专门的状态管理模式。
首先我们在Siderbar组件中进行以下修改。
添加状态记录展开或收起状态
在data中添加menuShowAll变量记录状态:
1 2 3 4 5 6
| data() { return { ... menuShowAll: true } }
|
添加方法控制展开收起
我们使用的是(gentelella模板)[https://github.com/puikinsh/gentelella],运行查看可知道,展开收起的控制主要由nav-md和nav-sm,以及active和active-sm来进行控制。
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
| methods: { toggleMenu(menu) { if (menu.href) { this.$router.push(menu.href); this.menus.forEach(item => { item.class = ''; }); menu.class = this.menuShowAll ? 'active' : 'active-sm'; return; } switch (menu.class) { case 'active': menu.class = ''; break; case '': menu.class = this.menuShowAll ? 'active' : 'active-sm'; } }, toggleMenuShowAll() { var $body = $('body'); this.menus.forEach(menu => { let c = menu.class; menu.class = c === 'active' ? 'active-sm' : (c === 'active-sm' ? 'active' : c) }) this.menuShowAll = !this.menuShowAll; $body.toggleClass('nav-md nav-sm'); } }
|
添加点击事件
从Html模板我们可以看到,点击菜单时的事件未toggleMenu,这里我们通过将其添加active的样式,并绑定v-show判断是否展示来实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| methods: { toggleMenu(menu) { if (menu.href) { this.$router.push(menu.href); this.menus.forEach(item => { item.class = ''; }); menu.class = 'active'; return; } switch (menu.class) { case 'active': menu.class = ''; break; case '': menu.class = 'active'; } } }
|
添加Top组件
添加Top组件用于点击触发展开收起事件
创建组件
我们在src/components文件夹里面创建Top.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 25 26
| <template> <div class="top_nav"> <div class="nav_menu"> <nav> <div class="nav toggle"> <a id="menu_toggle" v-on:click="sidebarToggleClick"><i class="fa fa-bars"></i></a> </div> <ul class="nav navbar-nav navbar-right"> <li class=""> <a href="javascript:;" class="user-profile dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> 用户 <span class=" fa fa-angle-down"></span> </a> <ul class="dropdown-menu dropdown-usermenu pull-right"> <li><a href="javascript:;">设置</a></li> <li><router-link to="/login"><i class="fa fa-sign-out pull-right"></i>退出</router-link></li> </ul> </li> </ul> </nav> </div> </div> </template>
|
添加点击事件
1 2 3 4 5 6 7 8 9
| export default { methods: { sidebarToggleClick() { this.$emit('SidebarToggleClick'); } } }
|
App父组件处理事件
注入Top组件并引入
1 2 3 4 5 6 7 8
| import Top from './components/Top' export default { ... components: { ... Top } }
|
模板中使用Top组件
在App模板中使用Top组件,这里我们还使用ref来获取Sidebar组件的事件。
1 2 3 4
| <Sidebar ref="sidebar"></Sidebar> <Top v-on:SidebarToggleClick="transSidebarToggle"></Top>
|
在App组件中添加方法,绑定SidebarToggleClick事件。
1 2 3 4 5 6 7
| methods: { transSidebarToggle() { this.$refs.sidebar.toggleMenuShowAll(); } }
|
页面最终效果
参考
Vue2.0中文文档
结束语
当然,父子组件间通信有很多实现方法。大家感兴趣的当然也可以尝试用中央事件总线或者是状态管理来实现啦。
此处查看项目代码
此处查看页面效果
查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢