Don’t let your limits become your limits

preface

In order to keep up with the pace, I tried vue3. While learning vue3, I learned first-hand Electron and TS. This tutorial will be published separately, and the source code will be published in the last article. Because it is still under development, it is also in order to prevent some pits from being forgotten in time, so sort out part of it first

Will be divided into 2 parts to issue a tutorial, because the configuration of things personal feel a little much and with the development of content related to things is not a lot, so issued alone, forgive me, the second two days issued, long warning! ⚠. 【electron+vue3+ TS actual battle note EXE 】 two, the electron+vue3 development content

Development idea:

  1. Page:
    • List of pp.index.vueOnly one list page can exist in the header, search, and content sections
    • Settings pagesetting.vueSet content and software information, like the list page can only exist one
    • Edit pageeditor.vueThe ICONS function and background color function allow multiple edit pages to exist simultaneously
  2. Dynamic effect:
    • Turn on the dynamic effect, there is a transition of enlargement and transparency, can not put the GIF here is not demonstrated for the time being.
    • Title transition effect
    • switchindexandsettingIs the same head, content transition
  3. Data storage: Data is created and updated in the edit pageeditor.vueGo ahead, the process is stored innedbThen the communication list pageindex.vueUpdate content, considering performance issues, used hereImage stabilizationPrevent continuous updates from causing a lag (but this seems not necessary). It’s a small feature, and then you can set the update speed)
  4. Error collection: Collect errors in use and pop-up prompt
  5. Edit display:documentexposedexecCommandMethod that allows you to run commands to manipulate elements in an editable content area.

During the development, I also encountered many pits, which were only found in the electron environment, for example

  1. @inputTrigger 2 times plusv-modelTrigger 3 times. That includes creating a new electron frame, which won’t happen on anyone else’s computer, guess whatElectron cacheThe problem
  2. Vue3 encounterEmpty propertiesAn infinite number of errors are reported, which is normal once in normal browsers (Edge and Chrome)
  3. Components that cannot render properly do not report an error, only an exception on the console
  4. After packing, due toelectronIt takes about 10 seconds to open the software cache of drive C

I don’t remember anything else.

The introduction of VUE3 and ELECTRON is not provided here for the time being. If necessary, you can read other relevant articles in the community first or provide them in detail later. The software is called I-Notes.

Vue3 Chinese tutorial vue3js.cn/docs/zh/gui… Electron tutorial www.electronjs.org/ typescript tutorial www.typescriptlang.org/

The e pack environment in electron-vue is too low, so the electron+vue3 configuration is manual (although manual. There are two steps.)

The directory structure
Electron - vue - notes ├ ─ ─ public │ ├ ─ ─ CSS │ ├ ─ ─ the font │ └ ─ ─ index. The HTML ├ ─ ─ the SRC │ ├ ─ ─ assets │ │ └ ─ ─ empty - content. SVG │ ├ ─ ─ │ ├── Message │ ├─ rightClick │ ├─ Edit.vue │ ├── Vue │ ├─ vue │ ├─ vue │ ├── Vue │ ├── ├.├.vue │ ├── ├.vue │ ├── ├.options │ │ ├ ─ ─ editorIcons. Options. Ts │ │ ├ ─ ─ but ts │ │ └ ─ ─ shortcuts. The keys. The ts │ ├ ─ ─ inotedb │ │ └ ─ ─ but ts │ ├ ─ ─ less │ │ ├── ─ ├─ ├─ ├─ ├─ ├─ ├─ class.class.class.class.class.class │ │ │ └ ─ ─ but ts ├ ─ ─ utils │ │ ├ ─ ─ errorLog. Ts │ │ └ ─ ─ but ts │ ├ ─ ─ views │ │ ├ ─ ─ editor. The vue │ │ ├ ─ ─ index. The vue │ │ ├ ─ ─ main. Vue │ │ └ ─ ─ setting. The vue │ ├ ─ ─ App. Vue │ ├ ─ ─ background. The ts │ ├ ─ ─ main. Ts │ └ ─ ─ shims - vue. Which s ├ ─ ─ .Browserslistrc ├─.Eslintrc.js ├─.prettierrc.js ├─.babel.config.js ├─ inoteError ├─ download.exe └─ Download.exe └─ Download.exe └─ Download.exe └─ Download.exe └─ download.exe └─ download.exe └─ download.exe └─ download.exe └─ download.exeCopy the code

