2记账 Vue 项目-Vue 导航栏

167 阅读1分钟

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引用

image.png

然后发现相同的代码引用了3次, 为啥不直接全局引用到main.ts中呢

image.png

image.png

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代码)

image.png

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">