Vue3 (5) Specification 1: Define interface template

There is no rule without rules, especially the setup writing method in the vue3 era. If the team members play at will, maintenance will be a disaster.
So the team interface template is defined here:

/**
* @name: index
* @author: weiyong
* @date: 2022-10-07 12:03
* @description:index
* @update: 2022-10-07 12:03
*/
<template>
  <div :class="prefixCls">
    界面内容
  </div>
</template>

<script lang="ts">
import {defineComponent} from 'vue';

export default defineComponent({
  components: {},
  name: "index",
});
</script>

<script lang="ts" setup>
import {useDesign} from "@/hooks/web/useDesign"; 
const {prefixCls} = useDesign('index');

</script>

<style type="text/css" lang="less">
@prefix-cls: ~'@{namespace}-index';
.@{prefix-cls} {
  background-color: #FFF;
}
</style>
  • First: The beginning part needs to explain the creator, creation time and other related information
  • Second: The top-level style is defined by prefixCls at the beginning of the interface, in order to solve side effects such as style repetition and conflicts
  • Third: prefixCls is generated by a prefix + splicing, and implemented by a hook. It is convenient to modify the prefix uniformly in the future.
  • Fourth: Uniformly adopt the setup writing method.
  • Fifth: Declare the name of the component through the defineComponent method. Generally, components do not need defineComponent to specify the name, but if dynamic component injection needs to specify the name, it must be used.
  • Sixth: Use less to process styles, scss is not recommended

The implementation of useDesign is very simple:


export function useDesign(scope: string) {
  const values = {prefixCls:'xm'}

  return {
    prefixCls: `${values.prefixCls}-${scope}`,
    prefixVar: values.prefixCls,
  };
}

Note: If you configure it for the first time, you may report an error that @{namespace} is not defined. This requires configuring the less parameter of vue.config.js

 const oneOfsMap = config.module.rule("less").oneOfs.store;
    oneOfsMap.forEach(item => {
      item
          .use("style-resources-loader")
          .loader("style-resources-loader")
          .options({
            // or an array : ["./path/to/vars.less", "./path/to/mixins.less"] 这里的路径不能使用@,否则会报错
            patterns: "./src/style/subApp.less"
          })
          .end()
    });

The complete config.js can refer to


const { defineConfig } = require("@vue/cli-service");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; // 开启gzip压缩, 按需写入
const name = require("./package").name;

const VUE_APP_BASE_API = process.env.VUE_APP_BASE_API;
const VUE_APP_BASE_REWRITE_API = process.env.VUE_APP_BASE_REWRITE_API;
const VUE_APP_SERVER_URL = process.env.VUE_APP_SERVER_URL;
const AutoImport = require("unplugin-auto-import/webpack");
const Timestamp = new Date().getTime();
const path = require("path");
const resolve = (dir) => path.join(__dirname, dir);

module.exports = defineConfig({
  transpileDependencies: true,
  productionSourceMap: false,
  publicPath: "./",
  outputDir: name,
  assetsDir: "assets",

  chainWebpack: (config) => {
    const oneOfsMap = config.module.rule("less").oneOfs.store;
    oneOfsMap.forEach(item => {
      item
          .use("style-resources-loader")
          .loader("style-resources-loader")
          .options({
            // or an array : ["./path/to/vars.less", "./path/to/mixins.less"] 这里的路径不能使用@,否则会报错
            patterns: "./src/style/subApp.less"
          })
          .end()
    });
    config.plugin("html").tap((args) => {
      args[0].title = "星芒运行态扩展应用";
      return args;
    });

    config.resolve.alias
        .set('/#/', resolve('types/'));

    // svg图标加载
    config.module
      .rule("svg")
      .exclude.add(path.join(__dirname, "src/icons/svg"))
      .end();

    config.module
      .rule("icons") // 定义一个名叫 icons 的规则
      .test(/\.svg$/) // 设置 icons 的匹配正则
      .include.add(path.join(__dirname, "src/icons/svg")) // 设置当前规则的作用目录,只在当前目录下才执行当前规则
      .end()
      .use("svg-sprite") // 指定一个名叫 svg-sprite 的 loader 配置
      .loader("svg-sprite-loader") // 该配置使用 svg-sprite-loader 作为处理 loader
      .options({
        // 该 svg-sprite-loader 的配置
        symbolId: "icon-[name]",
      })
      .end();
  },

  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          modifyVars: {
            //这是配置css主题色
            // "primary-color": "#347AE2",
            // 'border-radius-base': '6px',
          },
          javascriptEnabled: true,
        },
      },
    },
    // 每次打包后生成的css携带时间戳
    extract: {
      filename: `css/[name].${Timestamp}.css`,
      chunkFilename: `css/[name].${Timestamp}.css`,
    },
  },
  devServer: {
    port: 3333,
    open: false,
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
    historyApiFallback: true,
    // 配置多个代理
    proxy: {
      [`^${VUE_APP_BASE_API}`]: {
        target: VUE_APP_SERVER_URL,
        changeOrigin: true,
        // pathRewrite: {
        //   [`^${VUE_APP_BASE_API}`]: VUE_APP_BASE_REWRITE_API,
        // },
        pathRewrite: (path) => path.replace(/^\/api/, ""),
      },
    },
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: "umd", // 把微应用打包成 umd 库格式
      chunkLoadingGlobal: `webpackJsonp_${name}`,
    },
    plugins: [
      new CompressionWebpackPlugin({
        filename: '[path][base].gz',
        algorithm: 'gzip',
        test: productionGzipExtensions,
        threshold: 10240,//大于10k的进行压缩
        minRatio: 0.8,
      }),
      AutoImport({
        imports: ["vue", "pinia", "vue-router"],
        dts: true,
        eslintrc: {
          enabled: true,
          globalsPropValue: "readonly",
        },
      }),
    ],
  },
});

Guess you like

Origin blog.csdn.net/weiyongliang_813/article/details/127193035
Recommended