Use scaffolding to build the VU3 environment

Scaffolding can be installed first if there is no scaffolding

npm install -g @vue/cli
Copy the code

Create a VUE3 project

Vue create electron-vue-notes # follow-up? Please pick a preset: (Use arrow keys) Default ([Vue 2] babel, eslint) Default (Vue 3 Preview) ([Vue 3] babel, Eslint) > Manually select features Please pick a preset: Manually select features ? Check the features needed for your project: Choose Vue version, Babel, TS, Router, CSS Pre-processors, Linter ? Choose a version of Vue.js that you want to start the project with 3.x (Preview) ? Use class-style component syntax? Yes ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes ? Use history mode for router? (Requires proper server setup for index fallback in production) No ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less ? Pick a linter / formatter config: Prettier ? Pick additional lint features: Lint on save, Lint and fix on commit ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files ? Save this as a preset for future projects? (y/N) nCopy the code

The created directory looks like this

Electron - vue - notes ├ ─ ─ public │ ├ ─ ─ the favicon. Ico │ └ ─ ─ index. The HTML ├ ─ ─ the SRC │ ├ ─ ─ assets │ │ └ ─ ─ logo. The PNG │ ├ ─ ─ the components │ │ └ ─ ─ the HelloWorld. Vue │ ├ ─ ─ the router │ │ └ ─ ─ but ts │ ├ ─ ─ views │ │ ├ ─ ─ the About the vue │ │ └ ─ ─ Home. Vue │ ├ ─ ─ App. Vue │ ├ ─ ─ Main. Ts │ └ ─ ─ shims - vue. Which s ├ ─ ─ the browserslistrc ├ ─ ─ the eslintrc. Js ├ ─ ─ Babel. Config. Js ├ ─ ─ package. The json ├ ─ ─ the README. Md ├ ─ ─ Tsconfig. Json └ ─ ─ yarn. The lockCopy the code

Install the electron dependency

# yarn yarn add vue-cli-plugin-electron-builder electron # NPM or CNPM NPM I vue-cli-plugin-electron-builder electronCopy the code

After installing, complete the basic configuration, such as aliases, ESLint, prettier, etc., as well as some colors, ICONS, etc. See below

Some basic configuration of the project

eslint

Using ESLint is primarily a canonical code style. Tslint is not recommended because tsLint is not updated anymore. Tslint also recommends using ESLint to install ESLint

npm i eslint -g
Copy the code

Initialize ESLint after entering the project

Eslint --init # Subsequent configuration? How would you like to use ESLint? To check syntax and find problems ? What type of modules does your project use? JavaScript modules (import/export) ? Which framework does your project use? Vue.js ? Does your project use TypeScript? Yes ? Where does your code run? Browser, Node ? What format do you want your config file to be in? JavaScript The config that you've selected requires the following dependencies: eslint-plugin-vue@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest ? Would you like to install them now with npm? (Y/n) yCopy the code

Modify eslint configuration, ·.eslintrc.js, rules can be configured as you like eslint.org/docs/user-g…

module.exports = {
  root: true.env: {
    node: true
  },
  extends: [
    'plugin:vue/vue3-essential'.'eslint:recommended'.'plugin:prettier/recommended'.'plugin:@typescript-eslint/eslint-recommended'.'@vue/typescript/recommended'.'@vue/prettier'.'@vue/prettier/@typescript-eslint'].parserOptions: {
    ecmaVersion: 2020
  },
  rules: {
    quotes: [1.'single'].semi: 1.'@typescript-eslint/camelcase': 0.'@typescript-eslint/no-explicit-any': 0.'no-irregular-whitespace': 2.'no-case-declarations': 0.'no-undef': 0.'eol-last': 1.'block-scoped-var': 2.'comma-dangle': [2.'never'].'no-dupe-keys': 2.'no-empty': 1.'no-extra-semi': 2.'no-multiple-empty-lines': [1, { max: 1.maxEOF: 1}].'no-trailing-spaces': 1.'semi-spacing': [2, { before: false.after: true}].'no-unreachable': 1.'space-infix-ops': 1.'spaced-comment': 1.'no-var': 2.'no-multi-spaces': 2.'comma-spacing': 1}};Copy the code

