01 – vue3 UI framework – start


Write in front

I haven’t written a blog for more than a year, and my work and life have gradually smoothed out the edges and corners.

It’s easy to write code, difficult to blog, and more difficult to stick to a high-level technical blog.

The technical controller decided to slowly pick up this persistence and use it as a phased summary of technical learning.

Return to the reading list and clickhere


In the era of big front-end, in the process of interviewing front-end engineers recently, I felt that the technology update iteration is fast and the learning cost is high. Browse the major blog forums, which are very different and chaotic. Final decision referenceElement UIFor the design style, the theme color is purple (affected)MaterialDesignInXamlToolkitWrite a set based onVue3ofUIThe framework library and the corresponding official website are convenient for quick use in the later stage of the projectVue3Learning and summary of new features.

Have a look firstJeremy UI official websiteEffect! At present, the project is still in the development stage. If you are interested, you can practice together. You are also welcome to participate in the project. Project reference addressGitHub, welcomestarissueforkandPR


Analysis official website

Interface layout

  1. Top sidebar

  2. home page

  3. Document page

    1. sidebar
    2. Content area

Theme style


detailed description

position characteristic
layout Left blank on both sides, content in the middle, maximum width1200px, less than1200pxWhen, width100%less than500pxWhen, it becomes the mobile version
Top sidebar On the left is the jump link to the home page, and on the right is the jump link to the document page500pxWhen, only the jump to the home page is displayed
home page It is divided into two parts: visual effect part and feature introduction part
Home page vision Purple aurora background, with two jump links in the middle, one toGitHubLook at the code and go to the document page
Home page features contain3Two features are 1 Usedvue3New features 2 usets3. The code is easy to read
Document page The document page is actually composed of a top sidebar and an ontology, which includes a sidebar and a content area
Top Sidebar – document page less than500pxWhen, the key to pop up the sidebar is additionally displayed on the left, and the sidebar is invisible
sidebar Visible by default, highlight is selected, but the viewport width is less than500pxIt is invisible by default and consists of two parts: guide and component, each with child jump
Content area According to the link selected in the sidebar, themdContent or component example content

Build an official website

There are many ways to create, and I choose to use it hereViteCreateVue3Project, whyViteAnd? Here isVite official websiteThe following statement:

Practical problems

Before the browser supported es module, JavaScript did not provide a native mechanism for developers to develop in a modular way. This is why we are familiar with the concept of “packaging”: use tools to grab, process and concatenate our source modules into files that can run in the browser.

Over time, we have witnessedwebpackRollupandParcelAnd other tools, which have greatly improved the development experience of front-end developers.

However, as we start building larger and larger applications, the amount of JavaScript code that needs to be processed also grows exponentially. Large projects with thousands of modules are quite common. We’re starting to run into performance bottlenecks — tools developed with JavaScript usually take a long time (even a few minutes!) To start the development server, even if HMR is used, the modified effect of the file takes several seconds to be reflected in the browser. In this cycle, slow feedback will greatly affect the developer’s development efficiency and happiness.

Vite aims to take advantage of new developments in the ecosystem to solve the above problems: browsers begin to support es modules natively, and more and more JavaScript tools are written in compiled languages.

Slow server startup

When the development server is cold started, the packer based startup must first grab and build your entire application before providing services.

Vite improves the startup time of the development server by dividing the modules in the application into dependency and source code at the beginning.

  • Most of the dependencies are pure JavaScript that will not change during development. Some large dependencies (such as component libraries with hundreds of modules) are also expensive to process. Dependencies also usually have multiple modular formats (such as ESM or commonjs).

    Vite will useesbuild Pre build dependency。 Esbuild is written in go and is 10-100 times faster than the packer pre build dependency written in JavaScript.

  • The source code usually contains some files that are not directly JavaScript and need to be converted (such as JSX, CSS or Vue / svelte components), which are often edited. At the same time, not all source codes need to be loaded at the same time (such as code modules based on route splitting).

    Vite toNative ESMProvide the source code. This is actually letting the browser take over part of the packaging program: vite only needs to convert the source code when the browser requests it and provide the source code on demand. The code is imported dynamically according to the scenario, that is, it will be processed only when it is actually used on the current screen.


    基于 ESM 的开发服务器

