First, technical details
- Use create-viet-app to build the official website
- Use vue3 + typescript
- Markdown syntax is supported to highlight code
- Use rollup to package the project library and publish the NPM
- Automate deployment using shell scripts
Second, effect preview
- Source link
- Results the preview
Home page
The document
Iii. Vite construction process
1. Preparation
- Install the NodeJS stable version
- To install NPM, run NPM config set registry registry.npm.taobao.org using Taobao source accelerator
- Installation of yarn
- Install vscode or webstorm for project development
2. Use Vite
- Install create-viet-app globally
Yarn Global add create-viet-app or NPM i-g create-viet-appCopy the code
- Create a project
Cva bobo-ui or create-vite-app bobo-ui // Bobo-ui can be changed to its own project nameCopy the code
- Open the project
cd bobo-ui
Copy the code
- Run the following command to open the local url and begin development
yarn dev
Copy the code
4. Knowledge summary
1. vue-router
- Installation:
yarn add vue-router
- Initialize: create a new history object; Creating a Router Object
/ / the main ts file
import { createApp } from 'vue';
import App from './App.vue';
import {createWebHashHistory,createRouter} from 'vue-router';
const history = createWebHashHistory();
const router = createRouter({
history,
routes:[
{path:'/'.component:Bobo},
{path:'/xxx'.component:Bobo2}
]
});
const app = createApp(App);
app.use(router);
app.mount('#app')
Copy the code
- router-view & router-link
/ / App. Vue file
<template>
<div>The navigation bar |<router-link to="/">BOBO</router-link>|
<router-link to="/xxx">BOBO2</router-link></div>
<hr />
<router-view />
</template>
<script>
export default {
name: 'App',}</script>
Copy the code
2. Dojo.provide and inject
// The parent component is marked
<script lang="ts">
import {ref ,provide} from 'vue';
export default {
name: 'App'.setup(){
const asideVisible = ref(false);
provide('asideVisible',asideVisible);
}
}
</script>
Copy the code
// Child components receive values
<template>
<aside v-if="asideVisible">
<h2>Component list</h2>
</aside>
</template>
<script lang="ts">
import {inject, Ref} from "vue";
export default {
setup(){
const asideVisible = inject<Ref<boolean>>('asideVisible')
return {asideVisible}
}
}
</script>
Copy the code
3. Props pass values and V-Model
/ / the parent component
<template>
<div>
<Switch :value = "y" @update:value="y=$event"/>
</div>
</template>
<script lang="ts">
import Switch from '.. /lib/Switch.vue'
import {ref} from 'vue';
export default {
components:{Switch},
setup(){
const y = ref(false);
return {y}
}
}
</script>
Copy the code
/ / child component
<template>
<button @click="toggle" :class="{checked:value}"></button>
</template>
<script lang="ts">
export default {
props: {value:Boolean
},
setup(props,context){
const toggle = () = >{
context.emit('update:value',! props.value) }return{toggle}; }}</script>
Copy the code
//v-model
/ / the parent component
<Switch v-model:value = "y" />
/ / child component
context.emit('update:value',! props.value)Copy the code
4. Vue3 attribute Binding (Attrs)
<template>
// All attributes passed by the parent element are bound to the root element by default
<div :size = "size">
<! <button v-bind="$attrs"> <button v-bind="$attrs">
<button v-bind="rest"> <! -- Bind only attributes except size -->
<slot/>
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs:false.// The template root element does not inherit events passed by the parent element
setup(props,context){
const{onClick,onMouseOver,size,... rest}=context.attrs;// Get the attributes passed by the parent element to deconstruct the assignment
return{onClick,onMouseOver,size,rest}; }}</script>
Copy the code
5. Named slot
/ / the parent component
<Dialog>
<template v-slot:title>
<strong>The title</strong>
</template>
<template v-slot:content>
<strong>content</strong>
</template>
</Dialog>
Copy the code
/ / child component
<header>
<slot name="title"/>
</header>
<main>
<slot name="content"/>
</main>
Copy the code
6. Render nested slots
/ / the parent component
<template>
<Tabs>
<Tab title=Navigation "1">The content of 1</Tab>
<Tab title="Navigation 2">Content of the 2</Tab>
</Tabs>
</template>
Copy the code
// Nest child component tabs. vue
<template>
<div>
<component v-for="(c,index) in defaults" :is="c" :key="index"/>
</div>
</template>
<script lang="ts">
import Tab from "./Tab.vue";
export default {
setup(props,context){
const defaults = context.slots.default(); // All tabs can be fetched
return {defaults};
}
</script>
Copy the code
// Nested child tab. vue, content 1, content 2 of the parent component, will be inserted into slot
<template>
<div>
<slot/>
</div>
</template>
Copy the code
7. Teleport
Any Portal :Teleport is a technology that allows us to move our templates to a location in the DOM other than the Vue app
// Pass this block directly to the body inside the Dom node
<Teleport to = "body">
<div>A chunk of code</div>
</Teleport>
Copy the code
8. Ref and getgetBoundingClientRect
<template>
<div class="gulu-tabs-nav-indicator " ref="indicator">aaa</div>
</template>
<script lang="ts">
const indicator = ref<HTMLDivElement>(null);
const {width,height,top,left} = indicator.getBoundingClientRect();// Get the width of the div element referenced by indicator
return {indicator};
</script>
Copy the code
9. Introduce SVG ICONS
- Iconfont official website select the icon to add the shopping cart project, open the shopping cart, click symbol, click generate code
- Copy the generated address link into the project
index.html
theheader
In the
<script src="//at.alicdn.com/t/font_2426847_zhxe2xwikqs.js"></script>
Copy the code
- Click on the help next to it, search for symbol references, and copy the CSS to the project as instructed
index.css
file
.icon {
width: 1em; height: 1em;
vertical-align: -0.15 em;
fill: currentColor;
overflow: hidden;
}
Copy the code
- Add an SVG icon to your project
<svg class="icon" >
<use xlink:href="#icon-Vue"></use> // icon-vue specifies the name of the icon in iconfont
</svg>
Copy the code
10. Clip-path and border-radious can be used to draw arcs
11. Support Github markdown style
Markdown making address
Yarn add github-markdown- CSS // InstallationCopy the code
/ / use
import 'github-markdown-css' // in mian. Ts, you can use it directly
<template>
<article class="markdown-body" >// Add class="markdown-body" to display the markdown style<h1>The title</h1>
<p>Expand the amplification</P>
</article>
</template>
Copy the code
12. Support the introduction of Markdown files in projects
- SRC create a new plugins directory and add the md.ts file
import path from 'path'
import fs from 'fs'
import marked from 'marked';
const mdToJs = str= > {
const content = JSON.stringify(marked(str))
return `export default ${content}`
}
export function md() {
return {
configureServer: [ // For development purposes
async ({ app }) => {
app.use(async (ctx, next) => { // koa
if (ctx.path.endsWith('.md')) {
ctx.type = 'js'
const filePath = path.join(process.cwd(), ctx.path)
ctx.body = mdToJs(fs.readFileSync(filePath).toString())
} else {
await next()
}
})
},
],
transforms: [{ // for rollup // plug-in
test: context= > context.path.endsWith('.md'),
transform: ({ code }) = > mdToJs(code)
}]
}
}
Copy the code
- Install marked:
yarn add --dev marked
- SRC create vite. Config. ts, import plugins/md.ts, and pass it to plugins
import { md } from "./plugins/md";
export default {
plugins: [md()]
};
Copy the code
- Using the instance
Md file
<template>
<article class="markdown-body" v-html="md">
</article>
</template>
<script lang="ts">
import md from '.. /markdown/intro.md';
export default {
data() {
return {
md
}
}
}
</script>
Copy the code
13. CreateApp and h functions
- Use the createApp API to return an application instance, and you can continue to call other methods through the chain
//openDialog.ts
import Dialog from './Dialog.vue';
import {createApp,h} from 'vue';
export const openDialog = (options) = >{
const {title,content,ok,cancel,closeOnClickOverlay}= options;
const div = document.createElement('div');
document.body.appendChild(div);
const close=() = >{
app.unmount(div);
div.remove();
}
const app =createApp({
render(){
return h(
Dialog,
{
visible:true."onUpdate:visible":(newVisible) = >{
if (newVisible===false){
close();
}
},
ok,
cancel,
closeOnClickOverlay
},
{title,content}
)
}
});
app.mount(div);
}
Copy the code
14. Display source code
- Modify the configuration of the vite. Config. ts file
import fs from 'fs'
import {baseParse} from '@vue/compiler-core'
export default {
vueCustomBlockTransforms: {
demo: (options) = > {
const { code, path } = options
const file = fs.readFileSync(path).toString()
const parsed = baseParse(file).children.find(n= > n.tag === 'demo')
const title = parsed.children[0].content
const main = file.split(parsed.loc.source).join(' ').trim()
return `export default function (Component) {
Component.__sourceCode = The ${JSON.stringify(main)
}
Component.__sourceCodeTitle = The ${JSON.stringify(title)}} `.trim()
}
}
};
Copy the code
- Appended to template in Switch1demo
<demo> General usage </demo>
- In the switchDemo. vue parent component reference Switch1Demo, add the preview
<div class="demo">
<h2>Regular use</h2>
<div class="demo-component">
<component :is="Switch1Demo"/>// Here is the component</div>
<div class="demo-actions">
<Button>Look at the code</Button>
</div>
<div class="demo-code">
<pre>{{Switch1Demo.__sourceCode}}</pre>// Here is the source code for the component</div>
</div>
Copy the code
15. Highlight source code
Install prismjs YARN add Prismjs
2. Import switchDemo. vue where Demo is used
import 'prismjs'
const Prism = (window as any) .Prism
Copy the code
3, look at themes in node_modules prismjs and prisms. CSS, which are the CSS styles that can be referenced, and import them in switchDemo. vue where Demo is used
import 'prismjs/themes/prism.css'
Copy the code
4. Use prism.highlight to highlight the source code
<pre class="language-html" v-html="Prism.highlight(Switch2Demo.__sourceCode, Prism.languages.html, 'html')" />
Copy the code
Rollup package library files and release NPM
1. Create the sr/lib/index.ts file to export components
SRC create rollup.config.js and tell rollup how to package
// Install rollup-plugin-esbuild rollup-plugin-vue rollup-plugin-scss sass rollup-plugin-terser
// Change name to your library name
import esbuild from 'rollup-plugin-esbuild'
import vue from 'rollup-plugin-vue'
import scss from 'rollup-plugin-scss'
import dartSass from 'sass';
import { terser } from "rollup-plugin-terser"
export default {
input: 'src/lib/index.ts'.output: [{
globals: {
vue: 'Vue'
},
name: 'Bobo'.file: 'dist/lib/bobo.js'.format: 'umd'.plugins: [terser()]
}, {
name: 'Bobo'.file: 'dist/lib/bobo.esm.js'.format: 'es'.plugins: [terser()]
}],
plugins: [
scss({ include: /\.scss$/, sass: dartSass }),
esbuild({
include: /\.[jt]s$/,
minify: process.env.NODE_ENV === 'production'.target: 'es2015'
}),
vue({
include: /\.vue$/,}})]Copy the code
3. Install rollup(global or local) and run rollup -c in the project root directory
Yarn Global add rollup // InstallCopy the code
4. Update the package.json file
5. Release NPM
- Example Change the NPM source to the official source
NPM config get registry / / view the source of NPM NPM config set registry / / modify NPM source at https://registry.npmjs.org/Copy the code
Tip: NRM quickly switches sources
- Log in to NPM website to register as a user
- Project terminal operation
npm login
, enter user name, password, email login (usenpm logout
Can log out) - Project terminal operation
npm publish
, you can publish the packaged library files to NPM - Log in to NPM official website, login account, click on the top right corner of the picture, view packages, you can see your published packages
- Next time, re-rollup -c, change the version number in package.json, and re-npm publish
Automated deployment
1. Modify the vite. Config. ts configuration file (the configuration file cannot be added.
2. Create a source repository on Github. The procedure is omitted
3. Create the automatic script deploy.sh to implement one-click deployment
Note: Orgin source needs to be changed to its own Github repository address
Viii. Problem solving
To complement…