2.1 使用VueRouter
思路
一、确定页面url
- #/money记账
- #/labels标签
- #/statistics统计
- 默认进入#/money
- 添加一个404页面
添加代码
- router/index.ts添加router,配置4个路径对应组件
- 初始化组件
- 将router传给new Vue()
- 在App组件里用给出router渲染区域
//index.ts
import Vue from 'vue'
import VueRouter from 'vue-router'
import Money from '@/views/Money.vue'
import Labels from '@/views/Labels.vue';
import Statistics from '@/views/Statistics.vue';
import NotFound from '@/views/NotFound.vue';
const routes = [
{
path: '/',
redirect: '/money'
},
{
path: '/money',
component: Money
},
{
path: '/labels',
component: Labels
},
{
path: '/statistics',
component: Statistics
},
{
path: '*',
component: NotFound
}
]
const router = new VueRouter({
routes
})
初始化
//main.ts
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
//App.vue
<template>
<div>
<router-view />
</div>
</template>
2.2 将Nav组件做成全局组件
导航栏
有的页面不需要引入这个Nav,不好添加和删除,有的页面不需要显示也隐藏不好,因此创建Nav.vue,将HTML放到组件里
//App.vue
<template>
<div>
<router-view />
<div>
<router-link to="/money">记账</router-link>
<router-link to="/labels" >标签 </router-link>
<router-link to="/statistics">统计</router-link>
</div>
</div>
</template>
首先三个导航按钮写入到App.vue中,
但是有些页面不需要三个导航按钮呢.比如404页面
需要将这三个导航按钮抽象成一个Nav组件, 这样直接给Money.vue, Labels.vue和Statistics.vue引用
然后发现相同的代码引用了3次, 为啥不直接全局引用到main.ts中呢
2.3 VueRouter 404页面
//路由没有已知的页面, 就跳转到404
//index.ts
import NotFound from '@/views/NotFound.vue';
const routes = [
......
{
path: '*',
component: NotFound
}
]
2.4 用Fixed还是Flex布局
千万别在手机上用Fixed
加scoped后, 对应的class地方的标签出会出现data-v-xxxxx,\
自动会在写该class的时候加上该部分(属性选择器)
只要能加scoped的地方都需要加, App.vue除外
复制3次就是bug
2.5 Layout组件 & slot插槽 - 我与重复不共戴天
继续简化封装
通过vue里的</slot> 。
创建Layout.vue 来简化Money.vue,labels.vue,statistics.vue里相同部分的代码(div布局和css代码)
2.6 使用svg-sprite-loader引入icon
//在终端上安装svg-sprite-loader
yarn add svg-sprite-loader -D
因为github上没有vue配置, 需要将webpack转一下.
在iconfont网站上找icon
//vue.config.js
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path')
module.exports = {
lintOnSave: false,
chainWebpack: config => {
const dir = path.resolve(__dirname, 'src/assets/icons')
// 配置svg-sprite-loader
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')
// eslint-disable-next-line @typescript-eslint/no-var-requires
.use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
config.module.rule('svg').exclude.add(dir) // 其他 svg loader 排除 icons 目录
}
}
2.7 eslint 报错如何解决
2.8 如何 import 一个目录
//解决svg整个引入,不需要一个一个引入
// import svg 文件夹
const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
try {
importAll(require.context('../assets/icons', true, /\.svg$/));
} catch (error) {
console.log(error);
}
2.9 封装 icon 组件
//因为<svg></svg>重复了三次,所以封装了
//Icon.vue
<style lang="scss" scoped>
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
2.10 添加导航栏CSS样式
<router-link>不是一个标签
用阴影的标准: 不能让别人看出用阴影
能不写高度就不要写高度
2.11 active-class的使用(路由激活)
active-class="selected" 主要作用是用来实现选中样式的切换
<router-link to="/money" class="item" active-class="selected">
<Icon name="money" />
记账
</router-link>
// active-class="selected"
nav {
> .item.selected {
color: $color-highlight;
}
}
//通过css,点击它时会变红
2.12 更新 meta viewport
//更新index.html
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">