如何使用Vue3.2+Vite2.7从0快速打造一个UI组件库

目录
  • 1. 前言
  • 2. 使用Vite搭建官网
    • 2.1 创建项目
      • 2.1.1. 全局安装vite(这里我装的时候是2.7.2)
      • 2.1.2. 构建一个vue模板(项目名可以改成自己的名字)
      • 2.1.3. 装好之后按照提示逐步执行命令
    • 2.2 基本完成官网的搭建
      • 2.2.1. 下载vue-router
      • 2.2.2. 创建home首页与doc文档页 以及顶部导航栏
      • 2.2.3. 配置路由
  • 3. 封装一个Button组件
  • 4. 封装Markdown组件介绍文档
    • 4.1. 下载
    • 4.2. main.ts中引入
    • 4.3. vite.config.js中配置vite-plugin-markdown插件
    • 4.4. 封装Markdown组件
    • 4.5. 创建介绍页面路由
  • 5. 自定义代码块获取组件展示源代码
    • 5.1. 自定义插件vue-custom-blocks-plugin
    • 5.2. 在vite.config.ts中配置
    • 5.3. 封装Preview组件展示
    • 5.4. 使用Preview组件
    • 5.5. 高亮源代码
  • 6. 去掉示例中的文件导入
    • 6.1. 在lib目录下创建main.ts 这个也是作为之后打包上传至npm的入口
    • 6.2. main.ts中导入注册
    • 6.4. 效果
  • 7. 部署到github官网
    • 7.1. 打包
    • 7.2. 上传至github
    • 7.3. 进入仓库Settings最底层
    • 7.4. 找到GitHub Pages
    • 7.5. 选择master分支 点击保存 链接就生成了
    • 7.6 一键部署
  • 8. 上传至npm
    • 8.1. 创建rollup.config.js配置文件
    • 8.2. 执行命令打包
    • 8.3. 效果
    • 8.4. 上传至npm
  • 9. 最后

1. 前言

最近自己学习写了一个基于Vue3的组件库,感觉有点意思,这篇文章来记录一下我是怎么从0快速打造一个UI组件库的

  • 先来个预览 
  • 附上访问地址jw-ui
  • 上面网址打不开的话可以用这个jw-ui

2. 使用Vite搭建官网

Vite是尤雨溪开发的一种新型前端构建工具,具体介绍可以查看官方文档

2.1 创建项目

2.1.1. 全局安装vite(这里我装的时候是2.7.2)

$ yarn create vite@2.7.2

2.1.2. 构建一个vue模板(项目名可以改成自己的名字)

yarn create vite jw-ui --template vue

2.1.3. 装好之后按照提示逐步执行命令

cd jw-ui
yarn
yarn dev

可以看到界面

ps: 推荐的IDE和设置:VSCode + Volar

2.2 基本完成官网的搭建

2.2.1. 下载vue-router

yarn add vue-router@4

2.2.2. 创建home首页与doc文档页 以及顶部导航栏

/* /views/home/index.vue 首页*/
<template>
    <div>
        Home
    </div>
</template>
/* /views/doc/index.vue 文档页面 */
<template>
  <div>
    Doc
  </div>
</template>
/* /components/Topnav.vue 顶部导航栏组件 */
<template>
  <div class="topnav">
    <router-link to="/home">首页</router-link>
    <router-link to="/doc">文档</router-link>
  </div>
</template>

2.2.3. 配置路由

创建路由配置文件

// router/index.ts
import { createRouter, createWebHashHistory } from "vue-router";
const history = createWebHashHistory();

const router = createRouter({
  history,
  routes: [
    { path: "/", redirect: "" },
  ],
});

export default router;

在main.ts里导入,使得整个应用支持路由。

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";

const app = createApp(App);
app.use(router);

app.mount("#app");

修改App.vue

<template>
  <Topnav />
  <router-view />
</template>
<script setup>
import Topnav from "./components/Topnav.vue";
</script>

