Nav.vue 底部导航栏的封装
1.svg的使用(使用svg-sprite-loader)
- iconfont.con下载svg
- shims-tsx.d.ts中添加
1
2
3
4
|
declare module '*.svg' {
const content: string;
export default content
}
|
- 安装 svg-sprite-loader(命令行输入)
1
2
|
yarn add svg-sprite-loader -D
yarn add svgo-loader
|
- 在vue.config.js里面添加,启用两个loder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
module.exports = {
lintOnSave: false,
chainWebpack: config => {
const dir = path.resolve(__dirname, 'src/assets/icons')
config.module
.rule('svg-sprite')
.test(/\.svg$/)
.include.add(dir).end() //包含icons目录
.use('svg-sprite-loader').loader('svg-sprite-loader').options({ extract: false }).end()
config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{ plainSprite: true }])
config.module.rule('svg').exclude.add(dir) //其他svg loader排除icons
}
}
|
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
|
<template>
<svg class="icon">
<use :xlink:href="'#'+name" />
</svg>
</template>
<script lang="ts">
// 引入整个icons
const importAll = (requireContext: __WebpackModuleApi.RequireContext) =>
requireContext.keys().forEach(requireContext);
try {
importAll(require.context("../../assets/icons", true, /\.svg$/));
} catch (error) {
console.log(error);
}
export default {
name: "Icon",
props: ["name"]
};
</script>
<style lang="scss" scoped>
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
|
1
2
|
import Icon from '@/components/Icon.vue'
Vue.component('Icon', Icon)
|
2.封装nav.vue,通过url判断路由是否活跃以显示不同的icon(使用v-show显示)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<script lang='ts'>
import Vue from "vue";
import { Component } from "vue-property-decorator";
@Component
export default class Nav extends Vue {
get moneyIsActive() {
return this.$route.path.indexOf("money") !== -1;
}
get statisticsIsActive() {
return this.$route.path.indexOf("statistics") !== -1;
}
}
</script>
|
Layout.vue的封装
- 使Nav居于页面下方的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<template>
<div class="layout-wrapper">
<div class="content">
<slot />
</div>
<Nav class="nav" />
</div>
</template>
<style lang='scss' scoped>
.layout-wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
> .content {
overflow: auto;
flex: 1;
}
}
</style>
|
TabBar的封装
- 获得选中状态(添加 class selected)
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
|
<template>
<div class="tab-bar">
<div class="icon">
<slot name="icon" />
</div>
<span class="expend" :class="{'selected':type==='-'}" @click="selectType('-')">支出</span>
<span class="income" :class="{'selected':type==='+'}" @click="selectType('+')">收入</span>
<div class="delete">
<slot name="delete" />
</div>
</div>
</template>
<script lang='ts'>
import Vue from "vue";
import { Component } from "vue-property-decorator";
@Component
export default class extends Vue {
type: string = "-";
selectType(type: string) {
this.type = type;
this.$emit("selectType", type);
}
}
</script>
|
- slot插槽添加可能的Icon,并使它绝对定位
1
2
3
4
5
6
7
8
9
|
<div class="icon">
<slot />
</div>
.icon {
position: absolute;
top: 50%;
margin-top: -9px;
}
|