Slow update

When the packer is started, the efficiency of reconstructing the whole package is very low. The reason is obvious: because in this way, the update speed will decrease linearly with the growth of application volume.

Some packer development servers store the build content in memory so that they only need to inactivate part of the module diagram when the file changes[1]However, it still requires the entire page to be rebuilt and reloaded. This is expensive, and reloading the page will eliminate the current state of the application, so the packer supports dynamic module hot overloading (HMR): allowing a module to “hot replace” itself without affecting the rest of the page. This greatly improves the development experience – however, in practice, we have found that even if the HMR mode is adopted, its hot update speed will decrease significantly with the growth of application scale.

In vite, HMR is executed on the native ESM. When editing a file, vite only needs to precisely inactivate the chain between the edited module and its nearest HMR boundary[1](mostly just the module itself), so that HMR can always be updated quickly regardless of the application size.

Vite also uses HTTP headers to speed up the reload of the entire page (let the browser do more for us again): the request of the source module will be based on304 Not ModifiedNegotiation cache, while dependent module requests will passCache-Control: max-age=31536000,immutableStrong caching, so once cached, they will not need to be requested again.

Once you experience the speed of vite, whether you are willing to tolerate using packer development as before will be a big question mark.

Why does the production environment still need to be packaged

Although native ESMS are now widely supported, it is still inefficient to publish unpackaged ESMS in a production environment (even with HTTP / 2) because nested imports can lead to additional network roundtrips. In order to obtain the best loading performance in the production environment, it is best to perform tree shaking, lazy loading and chunk splitting of the code (for better caching).

It is not easy to ensure optimal output and behavior consistency between the development server and the production environment build. So vite comes with a setConstruction optimizationofBuild command, out of the box.

Why not package with esbuild?

althoughesbuildIt’s surprisingly fast, and it’s already an excellent tool for building libraries, but some are aimed at building librariesapplicationImportant features of are still under development — especially in code segmentation and CSS processing. At present, rollup is more mature and flexible in application packaging. Nevertheless, when these functions are stable in the future, we do not rule out using themesbuildPotential as a production builder.

Before we start, we need to pay attention to compatibility issues:

Compatibility Note

Vite requires node JS version > = 12.0.0


  • Create directly
