# 导航栏页面布局

# scoped

Vue scoped: 当 <style> 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素

<https://vue-loader-v14.vuejs.org/zh-cn/features/scoped-css.html>

# Money.vue 布局
<template>
  <div class="nav-wrapper">
    <div class="content">
      Money
    </div>
    <Nav/>
  </div>
</template>

<style lang="scss" scoped>
 .nav-wrapper{
   border: 1px solid green;
   display: flex;
   flex-direction: column;
   height: 100vh;
 }
  .content{
    flex-grow: 1;
    overflow: auto;
  }
</style>

Labels 布局、 Statistics 布局同 Money 布局

# 封装Layout组件

将重复代码封装成组件,需要时调用

<template>
  <div class="nav-wrapper">
    <div class="content">
      <slot/>
    </div>
    <Nav/>
  </div>
</template>

<script lang="ts">
  export default{
    name:'Layout'
  }
</script>

<style lang="scss" scoped>
  .nav-wrapper{
    border: 1px solid green;
    display: flex;
    flex-direction: column;
    height: 100vh;
  }
  .content{
    flex-grow: 1;
    overflow: auto;
  }
</style>

Vue 插槽 : <slot></slot> 当组件渲染的时候,<slot></slot> 将会被指定内容

<https://cn.vuejs.org/v2/guide/components-slots.html#ad>

<template>
  <div>
    <Layout>
      Money
    </Layout>
  </div>
</template>

# 引入 icon

创建icons目录 存放 iconfont.cn 下载的图片@/assets/icons/'

import x from '@/assets/icons/label.svg';

label.vue 导入icon 报错解决方案: `Can't found module '@/assets/icons/label.svg' or its corresponding type declarations

// 在 shims-vue.ts 文件添加
declare module "*.svg"{
  const content: string;
  export default content;
}

安装 svg-sprite-loader

 yarn add svg-sprite-loader -D

Eslint 报错解决方案:

eslint require statement not part of import statement
// you can disable this check in eslintrc.js file
module.exports = {
  ...
  rules: {
    ...
    '@typescript-eslint/no-var-requires': 0,
  }
}

import icons整个目录

  const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  try{importAll(require.context('../assets/icons',true,/\.svg$/));
  }catch (error) {
    console.log(error);
  }

# 引用icon

<template>
  <div class="nav">
    <router-link to="/labels">
      <svg>
        <use xlink:href="#label"></use>
      </svg>
      标签
    </router-link>|
    <router-link to="/money">
      <svg>
        <use xlink:href="#money"></use>
      </svg>
      记账
    </router-link>|
    <router-link to="statistics">
      <svg>
        <use xlink:href="#statistics"></use>
      </svg>
      统计
    </router-link>
  </div>
</template>

# 封装Icon

<template>
  <svg class="icon">
    <use :xlink:href="'#'+ name"></use>
  </svg>
</template>

<script lang="ts">

  const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  try{importAll(require.context('../assets/icons',true,/\.svg$/));
  }catch (error) {
    console.log(error);
  }

  export default{
    props:['name']  
  }
</script>

// 将Icon注册为全局组件
import Icon from '@/components/Icon.vue';
Vue.component('Icon',Icon);
// 引用组件
<template>
  <div class="nav">
    <router-link to="/labels">
      <Icon name="label"/>
      标签
    </router-link>|
    <router-link to="/money">
      <Icon name="money"/>
      记账
    </router-link>|
    <router-link to="statistics">
      <Icon name="statistics"/>
      统计
    </router-link>
  </div>
</template>

修改icon样式

  .icon{
    width:1em;height:1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow:hidden;
  }

# 添加Nav样式

<template>
  <nav>
    <router-link to="/labels" class="item" active-class="selected"> // active-class 路由激活 点击链接,链接高亮显示
      <Icon name="label"/>
      标签
    </router-link>|
    <router-link to="/money" class="item" active-class="selected">
      <Icon name="money"/>
      记账
    </router-link>|
    <router-link to="statistics" class="item" active-class="selected">
      <Icon name="statistics"/>
      统计
    </router-link>
  </nav>
</template>
  nav{
    display: flex;
    box-shadow: 0 0 3px rgba(0,0,0,0.25);
    flex-direction: row;
    font-size:12px;
    > .item{
      padding: 2px 0;
      width: 33.33333%;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      .icon{
        width: 32px;
        height: 32px;
      }
    }
    > .item.selected{
      color:red;
    }
  }

SVG图标设置CSS颜色不变解决方案: fill="color"

a. 下载时采用默认颜色
b. 查看svg源文件,删除 fill="yellow"
c. Vue.config.js配置文件(需安装svgo-loader)
  yarn add --dev svgo-loader
  config.module
  .use('svgo-loader').loader('svgo-loader')
  .tap(options=>({...options,plugins:[{removeAttrs:{attrs:'fill'}}]})).end()

svg-sprite-loader bug导致webstorm无法引入scss解决方案:(Bug已修复)

@import"~@/assets/style/helper.scss"; 
a.  Settings-->Webpack-->D:\resumeProject\ledger\node_modules\@vue
\cli-service\webpack.config.js
b.  安装 yarn add --dev svg-sprite-loader-mod
c. 修改Vue.config.js配置文件(需安装svgo-loader-mod)
.use('svg-sprite-loader-mod').loader('svg-sprite-loader-mod').options({extract:false}).end()