到目前为止的效果

装饰一下顶部导航栏后的效果

这里首页按照自己喜欢的来写CSS就好了,接下来讲一下文档页面。

文档页需要一个侧边栏来切换不同组件的文档,这里我就举例做一个Button组件

// doc/index.vue
<template>
  <div class="layout">
    <div class="content">
      <aside>
        <router-link class="menu-item text-overflow" to="/doc/button"
          >Button 组件</router-link
        >
      </aside>
      <main style="padding-left: 302px">
        <router-view />
      </main>
    </div>
</template>
// router/index.ts 添加一个展示的button页面
import { createRouter, createWebHashHistory } from "vue-router";

import Home from "../views/home/index.vue";
import Doc from "../views/doc/index.vue";
import ButtonDoc from "../views/doc/button/index.vue";

const history = createWebHashHistory();

const router = createRouter({
  history,
  routes: [
    { path: "/", redirect: "/home" },
    { path: "/home", component: Home },
    {
      path: "/doc",
      component: Doc,
      children: [{ path: "button", component: ButtonDoc }],
    },
  ],
});

export default router;
// /views/doc/button/index
<template>
  <Button />
</template>

<script setup>
import Button from '../../../lib/button/index.vue'
</script>

<style lang="scss" scoped>

</style>

展示效果