prettier

Add. Prettierrc.js configuration in the root directory, as you like, number of characters in a line, single quotes, semicolons, comma endings, and so on

module.exports = {
  printWidth: 120.singleQuote: true.semi: true.trailingComma: 'none'
};
Copy the code

tsconfig.json

If this is not configured to recognize the @/ path, it will cause an error when used in a project

"paths": {
  "@ / *": [
    "src/*"]}Copy the code

package.json

"author": "heiyehk"."description": "I notes personal developer Heiyehk independently developed, in Windows more convenient to record text."."main": "background.js"."scripts": {
  "lint": "vue-cli-service lint"."electron:build": "vue-cli-service electron:build"."electron:serve": "vue-cli-service electron:serve"
}
Copy the code

Configuration entry filebackground.ts

Since we need to do some opening and closing dynamic effects, we need to configure electron for frame bezel-free and transparent

/* eslint-disable @typescript-eslint/no-empty-function */
'use strict';

import { app, protocol, BrowserWindow, globalShortcut } from 'electron';
import {
  createProtocol
  // installVueDevtools
} from 'vue-cli-plugin-electron-builder/lib';

constisDevelopment = process.env.NODE_ENV ! = ='production';

let win: BrowserWindow | null;
protocol.registerSchemesAsPrivileged([
  {
    scheme: 'app'.privileges: {
      secure: true.standard: true}}]);function createWindow() {
  win = new BrowserWindow({
    frame: false./ / no borders
    hasShadow: false.transparent: true./ / transparent
    width: 950.height: 600.webPreferences: {
      enableRemoteModule: true.nodeIntegration: true}});if (process.env.WEBPACK_DEV_SERVER_URL) {
    win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
    if(! process.env.IS_TEST) win.webContents.openDevTools(); }else {
    createProtocol('app');
    win.loadURL('http://localhost:8080');
  }

  win.on('closed'.() = > {
    win = null;
  });
}

app.on('window-all-closed'.() = > {
  if(process.platform ! = ='darwin') { app.quit(); }}); app.on('activate'.() = > {
  if (win === null) { createWindow(); }}); app.on('ready'.async() = > {// You can open the comment if you have the ability
  // if (isDevelopment && ! process.env.IS_TEST) {
  // try {
  // await installVueDevtools();
  // } catch (e) {
  // console.error('Vue Devtools failed to install:', e.toString());
  / /}
  // }
  createWindow();
});

if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message'.data= > {
      if (data === 'graceful-exit') { app.quit(); }}); }else {
    process.on('SIGTERM'.() = >{ app.quit(); }); }}Copy the code

Start the

yarn electron:serve
Copy the code

At this point the configuration is considered to have successfully set up the window, but there are some other details that need to be configured, such as electron packing configuration, modular configuration and so on

General configuration

Some common development stuff and some wheel code are configured here

reset.csss

html{font-family:'Microsoft YaHei UI'.'Microsoft YaHei',sans-serif; -ms-text-size-adjust:100%; -webkit-text-size-adjust:100%}address,applet,article.aside.audio.blockquote.body.canvas.caption.dd.details.div.dl.dt,embed,figcaption.figure.footer.h1.h2.h3.h4.h5.h6.header.html.iframe.li.mark.menu.nav.object.ol,output,p,pre,progress,ruby,section.summary.table.tbody.td.tfoot.th.thead.time.tr.ul.video{margin:0;padding:0;border:0;vertical-align:baseline}article.aside.details.figcaption.figure.footer.header.main.menu.nav.section.summary{display:block}audio.canvas,progress,video{display:inline-block}audio:not([controls]) {display:none;height:0}[hidden],template{display:none}a{background-color:transparent;text-decoration:none}a:active.a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b.strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:# 000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top: -.5em}sub{bottom: -.25em}img{border:0}svg:not(:root) {overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code.kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button.input,optgroup,select,textarea{color:inherit;font:inherit;margin:0;outline:0;line-height:normal}button{overflow:visible}button,select{text-transform:none}button.html input[type=button].input[type=reset].input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled].html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox].input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td.th{padding:0}::-ms-clear,::-ms-reveal{display:none}input:-webkit-autofill{-webkit-animation:autofill-fix 1s infinite! important; -webkit-text-fill-color:# 666; -webkit-transition:background-color 50000s ease-in-out 0s! important;transition:background-color 50000s ease-in-out 0s! important;background-color:transparent! important;background-image:none! important; -webkit-box-shadow:0 0 0 1000px transparent inset! important}[role=button].a,area,button.input:not([type=range]),label,select,summary.textarea{-ms-touch-action:manipulation; touch-action:manipulation}input[type=number].input[type=password].input[type=text].textarea{-webkit-appearance:none}
Copy the code

