1. 最佳实践

1.1. 项⽬配置

  • npm run eject
  • vue.config.js

做⼀些基础配置:指定应⽤上下⽂、端⼝号、主⻚ title

// vue.config.js
const port = 7070;
const title = 'vue in practice';

module.exports = {
  publicPath: '/best-practice', // 部署应⽤包时的基本 URL
  devServer: {
    port
  },
  configureWebpack: {
    // 向index.html注⼊标题
    name: title
  }
};

// index.html
<title><%= webpackConfig.name %></title>

1.1.1. 链式操作:演示 webpack 规则配置,custom icon

范例:项⽬要使⽤ icon,传统⽅案是图标字体(字体⽂件+样式⽂件),不便维护;svg ⽅案采⽤ svgsprite-loader ⾃动加载打包,⽅便维护。

使⽤ icon 前先安装依赖:svg-sprite-loader

npm i svg-sprite-loader -D
vue inspect -h
Usage: inspect [options] [paths...]

inspect the webpack config in a project with vue-cli-service

Options:
  --mode <mode>
  --rule <ruleName>      inspect a specific module rule
  --plugin <pluginName>  inspect a specific plugin
  --rules                list all module rule names
  --plugins              list all plugin names
  -v --verbose           Show full function definitions in output
  -h, --help             output usage information

复制图标 svg code,存⼊ src/icons/svg 中。修改规则和新增规则:

vue.config.js

  chainWebpack(config) {
    // 配置svg规则排除icons⽬录中svg⽂件处理
    config.module.rule('svg').exclude.add(resolve('src/icons'));

    // 新增icons规则,设置svg-sprite-loader处理icons⽬录中的svg
    config.module
      .rule('icons') //新增icons规则
      .test(/\.svg$/) //匹配后缀
      .include.add(resolve('src/icons')) //加入include array
      .end() //add完上下⽂是数组不是icons规则,使⽤end()回退
      .use('svg-sprite-loader') // 添加loader
      .loader('svg-sprite-loader') // 切换上下文到loader
      .options({ symbolId: 'icon-[name]' }) //指定选项
      .end();
  }

检查配置:

vue inspect --rule svg

/* config.module.rule('svg') */
{
  test: /\.(svg)(\?.*)?$/,
  exclude: [
    '/Users/guanghuiw/My/kaikaba/vue-learning/src/icons'
  ],
  use: [
    {
      loader: 'file-loader',
      options: {
        name: 'img/[name].[hash:8].[ext]'
      }
    }
  ]
}

图标⾃动导⼊

/* 图标自动导入, note main.js needs import './icons'; */
import Vue from 'vue';
import Icon from '@/components/Icon.vue';

// 利用webpack 的require.context自动导入
const req = require.context('./svg', false, /\.svg$/); // 遍历加载上下⽂中所有项

// 返回的req是只去加载svg目录中的模块的函数
req.keys().map(req);
// console.log(req.keys()); // ["./qq.svg", "./wechat.svg"]

// Icon组件全局注册一下
Vue.component('Icon', Icon);

创建 Icon 组件:

<!-- ./components/Icon.vue -->
<template>
  <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script>
export default {
  name: 'Icon',
  props: {
    name: {
      type: String,
      required: true,
    },
    className: {
      type: String,
      default: '',
    },
  },
  computed: {
    iconName() {
      return `#icon-${this.name}`;
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className;
      } else {
        return 'svg-icon';
      }
    },
  },
};
</script>

<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

注册:

// icons/index.js
/* 图标自动导入, note main.js needs import './icons'; */
import Vue from 'vue';
import Icon from '@/components/Icon.vue';

// Icon组件全局注册一下
Vue.component('Icon', Icon);

// main.js
import './icons';

使⽤:

<!-- App.vue -->
<Icon name="qq" class-name="my-icon"></Icon> <Icon name="wechat" class-name="my-icon"></Icon>
Copyright © Guanghui Wang all right reserved,powered by GitbookFile Modified: 2019-08-25 13:56:34

results matching ""

    No results matching ""