part04~开发通用前端UI框架(主题,国际化,高效打包,单测,组件文档)

定制主题

  • 所谓定制呢,就是将封装一些跟页面整体设计色值或者特殊设计相关的通用的颜色或者圆角等信息封装成变量然后存储成一个文件,这样我们就可以直接引用文件,使用变量,从而降低代码冗余度

  • https://www.antdv.com/docs/vue/customize-theme-cn/

  • 这是Antd已经封装好的所有的变量,可以直接使用

  • https://github.com/vueComponent/ant-design-vue/blob/master/components/style/themes/default.less

  • vue.config.js

      less: {
        modifyVars: {
          // 配置主题
          'primary-color': '#1DA57A',
          // 链接颜色
          'link-color': '#1DA57A',
          // 圆角设计
          'border-radius-base': '2px'
        },
        javascriptEnabled: true
      }
  • 此时重启服务,你会发现,页面的主题颜色,链接颜色,圆角都跟你上面配置的一致了

动态切换主题

  • 安装插件
    • cnpm i antd-theme-webpack-plugin
    • http://npm.taobao.org/package/antd-theme-webpack-plugin
  • vue.config.js
const path = require("path"); // 引入path模块
const AntDesignThemePlugin = require("antd-theme-webpack-plugin");
const options = {
  antDir: path.join(__dirname, "./node_modules/ant-design-vue"),
  stylesDir: path.join(__dirname, "./src"),
  varFile: path.join( // 使用默认ant提供的默认的变量库
    __dirname,
    "./node_modules/ant-design-vue/lib/style/themes/default.less"
  ),
  mainLessFile: "",
  themeVariables: ["@primary-color"],
  generateOnce: false,
  customColorRegexArray: [] // An array of regex codes to match your custom color variable values so that code can identify that it's a valid color. Make sure your regex does not adds false positives.
};
// 实例化一个主题对象
const themePlugin = new AntDesignThemePlugin(options);

module.exports = {
   configureWebpack: {
    plugins: [themePlugin]
  },
 // 使用插件
}
  • index.html
  
  <link rel="stylesheet/less" type="text/css" href="/color.less" />
  <script>
    window.less = {
      async: false,
      env: 'production',
      javascriptEnabled: true,
      modifyVars: {
        // 配置默认主题
        "primary-color": "#1DA57A"
      },
    };
  script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js">script>
  
  • 此时你打开控制台输入
window.less.modifyVars({'primary-color':'red'})
// 页面主题色是不是变了
// 但是依旧有一个问题:我们把抽屉的按钮写死了,所以要做以下调整
  • components/SettingDrawer
    • 将index.vue中的handle类名换成一个不会重复的类名,将scope去掉
      • 将样式提取出来放到新建的index.less中
      • 然后引入index.less
        <div class="setting-handle" @click="visible = !visible">div>
        <style lang="less">
           @import url("./index.less");
        style>         
      
    • 新建index.less
    /* 引入默认主题的less */
    @import '~ant-design-vue/lib/style/themes/default.less' 
    .setting-handle {
       position: absolute;
       top: 300px;
       right: 268px;
       background-color: saddlebrown;
       height: 40px;
       width: 40px;
       line-height: 40px;
       text-align: center;
       background-color: @primary-color;
       border-radius: 5px;
       color: white;
     }
    
    • 重新启动项目
      • window.less.modifyVars({‘primary-color’:‘red’})
      • 你会发现,主题切换ok了…
      • 接下来不用我说了吧,你只需要动态切换这个脚本就好啦

    重点,这样通过变脸去改变主题,其实呢如果项目很大性能损耗很大,实际生产环境中,可以通过主题文件进行切换,这样大大提高效率

国际化

  • antd中明确的也有国际化的内容
  • 注册组件
    • main.js
    import {
    LocaleProvider
    

} from “ant-design-vue”;
// 使用
Vue.use(LocaleProvider)

