文章目录
  1. 1. 父子组件通信
    1. 1.1. 使用Props传递数据
    2. 1.2. 使用自定义事件
    3. 1.3. 子组件索引
    4. 1.4. 非父子组件通信
  2. 2. 添加Sidebar组件展开收起事件
    1. 2.1. 添加状态记录展开或收起状态
    2. 2.2. 添加方法控制展开收起
    3. 2.3. 添加点击事件
  3. 3. 添加Top组件
    1. 3.1. 创建组件
    2. 3.2. 添加模板
    3. 3.3. 添加点击事件
  4. 4. App父组件处理事件
    1. 4.1. 注入Top组件并引入
    2. 4.2. 模板中使用Top组件
    3. 4.3. 添加方法处理SidebarToggleClick事件
    4. 4.4. 页面最终效果
    5. 4.5. 参考
  5. 5. 结束语

最近在使用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()
// 触发组件 A 中的事件
bus.$emit('id-selected', 1)
// 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
// ...
})

在更多复杂的情况下,你应该考虑使用专门的状态管理模式

添加Sidebar组件展开收起事件


首先我们在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) {
// 当菜单有href属性时,代表其将进行路由跳转而不是展开收起子菜单
// 此时将其余菜单收起
if (menu.href) {
this.$router.push(menu.href);
this.menus.forEach(item => {
item.class = '';
});
// 设置active时需判断当前状态,进行展开和收起的状态区分
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` 对象中定义方法
methods: {
toggleMenu(menu) {
// 当菜单有href属性时,代表其将进行路由跳转而不是展开收起子菜单
// 此时将其余菜单收起
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>
<!-- top navigation -->
<div class="top_nav">
<div class="nav_menu">
<nav>
<div class="nav toggle">
<!--这里添加点击事件,用来触发Sidebar的展开和收起-->
<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>
<!-- /top navigation -->
</template>

添加点击事件

1
2
3
4
5
6
7
8
9
export default {
methods: {
// 点击事件
sidebarToggleClick() {
// 使用$emit触发自定义事件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 ref="sidebar"></Sidebar>
<!--使用Top组件,且绑定监听子组件SidebarToggleClick事件-->
<Top v-on:SidebarToggleClick="transSidebarToggle"></Top>

添加方法处理SidebarToggleClick事件

在App组件中添加方法,绑定SidebarToggleClick事件。

1
2
3
4
5
6
7
methods: {
// 添加方法绑定SidebarToggleClick事件
// 这里我们直接通过ref索引获取调用Sidebar子组件的toggleMenuShowAll方法
transSidebarToggle() {
this.$refs.sidebar.toggleMenuShowAll();
}
}

页面最终效果

image

参考

Vue2.0中文文档

结束语


当然,父子组件间通信有很多实现方法。大家感兴趣的当然也可以尝试用中央事件总线或者是状态管理来实现啦。
此处查看项目代码
此处查看页面效果

查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢

码生艰难,写文不易,给我家猪囤点猫粮了喵~

作者:被删

出处:https://godbasin.github.io

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

文章目录
  1. 1. 父子组件通信
    1. 1.1. 使用Props传递数据
    2. 1.2. 使用自定义事件
    3. 1.3. 子组件索引
    4. 1.4. 非父子组件通信
  2. 2. 添加Sidebar组件展开收起事件
    1. 2.1. 添加状态记录展开或收起状态
    2. 2.2. 添加方法控制展开收起
    3. 2.3. 添加点击事件
  3. 3. 添加Top组件
    1. 3.1. 创建组件
    2. 3.2. 添加模板
    3. 3.3. 添加点击事件
  4. 4. App父组件处理事件
    1. 4.1. 注入Top组件并引入
    2. 4.2. 模板中使用Top组件
    3. 4.3. 添加方法处理SidebarToggleClick事件
    4. 4.4. 页面最终效果
    5. 4.5. 参考
  5. 5. 结束语