好了到这里官网总算是基本搭建完了,我们终于就可以愉快的在src/lib/button/index.vue文件里封装组件啦。(封装的组件都放在lib文件夹里,以后打包用

3. 封装一个Button组件

下面附上我写的一个Button组件以及使用效果

PS: 需要注意的一点是封装的样式一定要加自己独特的前缀我这里是 jw 以避免在项目中产生样式重叠

<template>
  <button class="jw-button" :class="classes">
    <span v-if="loading" class="jw-loadingIndicator"></span>
    <slot> {{ theme }} </slot>
  </button>
</template>
<script setup lang="ts">
import { computed } from "vue";
const props = defineProps({
  theme: {
    type: String,
    default: "default",
  },
  dashed: {
    type: Boolean,
    default: false,
  },
  size: {
    type: String,
    default: "default",
  },
  round: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  loading: {
    type: Boolean,
    default: false,
  },
});

const { theme, dashed, size, round, disabled } = props;
const classes = computed(() => {
  return {
    [`jw-theme-${theme}`]: theme,
    [`jw-theme-dashed`]: dashed,
    [`jw-size-${size}`]: size,
    [`is-round`]: round,
    [`is-disabled`]: disabled,
  };
});
</script>

<script lang="ts">
export default {
  name: "JwButton",
};
</script>

<style lang="scss" scoped>
$h-default: 32px;
$h-small: 20px;
$h-large: 48px;
$white: #fff;
$default-color: #333;
$primary-color: #36ad6a;
$info-color: #4098fc;
$success-color: #85ce61;
$warning-color: #f0a020;
$error-color: #d03050;
$grey: grey;

$default-border-color: #d9d9d9;

$radius: 3px;
$green: #18a058;

.jw-button {
  box-sizing: border-box;
  height: $h-default;
  background-color: #fff;
  padding: 0 12px;
  cursor: pointer;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  white-space: nowrap;
  border-radius: $radius;
  box-shadow: 0 1px 0 fade-out(black, 0.95);
  transition: all 250ms;
  color: $default-color;
  border: 1px solid $default-border-color;
  user-select: none;

  &:focus {
    outline: none;
  }

  &::-moz-focus-inner {
    border: 0;
  }

  &.jw-size-large {
    font-size: 24px;
    height: $h-large;
    padding: 0 16px;
  }
  &.jw-size-small {
    font-size: 12px;
    height: $h-small;
    padding: 0 8px;
  }

  &.is-round.jw-size-default {
    border-radius: calc($h-default / 2);
  }
  &.is-round.jw-size-large {
    border-radius: calc($h-large / 2);
  }
  &.is-round.jw-size-small {
    border-radius: calc($h-small / 2);
  }

  &.jw-theme-default {
    &:hover {
      color: $green;
      border-color: $green;

      > .jw-loadingIndicator {
        border-style: dashed;
        border-color: $green $green $green transparent;
      }
    }
    &:active {
      color: darken($green, 20%);
      border-color: darken($green, 20%);

      > .jw-loadingIndicator {
        border-style: dashed;
        border-color: darken($green, 20%) darken($green, 20%)
          darken($green, 20%) transparent;
      }
    }
    &.jw-theme-dashed {
      border-style: dashed;
    }
    > .jw-loadingIndicator {
      border-style: dashed;
      border-color: $default-color $default-color $default-color transparent;
    }
  }
  &.jw-theme-primary {
    background-color: $primary-color;
    border-color: $primary-color;
    color: $white;

    &:hover {
      background: lighten($primary-color, 20%);
      border-color: lighten($primary-color, 20%);
    }
    &:active {
      background-color: darken($primary-color, 20%);
      border-color: darken($primary-color, 20%);
    }

    &.is-disabled {
      cursor: not-allowed;
      background: lighten($primary-color, 20%);
      border-color: lighten($primary-color, 20%);
      &:hover {
        background: lighten($primary-color, 20%);
        border-color: lighten($primary-color, 20%);
      }
    }

    &.jw-theme-dashed {
      border-style: dashed;
      background-color: $white !important;
      color: $primary-color;

      > .jw-loadingIndicator {
        border-style: dashed;
        border-color: $primary-color $primary-color $primary-color transparent;
      }
    }
  }

  &.jw-theme-info {
    background-color: $info-color;
    border-color: $info-color;
    color: $white;
    &:hover {
      background: lighten($info-color, 20%);
      border-color: lighten($info-color, 20%);
    }
    &:active {
      background-color: darken($info-color, 20%);
      border-color: darken($info-color, 20%);
    }

    &.is-disabled {
      cursor: not-allowed;
      background: lighten($info-color, 20%);
      border-color: lighten($info-color, 20%);
      &:hover {
        background: lighten($info-color, 20%);
        border-color: lighten($info-color, 20%);
      }
    }

    &.jw-theme-dashed {
      border-style: dashed;
      background-color: $white !important;
      color: $info-color;

      > .jw-loadingIndicator {
        border-style: dashed;
        border-color: $info-color $info-color $info-color transparent;
      }
    }
  }

  &.jw-theme-success {
    background-color: $success-color;
    border-color: $success-color;
    color: $white;
    &:hover {
      background: lighten($success-color, 20%);
      border-color: lighten($success-color, 20%);
    }
    &:active {
      background-color: darken($success-color, 20%);
      border-color: darken($success-color, 20%);
    }

    &.is-disabled {
      cursor: not-allowed;
      background: lighten($success-color, 20%);
      border-color: lighten($success-color, 20%);
      &:hover {
        background: lighten($success-color, 20%);
        border-color: lighten($success-color, 20%);
      }
    }

    &.jw-theme-dashed {
      border-style: dashed;
      background-color: $white !important;
      color: $success-color;

      > .jw-loadingIndicator {
        border-style: dashed;
        border-color: $success-color $success-color $success-color transparent;
      }
    }
  }

  &.jw-theme-warning {
    background-color: $warning-color;
    border-color: $warning-color;
    color: $white;
    &:hover {
      background: lighten($warning-color, 20%);
      border-color: lighten($warning-color, 20%);
    }
    &:active {
      background-color: darken($warning-color, 20%);
      border-color: darken($warning-color, 20%);
    }

    &.is-disabled {
      cursor: not-allowed;
      background: lighten($warning-color, 20%);
      border-color: lighten($warning-color, 20%);
      &:hover {
        background: lighten($warning-color, 20%);
        border-color: lighten($warning-color, 20%);
      }
    }

    &.jw-theme-dashed {
      border-style: dashed;
      background-color: $white !important;
      color: $warning-color;

      > .jw-loadingIndicator {
        border-style: dashed;
        border-color: $warning-color $warning-color $warning-color transparent;
      }
    }
  }

  &.jw-theme-error {
    background-color: $error-color;
    border-color: $error-color;
    color: $white;
    &:hover {
      background: lighten($error-color, 20%);
      border-color: lighten($error-color, 20%);
    }
    &:active {
      background-color: darken($error-color, 20%);
      border-color: darken($error-color, 20%);
    }

    &.is-disabled {
      cursor: not-allowed;
      background: lighten($error-color, 20%);
      border-color: lighten($error-color, 20%);
      &:hover {
        background: lighten($error-color, 20%);
        border-color: lighten($error-color, 20%);
      }
    }

    &.jw-theme-dashed {
      border-style: dashed;
      background-color: $white !important;
      color: $error-color;

      > .jw-loadingIndicator {
        border-style: dashed;
        border-color: $error-color $error-color $error-color transparent;
      }
    }
  }

  > .jw-loadingIndicator {
    width: 14px;
    height: 14px;
    display: inline-block;
    margin-right: 4px;
    border-radius: 8px;
    border-color: $white $white $white transparent;
    border-style: solid;
    border-width: 2px;
    animation: jw-spin 1s infinite linear;
  }
}

@keyframes jw-spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>

虽然有不完美,但差不多就这个意思吧

4. 封装Markdown组件介绍文档

4.1. 下载

vite-plugin-markdown:一个插件可以让你导入Markdown文件作为各种格式的vite项目。

github-markdown-css:复制GitHub Markdown风格

yarn add github-markdown-css vite-plugin-markdown

4.2. main.ts中引入

import "github-markdown-css";

4.3. vite.config.js中配置vite-plugin-markdown插件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
const md = require("vite-plugin-markdown");

export default defineConfig({
  plugins: [vue(),
    md.plugin({
    mode: ["html", "vue"],
  }),]
})

4.4. 封装Markdown组件

// /components/Markdown.vue
<template>
  <article class="markdown-body" v-html="content"></article>
</template>

<script setup lang="ts">
// 传入的md文件
const props = defineProps({
  content: {
    type: String,
    required: true,
  },
});
</script>

4.5. 创建介绍页面路由

import { h } from "vue";
import { createRouter, createWebHashHistory } from "vue-router";

import Home from "../views/home/index.vue";
import Doc from "../views/doc/index.vue";
import ButtonDoc from "../views/doc/button/index.vue";

const history = createWebHashHistory();

import Markdown from "../components/Markdown.vue";
const md = (string) => h(Markdown, { content: string, key: string });
import { html as Intro } from "../../markdown/intro.md";
const IntroDoc = md(Intro);

const router = createRouter({
  history,
  routes: [
    { path: "/", redirect: "/home" },
    { path: "/home", component: Home },
    {
      path: "/doc",
      component: Doc,
      children: [
        { path: "intro", component: IntroDoc },
        { path: "button", component: ButtonDoc },
      ],
    },
  ],
});

export default router;

可以看到,最终md就能导入,并且生成了github上md的样式了

5. 自定义代码块获取组件展示源代码

5.1. 自定义插件vue-custom-blocks-plugin

import path from "path";
import fs from "fs";
import { baseParse } from "@vue/compiler-core";
const vitePluginVue = {
  name: "preview",
  transform(code, id) {
    if (
      !/\/src\/views\/doc\/.*\.preview\.vue/.test(id) ||
      !/vue&type=preview/.test(id)
    ) {
      return;
    }

    let path = `.${id.match(/\/src\/views\/doc\/.*\.preview\.vue/)[0]}`;
    const file = fs.readFileSync(path).toString();
    const parsed = baseParse(file).children.find((n) => n.tag === "preview");
    const title = parsed.children[0].content;
    const main = file.split(parsed.loc.source).join("").trim();
    return `export default function (Component) {
      Component.__sourceCode = ${JSON.stringify(main)}
      Component.__sourceCodeTitle = ${JSON.stringify(title)}
    }`.trim();
  },
};

export default vitePluginVue;

5.2. 在vite.config.ts中配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
const md = require("vite-plugin-markdown");
import vitePluginVue from "./plugins/vue-custom-blocks-plugin";

export default defineConfig({
  plugins: [vue(),
    md.plugin({
    mode: ["html", "vue"],
  }),
  vitePluginVue]
})

5.3. 封装Preview组件展示

<template>
  <div class="pre">
    <h2>
      {{ component.__sourceCodeTitle }}
      <Button @click="hideCode" v-if="codeVisible">隐藏代码</Button>
      <Button @click="showCode" v-else>查看代码</Button>
    </h2>
    <div class="pre-component">
      <component :is="component" />
    </div>

    <div class="pre-code" v-if="codeVisible">
      <pre class="language-html">{{ component__sourceCOde }}</pre>
    </div>
  </div>
</template>

<script setup lang="ts">
import Button from "../lib/button/index.vue";
import { computed, ref } from "vue";
const props = defineProps({
  component: Object,
});

const showCode = () => (codeVisible.value = true);
const hideCode = () => (codeVisible.value = false);
const codeVisible = ref(false);
</script>

<style lang="scss" scoped>
$border-color: #d9d9d9;

.pre {
  border: 1px solid $border-color;
  margin: 16px 0px 32px;
  max-width: 700px;
  min-width: 300px;
  > h2 {
    font-size: 20px;
    padding: 8px 16px;
    border-bottom: 1px solid $border-color;
    display: flex;
    justify-content: space-between;
  }

  &-component {
    padding: 16px;
  }

  &-actions {
    padding: 8px 16px;
    border-top: 1px dashed $border-color;
  }

  &-code {
    padding: 8px 16px;
    border-top: 1px dashed $border-color;

    > pre {
      line-height: 1.1;
      font-family: Consolas, "Courier New", Courier, monospace;
      margin: 0;
      background-color: #fff;
    }
  }
}
</style>

5.4. 使用Preview组件

views/doc/button/index.vue

<template>
  <div>
    <Preview :component="Button1" />
  </div>
</template>

<script setup>
import Button1 from "./Button1.preview.vue";
import Preview from "../../../components/Preview.vue";
</script>

<style lang="scss">
.jw-button + .jw-button {
  margin-left: 20px;
}
</style>

/views/doc/button/Button1.preview.vue

<preview>基础示例</preview>
<template>
  <Button />
</template>

<script setup lang="ts">
import Button from "../../../lib/button/index.vue";
</script>

现在,只要编写上面的以.preview.vue后缀的文件就行了。

  • 效果:

5.5. 高亮源代码

下载prismjs

yarn add prismjs

对Preview组件做修改

<template>
  <div class="pre">
    <h2>
      {{ component.__sourceCodeTitle }}
      <Button @click="hideCode" v-if="codeVisible">隐藏代码</Button>
      <Button @click="showCode" v-else>查看代码</Button>
    </h2>
    <div class="pre-component">
      <component :is="component" />
    </div>

    <div class="pre-code" v-if="codeVisible">
      <pre class="language-html" v-html="html" />
    </div>
  </div>
</template>
<script setup lang="ts">
import Button from "../lib/button/index.vue";
import { computed, ref } from "vue";
import "prismjs";
import "prismjs/themes/prism.css";
const Prism = (window as any).Prism;
const props = defineProps({
  component: Object,
});

console.log(props.component.__sourceCode);
const html = computed(() => {
  return Prism.highlight(
    props.component.__sourceCode,
    Prism.languages.html,
    "html"
  );
});
const showCode = () => (codeVisible.value = true);
const hideCode = () => (codeVisible.value = false);
const codeVisible = ref(false);
</script>
  • 效果

6. 去掉示例中的文件导入

6.1. 在lib目录下创建main.ts 这个也是作为之后打包上传至npm的入口

import { App } from "vue";
import JwButton from "./button/index.vue";
export {  JwButton };
const components = [JwButton];

// 全局注册主键
export function registerJwUi(app: App): void {
  for (const component of components) {
    app.component(component.name, component);
  }
}

export default registerJwUi;

6.2. main.ts中导入注册

import JwUi from "./lib/index";
app.use(JwUi);

6.3. 这样在示例中就可以直接用了/src/views/doc/button/Button1.preview

<preview>基础示例</preview>
<template>
  <jw-button />
</template>

6.4. 效果

7. 部署到github官网

7.1. 打包

yarn build

7.2. 上传至github

github创建一个新的仓库 将dist上传只仓库

7.3. 进入仓库Settings最底层

7.4. 找到GitHub Pages

7.5. 选择master分支 点击保存 链接就生成了

7.6 一键部署

创建deploy.sh文件

rm -rf dist &&
yarn build &&
cd dist &&
git init &&
git add . &&
git commit -m "update" &&
git branch -M master &&
git remote add origin git@github.com:coderyjw/jw-ui-website.git &&
git push -f -u origin master &&
cd -
echo https://coderyjw.github.io/jw-ui-website/

执行命令

sh deploy.sh

8. 上传至npm

8.1. 创建rollup.config.js配置文件

// 为了保证版本一致,请复制我的 package.json 到你的项目,并把 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"
import alias from '@rollup/plugin-alias'
import path from "path";
import resolve from 'rollup-plugin-node-resolve'

export default {
  input: 'src/lib/index.ts',
  output: [{
    globals: {
      vue: 'Vue'
    },
    name: 'Yjw-ui',
    file: 'dist/lib/yjw-ui.js',
    format: 'umd',
    plugins: [terser()]
  }, {
    name: 'Yjw-ui',
    file: 'dist/lib/yjw-ui.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$/,
    }),
    alias({
      entries: [
        {
          find: '@', // 别名名称,作为依赖项目需要使用项目名
          replacement: path.resolve(__dirname, 'src'),
          customResolver: resolve({
            extensions: ['.js', '.jsx', '.vue', '.sass', '.scss']
          })
        }
      ]
    }),
  ],
}