- App.vue
```html
<script>
import zhCN from "ant-design-vue/lib/locale-provider/zh_CN";
import enUS from "ant-design-vue/lib/locale-provider/en_US";
export default {
  data() {
    return {
      locale: zhCN
    };
  },
  watch: {
    // 通过路由监听来切换语言
    "$route.query.locale": function(val) {
      this.locale = val === "enUS" ? enUS : zhCN;
    }
  }
};
</script>
// 这是针对Antd自己的组件的国际化方法,但是比如日期,日历组件,使用第三方moment.js,无法像自己组件一样的随意切换,所以需要额外处理
  • 处理第三方库的国际化问题
  <div id="app">
    <LocaleProvider :locale="locale">
      <router-view>router-view>
    LocaleProvider>
  div>
<script>
import zhCN from "ant-design-vue/lib/locale-provider/zh_CN";
import enUS from "ant-design-vue/lib/locale-provider/en_US";
import moment from "moment"; // 处理第三方库的国际化
export default {
  data() {
    return {
      locale: zhCN
    };
  },
  watch: {
    // 通过路由监听来切换语言
    "$route.query.locale": function(val) {
      this.locale = val === "enUS" ? enUS : zhCN;
      moment(val === "enUS" ? enUS : zhCN);
    }
  }
};
</script>
  • layout-Header中去添加一个切换语言的功能
     <a-dropdown>
      <a class="ant-dropdown-link" @click="e => e.preventDefault()">
        <a-icon style="font-size:28px; margin-right:20px" type="global" />
      a>
      <a-menu
        slot="overlay"
        @click="localeChange"
        :selectedKeys="[$route.query.locale || 'zhCN']"
      >
        <a-menu-item key="zhCN">
          <a href="javascript:;">中文a>
        a-menu-item>
        <a-menu-item key="enUS">
          <a href="javascript:;">Englisha>
        a-menu-item>
      a-menu>
    a-dropdown>
    
<script>
export default {
  data() {
    return {};
  },
  methods: {
    localeChange(obj) {
      this.$router.push({ query: { locale: obj.key } });
    }
  }
};
</script>
// 此时你点击切换语言就可以通过路由看到切换成功了
// 怎么验证呢?
// 引入一个日期组件看看
// 是不是你会发现,中英文切换成功了
  • 此时你会疑问,奇怪啊,难道就是日期有用,其他的文字没变啊,都还是中文,没错啊,应为那些中文是不是在之前开发中写死了?
  • 怎么解决这个问题?
    • 你可以自己写json文件去处理,也就是什么能,原来写中文的地方换成一个占位符,然后进行文件读取,根据router参数判断读取的中文文件渲染还是英文文件渲染

摊牌了,vue有国际化插件

  • https://kazupon.github.io/vue-i18n/
  • 老规矩,先安装,在全局注册
  • 新建一个locale语言包
  • 新建zhCN.js
export default {
  // 注意这个key哦
  "app.dashboard.analysis.timeLable": "时间"
};

  • 新建enUS.js
export default {
  // 注意这个key哦
  "app.dashboard.analysis.timeLable": "Time"
};
  • 使用一个解析路由字符串的包query-string,记得安装
  • main.js
// 新建的语言包
import enUS from "./locale/enUS";
// 新建的语言包
import zhCN from "./locale/zhCN";
import VueI18n from "vue-i18n";
import queryString from "query-string";
// 注册国际化插件
Vue.use(VueI18n);
const i18n = new VueI18n({
  locale: queryString.parse(location.search).locale || "zhCN", // 解析路由地址看看有没有语言切换标志
  messages: {
    zhCN: { message: zhCN },
    enUS: { message: enUS }
  }
});
new Vue({
  i18n,// 挂在到vue对象上方便使用
  render: h => h(App)
}).$mount("#app");

  • header.vue
    localeChange(obj) {
      this.$router.push({ query: { locale: obj.key } });
      // 切换路由的同时,告诉i18n你选的语言
      this.$i18n.locale = obj.key; 
    }
  • 回到Dashboard/Analysis.vue
     
     
    {{ $t("message")["app.dashboard.analysis.timeLable"] }}

高效打包优化

  • 首先我们打包后可以去观察当前打包的一些大小
  • npm run build – --report
    • 运行完之后,你可以在dist目录中看到一个report.html打开它就你能看到根据你当前的打包分析出来的体积信息图
  • 那么处理这块常规手段
    • icon按需加载
    • 组件按需加载
    • moment优化
    • echart 按需加载
  • 组件按需加载环境搭建时我们已经处理了
  • 下面icon的按需加载
  • 新建src/icon.js
// 图标的按需加载
export { default as SettingOutline } from "@ant-design/icons/outline/SettingOutline";
  • webpack配置
 configureWebpack: {
    resolve: {
      alias: {
        "@ant-design-vue/lib/icon$": path.resolve(__dirname, "./src/icons.js")
      }
    }
  },
  • 下面时moment按需加载
  • https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
  • vue.config.js
const webpack = require("webpack"); // 引入webpack
// 添加插件
configureWebpack: {
    plugins: [new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)],
  },
  • main.js
import "moment/locale/zh-cn"; // 引入中文包,默认是英文的不必理会
  • 下面是chart按需加载
    • 需要哪种图就只需要打包那种代码, 而不是全部打包
import echarts from "echarts/lib/echarts";
// 用了柱状图,就只引入柱状图
import "echarts/lib/chart/bar";
import "echarts/lib/component/title";
  • 至此重新运行打包命令,你会发现代码体积小了很多
  • 当然了,根据项目实际需要,还会有很多优化的点

可交互的组件文档

  • 这玩意就是用来展示组件的代码而已,看起来比较直观一些
  • cnpm i raw-loader --save-dev
  • 将组件代码导出成字符串
  • Analysis.vue
// 导出组件代码字符串
 import chartCode from "!!raw-loader!@/components/chart/Chart";
 export default {
 data() {
   return {
     chartCode, //chart代码字符串
   }
 }
  • 此时呢你把 chartCode 扔到页面花括号里就已经可以看到代码了
  • 但是视觉太差,我们改一下,用highlight.js高亮展示
  • cnpm i --save vue-highlightjs
  • 然后main.js中引入注册
import VueHighlightJS from "vue-highlightjs";
Vue.use(VueHighlightJS);
  • Analysis.vue
   <pre v-highlightjs="chartCode"><code class="html">code>pre>
  • 此时刷新页面已经有了组件代码
  • 在添加高亮效果
  • https://highlightjs.org/ 去官方找你想要的效果
  • main.js
import 'highlight.js/styles/github.css';
  • 此时刷新就有了高亮效果

单元测试

  • 单元测试不用说了吧,就是测试写的js的执行情况咯
  • jest.config.js
module.exports = {
  moduleFileExtensions: ["js", "jsx", "json", "vue"],
  transform: {
    "^.+\\.vue$": "vue-jest",
    ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$":
      "jest-transform-stub",
    "^.+\\.jsx?$": "babel-jest"
  },
  transformIgnorePatterns: ["/node_modules/"],
  moduleNameMapper: {
    "^@/(.*)$": "/src/$1"
  },
  snapshotSerializers: ["jest-serializer-vue"],
  testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
  testURL: "http://localhost/",
  collectCoverage: process.env.COVERAGE === "true", // 是否生成测试报告
  collectCoverageFrom: ["src/**/*.{js,vue}", "!**/node_modules/**"] // 测试覆盖
};
  • .eslintrc.js
  env: {
    jest: true
  },
  • 我们以测试auth->index.js
  • 稍微修改一下代码
// 获取权限
const currentAuth = ["admin"];
// 导出当前权限
export { currentAuth };
export function getCurrentAuthority() {
  // 这里返回的权限应该是从后端读取回来的,此时用admin替代
  return currentAuth;
}
// 鉴权
export function check(authority) {
  const current = getCurrentAuthority();
  return current.some(item => authority.includes(item));
}
// 判断是否登陆
export function isLogin() {
  const current = getCurrentAuthority();
  return current && current[0] !== "guest";
}

  • 在tests->unit中新增auth的单侧文件
  • auth.spec.js
import { check, currentAuth } from "@/auth";
describe("auth test", () => {
  // 测试没权限
  it("empty auth", () => {
    currentAuth.splice(0, currentAuth.length);
    expect(check(["user"])).toEqual(false);
    expect(check(["admin"])).toEqual(false);
  });
  it("user auth", () => {
     // 测试user
    currentAuth.splice(0, currentAuth.length);
    currentAuth.push("user");
    expect(check(["user"])).toEqual(true);
    expect(check(["admin"])).toEqual(false);
  });
  it("admin auth", () => {
    // 测试admin和user
    currentAuth.push("admin");
    expect(check(["user"])).toEqual(true);
    expect(check(["admin"])).toEqual(true);
    expect(check(["user", "admin"])).toEqual(true);
  });
});

发布npm包

  • 其实很简单
  • 有一个npm账号
  • 在你的项目添加一个json,至少包含两个属性
    • name:‘项目名称’ --注意:不能重复
    • version:‘版本信息’
  • 但是关于源头:
    • 有的是本地使用了淘宝源头
    • 有的是用了npm官方
    • 还有自己公司的源头
    • 这么多怎么区分呢?
    • 使用nrm
      • https://www.npmjs.com/package/nrm
      • npm install -g nrm
    • 然后通过nrm use 源头名称 就可以随意切换了
    • 当然还有一些跟发包不是很相关的属性,自己去研究吧

github的相关生态工具(开源项目)

CI持续集成

  • https://travis-ci.org
  • https://circleci.com
  • 当然了我们可以使用Jenkins本地部署(推荐)

单测覆盖率

  • 可以生成单侧报告,让项目使用者更加清晰测试覆盖程度,以供选择
  • https://codecov.io
  • https://coveralls.io

文档管理

github.io
gitee.io
https://www.netlify.com

isuse使用

https://github/apps/close-issue-app

源码地址:[email protected]:sunhailiang/vue-public-ui.git

欢迎加微信一起学习:13671593005
未完待续…

你可能感兴趣的:(vue实战,前端项目,webpack)