最近在用
Vuetify
练手做个博客,vue
是真香,不过许多概念还需要慢慢消化下~记录一下这次遇到的需求和解决方法
需求描述
博客设计的管理后台如下图所示:
照着Vuetify
文档中的例子写出来这样的一个界面并不难,代码看结构就行了:
<v-content>
里面使用<router-view>
来显示子路由中的视图,主要框架介绍完毕.现在遇到的问题是:
想要在切换到不同的路由视图时动态修改父模块中面包屑里面的内容
再啰嗦描述一下期望效果:
点击左侧菜单"文章管理"时,顶部的面包屑可以显示内容首页/文章管理
,已经切换到"文章管理"页面状态下点击加号按钮,顶部面包屑显示内容首页/文章管理/添加文章
,诸如此类~’
实现方法
由于vue中对数据流的单向控制,所以子模块(路由视图中的模块)是不能直接修改父模块中的数据的,这里在父模块的面包屑控件中绑定了其显示的数据:
<v-breadcrumbs :items="bread" large></v-breadcrumbs>
data () {
return {
bread: [
{ text: '首页', href: '#/admin' },
],
}
},
<router-view>
中的视图模块需要使用$emit
函数的方式来触发父模块中的事件实现修改父模块中数据的效果,可以再父模块中的<router-view>
中绑定一个自定义的事件change_bread
,并创建相应的响应函数change_bread()
(这个响应函数的名称不一定非要和事件名一致的,方便好识别就行),需要注意的是响应函数中需要调用的参数是vue内置变量$event
,也就是从视图模块中使用$emit
触发事件时传入的变量.
<router-view @change_bread="change_bread($event)"></router-view>
methods: {
change_bread (e) {
this.bread = e
},
},
视图模块中在mount()
生命周期过程中使用$emit
触发父模块中的change_bread
事件修改面包屑绑定的数据
mounted () {
this.$emit('change_bread',
[
{ text: '首页', href: '#/admin' },
{ text: '文章管理' },
],
)
},
完整代码
父模块Index.vue
<template>
<v-app id="admin">
<v-navigation-drawer color="primary" absolute dark app>
<v-list dense nav class="py-0">
<v-list-item two-line>
<v-list-item-content>
<h1>管理后台</h1>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list-item
v-for="item in items"
:key="item.title"
:href="item.href"
link
>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar app color="white">
<v-label>当前位置:</v-label>
<v-breadcrumbs :items="bread" large></v-breadcrumbs>
</v-app-bar>
<v-content>
<router-view @change_bread="change_bread($event)"></router-view>
</v-content>
</v-app>
</template>
<script>
export default {
name: 'Index',
data () {
return {
items: [
{ title: '首页', icon: 'mdi-home', href: '#/admin/' },
{ title: '文章管理', icon: 'mdi-playlist-edit', href: '#/admin/article' },
{ title: '栏目管理', icon: 'mdi-view-carousel', href: '#/admin/category' },
],
bread: [
{ text: '首页', href: '#/admin' },
],
}
},
methods: {
change_bread (e) {
this.bread = e
},
},
}
</script>
<style scoped>
</style>
视图模块Article.vue
<template>
<v-container id="article">
<v-row>
<v-btn fab color="primary" href="#/admin/article_add">
<v-icon>fa-plus</v-icon>
</v-btn>
</v-row>
<v-row>
<v-col cols="12">
<v-data-table :headers="headers" :items="articles">
<template v-slot:item.actions="{item}">
<v-btn small @click="edit(item)" color="primary">
编辑
</v-btn>
<v-btn small @click="remove(item)" color="error">
删除
</v-btn>
</template>
</v-data-table>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
name: 'Article',
data () {
return {
headers: [
{ text: '编号', value: 'id' },
{ text: '标题', value: 'title' },
{ text: '栏目', value: 'category' },
{ text: '创建时间', value: 'create_date' },
{ text: '浏览次数', value: 'views' },
{ text: '点赞数量', value: 'rates' },
{ text: '操作', value: 'actions', sortable: false },
],
articles: [],
}
},
methods: {
init_table () {
this.$http.get('article/get_all').then(res => {
this.articles = res.data.data
})
},
edit (item) {
console.log(item)
this.$router.push({
name: 'edit_article',
params: { art: item },
})
},
remove (item) {
console.log(item)
},
},
mounted () {
this.init_table()
this.$emit('change_bread',
[
{ text: '首页', href: '#/admin' },
{ text: '文章管理' },
],
)
},
}
</script>
<style scoped>
</style>