common.css

/* The contents of the empty element */
.empty-content:empty::before {
  /* content: attr(placeholder); * /
  content: 'Take notes... ';
  font-size: 14px;
  color: # 666;
  line-height: 21px;
}

/* Hide the scroll bar */
::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Set the ol display format */
.module-editor ol {
  counter-reset:sectioncounter;
}

.module-editor ol li {
  list-style: none;
  position: relative;
}

.module-editor ol li::before {
  content: counter(sectioncounter) '. ';
  counter-increment:sectioncounter;
  margin-right: 10px;
}

/* Using custom pseudo-classes causes the cursor to be moved down */
/* .module-editor ul { position: relative; } .module-editor ul li { list-style-type: none; word-break: break-all; } .module-editor ul li::before { content: ''; width: 5px; height: 5px; background-color: #000; margin-right: 6px; display: inline-block; border-radius: 100%; transform: translateY(-2px); margin-left: 1px; } * /

.module-editor ul li {
  word-break: break-all;
  list-style: disc inside;
}

/* Common flex layout */
.flex {
  display: flex;
}

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.flex-left {
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.flex-right {
  display: flex;
  justify-content: center;
  align-items: flex-end;
}

.flex-items {
  display: flex;
  align-items: center;
}

.flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.flex1 {
  flex: 1;
}

/* ellips */
.hidden {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

html.body..app..transition..bg-white {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  position: relative;
  overflow: hidden;
  background-color: rgba(0.0.0.0);
  outline: none;
}

.bg-white {
  background-color: #fff;
}

/* Software shadow */
.app {
  box-shadow: 0 0 4px rgb(185.185.185);
}

body {
  padding: 4px;
  user-select: none;
  outline: none;
}

@keyframes fadein {
  0% {
    transform: scale(0.8);
    opacity: 0;
  }
  100% {
    transform: scale(1);
    opacity: 1; }}@keyframes fadeout {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  100% {
    transform: scale(0.9);
    opacity: 0; }}/* Enter and exit dynamic effects */
.app-show {
  animation: fadein 0.4 s forwards;
  transform: scale(1) ! important;
}

.app-hide {
  animation: fadeout 0.2 s forwards;
  transform: scale(0.9);
}

/ * * / color
.yellow-content {
  transition: background-color 0.4 s;
  background-color: #fff7d1 ! important;
}

.green-content {
  transition: background-color 0.4 s;
  background-color: #e4f9e0 ! important;
}

.pink-content {
  transition: background-color 0.4 s;
  background-color: #ffe4f1 ! important;
}

.purple-content {
  transition: background-color 0.4 s;
  background-color: #f2e6ff ! important;
}

.blue-content {
  transition: background-color 0.4 s;
  background-color: #e2f1ff ! important;
}

.gray-content {
  transition: background-color 0.4 s;
  background-color: #f3f2f1 ! important;
}

.black-content {
  transition: background-color 0.4 s;
  background-color: # 696969 ! important;
  color: #fff;
}

.black-content * {
  color: #fff;
}

Copy the code

config

The config folder in the corresponding project

Config ├─ Browse.options.ts # ├─ Classnames.options.ts # ├─ └─ shortcuts.keys. Ts # ├─ shortcuts.shortcuts. Electron is based on chromium browser, so there are some browser shortcuts like F5Copy the code

browser.options

The main function of this file is to configure the main window and edit window to distinguish between the development of the formal configuration, width, height, etc., and the main page to display

/** * Software Data and Configuration * C:\Users\{user name}\AppData\Roaming * Share * C:\ProgramData\Intel\ShaderCache\ i-Notes {xx} * Shortcut * C:\Users\{User name}\AppData\Roaming\Microsoft\Windows\Recent * Computer Automatically create cache * C:\Windows\Prefetch\ i-notes.exe {xx} */

/ * * * /
const globalEnv = process.env.NODE_ENV;

const devWid = globalEnv === 'development' ? 950 : 0;
const devHei = globalEnv === 'development' ? 600 : 0;

// Bottom icon: 40*40
const editorWindowOptions = {
  width: devWid || 290.height: devHei || 350.minWidth: 250
};

/** * BrowserWindow configuration item *@param Type alone for edit window configuration */
const browserWindowOption = (type? :'editor'): Electron.BrowserWindowConstructorOptions => {
  const commonOptions = {
    minHeight: 48.frame: false.hasShadow: true.transparent: true.webPreferences: {
      enableRemoteModule: true.nodeIntegration: true}};if (!type) {
    return {
      width: devWid || 350.height: devHei || 600.minWidth: 320. commonOptions }; }return{... editorWindowOptions, ... commonOptions }; };/ * * * development environment: http://localhost:8080 * formal environment: file://${__dirname} / index. HTML * /
const winURL = globalEnv === 'development' ? 'http://localhost:8080' : `file://${__dirname}/index.html`;

export { browserWindowOption, winURL };
Copy the code

classNames.options

If you want more color, just add it

/** * - 'yellow-content' yellow * - 'green-content' green * - 'pink-content' pink * - 'purple-content' - 'blue-content' blue * - 'gray-content' - 'black-content' Black */
const classNames = [
  / / {
  // color: 'white-content',
  // title: 'white'
  // },
  {
    className: 'yellow-content'.title: 'yellow'
  },
  {
    className: 'green-content'.title: 'green'
  },
  {
    className: 'pink-content'.title: 'pink'
  },
  {
    className: 'purple-content'.title: 'purple'
  },
  {
    className: 'blue-content'.title: 'blue'
  },
  {
    className: 'gray-content'.title: 'grey'
  },
  {
    className: 'black-content'.title: 'black'}];export default classNames;
Copy the code

editorIcons.options

/** * - 'bold' * - 'italic' * - 'underline' * - 'strikeThrough' 'delete line * -' insertUnorderedList ' 'unordered list * - 'insertOrderedList' ordered list * - 'image' image */
const editorIcons = [
  {
    name: 'bold'.title: 'bold'.icon: 'icon-editor-bold'
  },
  {
    name: 'italic'.title: 'italics'.icon: 'icon-italic'
  },
  {
    name: 'underline'.title: 'underline'.icon: 'icon-underline'
  },
  {
    name: 'strikethrough'.title: 'Delete line'.icon: 'icon-strikethrough'
  },
  {
    name: 'insertUnorderedList'.title: 'Unordered list'.icon: 'icon-ul'
  },
  {
    name: 'insertOrderedList'.title: 'Ordered list'.icon: 'icon-ol'
    // },
    / / {
    // name: 'image',
    // title: 'picture ',
    // icon: 'icon-image'}];export default editorIcons;
Copy the code

shortcuts.keys

/** * -f11 Disables full screen zoom * - CTRL+R disables Refresh * - CTRL+SHIFT+R disables Refresh */
const devShortcuts = ['F11'.'Ctrl+R'.'Ctrl+SHIFT+R']; // This is mainly used in development, but the formal environment needs to mask the shortcut key

const shortcuts = ['Ctrl+N'.'SHIFT+F10'.'Ctrl+SHIFT+I']; // Here are the shortcut keys to mask directly

const exportKeys = process.env.NODE_ENV === 'development' ? shortcuts : [...devShortcuts, ...shortcuts];

export default exportKeys;
Copy the code

index

export

import classNames from './classNames.options';
import editorIcons from './editorIcons.options';
import { browserWindowOption, winURL } from './browser.options';
import shortcutsKeys from './shortcuts.keys';

export { classNames, editorIcons, browserWindowOption, winURL, shortcutsKeys };
Copy the code

Adjust background. Ts

After configuring config, you need to adjust background.ts

// Modify the createWindow method
function createWindow() {
  win = new BrowserWindow(browserWindowOption());

  if (process.env.WEBPACK_DEV_SERVER_URL) {
    win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
    if(! process.env.IS_TEST) win.webContents.openDevTools(); }else {
    createProtocol('app');
    win.loadURL(winURL);
  }

  win.on('closed'.() = > {
    win = null; }); }... app.on('ready'.async () => {
  ...
  // The shortcut keys are disabled
  for (const key of shortcutsKeys) {
    globalShortcut.register(key, () = > {});
  }
  createWindow();
});

Copy the code

vue.config.js

Create the vue.config.js file

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');

module.exports = {
  productionSourceMap: false.configureWebpack: config= > {
    if(process.env.NODE_ENV ! = ='development') {/
    // Clear development debug, console.log, etc
      config.optimization.minimizer[0].options.terserOptions.warnings = false;
      config.optimization.minimizer[0].options.terserOptions.compress = {
        warnings: false.drop_console: true.drop_debugger: true.pure_funcs: ['console.log']}; }},pluginOptions: {
    // Here is the configuration information for ElectronBuild
    electronBuilder: {
      // To use the Node environment in a browser, the value must be true
      nodeIntegration: true.builderOptions: {
        productName: 'I notes'.appId: 'com.inote.heiyehk'.copyright: 'heiyehk'.compression: 'store'./ / "store" | "normal" | "maximum" compress condition (store relatively quickly), store 39749 KB, maximum 39186 KB
        // directories: {
        // output: 'build' // output folder
        // },
        win: {
          // icon: 'xxx/icon.ico',
          target: ['nsis'.'zip']},mac: {
          target: { target: 'dir'.arch: 'arm64'}},nsis: {
          oneClick: false.// One-click setup
          // guid: 'XXXX ', // Registry name, not recommended
          perMachine: true.// Whether to enable installation permission restrictions (for this computer or the current user)
          allowElevation: true.// Allow request promotion. If false, the user must restart setup with the promoted permissions.
          allowToChangeInstallationDirectory: true.// Allows you to change the installation directory
          // installerIcon: './build/ ICONS /aaa.ico', // Install ICONS
          // uninstallerIcon: './build/ ICONS /bbb.ico', // Uninstall ICONS
          // installerHeaderIcon: './build/ ICONS /aaa.ico', // Install header icon
          createDesktopShortcut: true.// Create a desktop icon
          createStartMenuShortcut: true.// Create start menu icon
          shortcutName: 'I notes' // Icon name}}},'style-resources-loader': {
      preProcessor: 'less'.patterns: [path.resolve(__dirname, 'src/less/index.less')] // Introduce global style variables}}};Copy the code

Use the global less variable

Here you need to use less global variables, the installation style – resources – loader, after installation will default in vue. Config. Configuration in js, you just need to change the path

vue add style-resources-loader
Copy the code

But less configuration

@primary-color: #027aff;
@success-color: #19be6b;
@warning-color: #ff9900;
@error-color: #ed4014;
@white-color: #ffffff;
@gray-color: #efefef;

@text-color: # 000000;
@text-sub-color: # 00000073;
@border-color: #d9d9d9;
@disabled-color: #c5c8ce;
@background-color: #f3f3f3;
@background-sub-color: #eeeeee;
@shadown-color: #cccccc;

/ / iconsize head
@headerIconFontSize: 22px;

// The height of the head, the bottom function button and the width and height of the icon are the same
@iconSize: 40px;

.icon {
  width: @iconSize;
  height: @iconSize;
  min-width: @iconSize;
  min-height: @iconSize;
  outline: none;
  border: none;
  background-color: transparent;
  padding: 0;
  position: relative;
  &::before {
    content: ' ';
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    z-index: 0;
  }
  a {
    color: initial;
    width: 100%;
    height: 100%;
    outline: none;
    position: relative;
    z-index: 1;
  }
  .iconfont {
    width: 22px;
    position: relative;
  }
  &:hover {
    &::before {
      background-color: rgba(0.0.0.0.1); }}}Copy the code

At the end

Light configuration content is a bit much, so the development process will be put in the later part to send, absolutely not pigeon!! In addition, the source code will be annotated on GitHub after it is sorted. Strives for the star.