8.2. 执行命令打包

rollup -c

8.3. 效果

可以看到dist文件下有lib文件,就是打包后的文件

8.4. 上传至npm

需要先注册npm账号

npm login // 先登录
npm publish // 发布

9. 最后

到此这篇关于如何使用Vue3.2+Vite2.7从0快速打造一个UI组件库的文章就介绍到这了,更多相关Vue3.2+Vite2.7打造UI组件库内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue3如何按需加载第三方组件库详解

    前言 以Element Plus为例,配置按需加载组件和样式. 环境 vue3.0.5 vite2.3.3 安装 Element Plus yarn add element-plus # OR npm install element-plus --save 完整引入 import { createApp } from 'vue' import ElementPlus from 'element-plus'; import 'element-plus/lib/theme-chalk/index.c

  • 使用vue3+TS实现简易组件库的全过程

    目录 前置 组件编写 dropdown form 验证 总结 前置 首先下载vue-cli,搭建我们的环境,vue-create-luckyUi,选择vue3和TypeScript .在src目录下创建package作为组件目录.再安装bootstrap,用bootstrap里面的样式来完成我们的组件. 组件编写 dropdown 首先查看boorstrap文档,是这样用的 <div class="dropdown"> <button class="btn

  • Vue3搭建组件库开发环境的示例详解

    目录 1 packages 目录 1.1 foo 目录 1.2 yyg-demo-ui 目录 2 实现 foo 示例组件 2.1 初始化 package.json 2.2 初始化 foo 目录结构 2.3 定义 foo 组件的 props 2.4 实现 foo 组件 2.5 定义 foo 组件入口文件 3 实现 yyg-demo-ui 3.1 初始化 package.json 3.2 安装依赖 3.3 定义入口文件 前文已经初始化了 workspace-root,从本文开始就需要依次搭建组件库.

  •  用Vue Demi 构建同时兼容Vue2与Vue3组件库

    目录 前言: 一.Vue Demi 中的额外 API 1.isVue2 and isVue3 二.Vue Demi 入门 前言: Vue Demi 是一个很棒的包,具有很多潜力和实用性.我强烈建议在创建下一个 Vue 库时使用它. 根据创建者 Anthony Fu 的说法,Vue Demi 是一个开发实用程序,它允许用户为 Vue 2 和 Vue 3 编写通用的 Vue 库,而无需担心用户安装的版本. 以前,要创建支持两个目标版本的 Vue 库,我们会使用不同的分支来分离对每个版本的支持.对于现

  • vue3.0 移动端二次封装van-uploader实现上传图片(vant组件库)

    1.前提:业务需求,最多上传6张图片,并可以实现本地预览 2.解决方法:使用vant组件库中的van-uploader实现 3.代码实现 template <div class="upload-oss"> <van-uploader :after-read="onRead" :before-read="beforeRead" :accept="fileType" v-model="fileList&

  • vue3组件库Shake抖动组件搭建过程详解

    目录 正文 CSS样式 组件逻辑 单元测试 导出打包发布 正文 先看下效果 其实就是个抖动效果组件,实现起来也非常简单.之所以做这样一个组件是为了后面写Form表单的时候会用到它做一个规则校验,比如下面一个简单的登录页面,当点击登录会提示用户哪个信息没输入,当然这只是一个简陋的demo 接下来就开始我们的Shake组件实现 CSS样式 其实样式很简单,当你需要抖动的时候就给它添加个抖动的样式,不需要就移除这个样式即可.抖动效果就用CSS3中的transform的平移属性即可 @keyframes

  • 如何使用Vue3.2+Vite2.7从0快速打造一个UI组件库

    目录 1. 前言 2. 使用Vite搭建官网 2.1 创建项目 2.1.1. 全局安装vite(这里我装的时候是2.7.2) 2.1.2. 构建一个vue模板(项目名可以改成自己的名字) 2.1.3. 装好之后按照提示逐步执行命令 2.2 基本完成官网的搭建 2.2.1. 下载vue-router 2.2.2. 创建home首页与doc文档页 以及顶部导航栏 2.2.3. 配置路由 3. 封装一个Button组件 4. 封装Markdown组件介绍文档 4.1. 下载 4.2. main.ts中

  • 基于Vue 2.0的模块化前端 UI 组件库小结

    AT-UI 是一款基于 Vue.js 2.0 的轻量级.模块化前端 UI 组件库,主要用于快速开发 PC 网站产品. 专门为桌面应用程序构建,AT-UI 提供了一套 npm + webpack + babel 前端开发工作流程,以及一个体面的干净整洁的 UI 组件. 特性 基于 Vue 开发的 UI 组件 基于 npm + webpack + babel 的工作流,支持 ES2015 CSS 样式独立,保证不同的框架实现都能保持统一的 UI 风格( 详见: AT-UI Style) 提供友好的

  • 使用vue-cli4.0快速搭建一个项目的方法步骤

    前言 最近公司的项目终于到了空闲期,而闲不住的我终于把目标放到了项目的迁移上面 因为公司的项目比较早的原因(虽然当时vue-cli也出来了一段时间,但是不敢轻易尝试啊!) 所以使用的环境还是 vue2.x 版本的,而又因为公司的前端项目都是我来搭建的原因(并不是技术大佬,入职早!) 所以所有项目开发的时候一直在用的 vue-cli2.0,后来项目多了也没时间就没往 vue-cli3.0 迁移 现在终于到了空闲期,可以尝试着慢慢迁移了 本篇文章就是主要记录迁移的过程和 vue-cli3.0 的搭建

  • 从0快速搭建一个实用的MVVM框架(超详细)

    目录 前言 基于MVVM进行快速开发,上手即用.(重构已完成,正在编写SampleApp) 如何集成 1.继承BaseApplication 2.创建ViewModel扩展函数 3.引入一键生成代码插件(可选) 框架结构 mvvm Activity封装 Fragment封装 Adapter封装 LiveData封装 Navigation封装 ViewModel封装 辅助类封装 管理类封装 mvvm_navigation mvvm_network 结合Jetpack,构建快速开发的MVVM框架.

  • Vue3 企业级组件库框架搭建 pnpm monorepo实战示例

    目录 引言 1 组件库工程应该具备的功能 2 环境准备 3 搭建 monorepo 项目 3.1 创建项目 3.2 配置 workspace 引言 基于 vite3 vue3 的组件库基础工程 vue3-component-library-archetype 和用于快速创建该工程的工具 yyg-cli,但在中大型的企业级项目中,通常会自主搭建这些脚手架或加速器.优雅哥希望每位前端伙伴能知其所以然,故接下来的文章将进入 Vue3 企业级优雅实战 系列,整个系列将包括五大部分: 首先会分享如何从 0

  • vue3+ts+vite2项目实战踩坑记录

    目录 1.Vite创建vue3项目 2.配置别名alias 3.引入element-plus 4.glob全局导入 5.静态资源导入 总结: 1.Vite创建vue3项目 使用 NPM: npm init @vitejs/app 使用 Yarn: yarn create @vitejs/app 一个命令快速安装vite+ts+vue3项目: npm init @vitejs/app vite-app --template vue-ts 默认构建好的目录结构是不包含router和vuex的需要手动

  • vue3.0 CLI - 2.1 - component 组件入门教程

    我的 github 地址 - vue3.0Study - 阶段学习成果都会建立分支. 进入 src 文件夹,这是实际都工程文件夹,其他文件夹以及文件以后在了解. 3个文件夹  assets - 各类静态资源文件夹 - 比如 图片, css 文件等.  components - 组件文件夹, 组件是 vue 等 MVC 框架等核心概念,自行了解含义. view - 视图文件夹. 5个文件  app.vue.main.js - 主视图.配合 main.js 成为 vue 程序的主入口.router.

  • vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单

    我的 github 地址 - vue3.0Study- 阶段学习成果都会建立分支. 新组件 - 新路由 Forms.vue ( 下面仅介绍如何创立, 不进行介绍 ) : <template><div class="form"> <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>

  • vue3.0封装轮播图组件的步骤

    接着上一篇文章,熟悉vue3.0的基本用法,和使用一段时间以后,开始准备开发适用于vue3.0使用的pc端的组件库.会陆续跟新一些组件库的写法和注意事项,有兴趣的同学可以多多关注哦,不多bb,开始. 开发一个轮播图组件,适用pc端,(暂无考虑app), 使用于vue3.0 + TS 大致的实现效果是这样: 图片自由轮播,对应圆点图片跳转,左右指示器跳转等.暴露以下options配置: 以上是主要的options,下面展开来说一下具体如何封装. 一:封装思想 在vue3.0和vue2.0中封装组件

  • vue3.0+vant3.0快速搭建项目的实现

    目录 一.项目的搭建 二.vue3体验+vant引入 2020年09月18日,vue.js 3.0正式发布,去网上看了看关于3.0的教程都不够完整,但其实vuecli最新版已经支持了vue3.0项目的快速搭建,这篇文章将带你了解一下vue3.0有哪些新的改变以及如何快速搭建vue3.0项目. 一.项目的搭建 1.首先,nodejs的安装不用我多说了吧,nodejs官网地址. 2.既然vuecli最新版已经可以快速搭建3.0了,那怎么升级到最新版呢?vue-cli官网地址,不知道vue-cli版本

随机推荐