mkdir jeremy-ui
cd jeremy-ui
cva .
  • Scaffold creation (just create it according to the prompt information, pay attention to the selectionvue -> vue-ts


Start project

cd jeremy-ui
npm install
npm run dev

Under normal circumstances, you can(http://localhost:3000/)Preview the project.

be careful:

If you don’t create a project through scaffolding, you may need tomain.jsChange tomain.ts。 In addition, you need tosrcAdd under directoryshims.d.tsFile, lettsDocuments can be identifiedvueSuffix file.

shims.d.tsThe source code of the file is as follows:

declare module '*.vue' {
  import { ComponentOptions } from 'vue'
  const componentOptions: ComponentOptions
  export default componentOptions

Overall layout design

Based on the previous analysis, we can conclude that, first, the maximum width limit needs to actappSo the corresponding style should be written inapp.vueThe top sidebar of the first page and the document page has the following functions:

position function
home page Disable pop-up menu
Document page Show or hide menus as appropriate

It can be seen that it is not exactly the same, that is, it is not the reuse of the same component, so the top sidebar component should be embedded in the home page and document page components respectively, rather than embeddedapp.vue ,Then, the home page obviously has no sidebar, so the content of the home page can be written directly in its template, while the document page needs a sidebar and content area, but the sidebar of the document page is actually the same content as the pop-up top menu, so it only needs to be written once, and then reused as a sidebar and top menu.

In addition, the content area of the document page should be displayed separatelymarkdownContent and component content, so the content area should be written in two ways.

To sum up, the front page is roughly the upper and lower structure, which is constant; The document page is roughlyTWord structure, less than1200pxIt is an up-down structure with pop-up menu options.

Overall style sheetindex.scss(may need to be modified)index.css(suffix of)

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
ol {
  list-style: none;
a {
  text-decoration: none;
  color: inherit;
  &:hover {
    text-decoration: underline;
    cursor: pointer;
h6 {
  font-weight: normal;

body {
  font-size: 16px;
  line-height: 1.5;
  color: #1d2c40;
  font-family: -apple-system, "Noto Sans", "Helvetica Neue", Helvetica,
    "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB",
    "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN",
    "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", "ST Heiti",
    SimHei, "WenQuanYi Zen Hei Sharp", sans-serif;
.icon {
  width: 1em; height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;

Then modifymain.tsIntroduction in

import './index.scss'

Final completionApp.vueContent of

export default {
  name: "App",

$max-width: 1200px;
.app {
  max-width: $max-width;
  margin-left: calc(50vw - 600px);
  position: relative;
  @media (max-width: $max-width) {
    margin-left: 0;

Installation of dependent packages

Please refer topackage.jsonFile, update it accordingly, and then execute it under the project root directorynpm installJust.

  "name": "jeremy-ui",
  "version": "0.0.3",
  "files": [
  "main": "lib/jeremy.js",
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  "dependencies": {
    "github-markdown-css": "^4.0.0",
    "marked": "^1.2.8",
    "prismjs": "^1.23.0",
    "vue": "^3.0.4",
    "vue-router": "^4.0.4"
  "devDependencies": {
    "@vue/compiler-sfc": "^3.0.4",
    "rollup-plugin-esbuild": "^4.7.2",
    "rollup-plugin-scss": "^3.0.0",
    "rollup-plugin-terser": "^7.0.2",
    "rollup-plugin-vue": "^6.0.0",
    "sass": "^1.44.0",
    "vite": "^1.0.0-rc.13"

Routing design

Since there are multiple pages, you must jump through the route. Routing is obviously usedvue-router, install it first. Note that the default installationvue-routeryes3.x.xVersion, can only be used forvue2, if you want to usevue3, must be4.x.xedition

adoptnpm info vue-routerYou can see the latest version(nextVersion) yes4.0.4(if there is any change, just download the latest version), then we cannpm install [email protected]Installation fitvue3ofvue-router。

Jeremy UIThe routing design of the official website is as follows:

target route
home page /
Document page /document
Document page – Introduction /document/introduction
Documentation page – Installation /document/install
Document page – quick start /document/start
Document page – [component name] /document/[componentName]

Because we haven’t tried yet, let’s write the framework first and write an empty introduction for the time being,router.tsas follows

import { createWebHistory, createRouter } from 'vue-router'

const history = createWebHistory()
const router = createRouter({
    routes: [
export default router

Then inmain.tsIntroduced in

import { createApp } from 'vue'
import App from './App.vue'
import './index.scss'
import router from './router'


Using svg

For the relative beauty of the official website, we decided to use itSVG, you can useicon fontThe free icons provided are roughly as follows

  1. Select your favorite Icon and add it to the shopping cart
  2. Create a new item, or select an existing item to add the icon in the shopping cart to the item
  3. Go to my project and generate a new reference link
  4. choiceSymbolMode, copy link, paste to local projectindex.htmlNewscriptIn label

After that, you can reference it locally in the following waysvgYes

svgNaming, referenceicon fontThe name of each icon set in “my project” on. In addition, if there is any change in the icon in the project, you must regenerate the reference link!

Project address

GitHub: https://github.com/JeremyWu917/jeremy-ui

Official website address

JeremyUI: https://ui.jeremywu.top

GitHub branch description

Branch name explain
main PR of merged website branches
dev Development branch, the reference of component library comes from local
publish The branch published by GitHub pages, and the reference of component library comes from NPM
website The branch used in the official website, and the reference of the component library comes from NPM

buddycloneYou can refer to it laterdevBranch, you candevBranch submission PR!

reference material


Nuggets-Dayne Wayne

Vite official-Vite

Ali vector icon library-Iconfont