大屏设计器开发 - 项目搭建

大屏设计器项目开发纪实之项目搭建篇。

创建项目

使用pnpm创建 vite + vue3 项目,终端执行pnpm create vite
选择 vue 模板中 Customize with create-vue
选择安装 ts, jsx, vue-router, pinia, elsint, prettier, vitest

使用pnpm workspace

文档参考:https://pnpm.io/zh/pnpm-workspace_yaml
根目录下新建文件pnpm-workspace.yaml
文件内容:

packages:
  - 'packages/*'

代码提交前校验

安装 husky, lint-staged, commitlint
对文件校验
因为配置了workspace,在根目录下安装依赖需要添加 -w 参数

pnpm add husky lint-staged -D -w

初始化husky

# 在package.json的script指令中添加prepare指令执行 husky install
npm set-script prepare "husky install"
# 执行 husky install
pnpm perpare

执行完根目录下会出现.husky文件夹
添加 pre-commit 执行钩子

npx husky add .husky/pre-commit "npx lint-staged"

根目录下新建.lintstagedrc.json,文件内容

{
  "*.{js,jsx,ts,tsx,vue}": [
    "prettier --write .",
    "eslint --fix"
  ],
  "*.md": [
    "prettier --write"
  ]
}

这表示在commit提交前,pre-commit这个钩子中触发执行lint-staged, lint-staged对暂存区的js, jsx. ts, tsx, vue, md尾缀的文件进行校验。

对提交信息校验

pnpm add commitlint @commitlint/config-conventional -D -w
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

@commitlint/config-conventional表示提交信息的校验安装默认的Angular提交规范,这也是业界常用的一种规范
根目录下新建.commitlintrc.json

{
  "extends": ["@commitlint/config-conventional"],
  "rules": {
    "type-enum": [2, "always", ["feat", "fix", "refactor", "test", "build", "docs", "chore"]],
    "subject-max-length": [1, "always", 150]
  }
}
类型 描述
build 编译相关的修改,例如发布版本、对项目构建或者依赖的改动
chore 其他修改, 比如改变构建流程、或者增加依赖库、工具等
ci 持续集成修改
docs 文档修改
feat 新特性、新功能
fix 修改bug
perf 优化相关,比如提升性能、体验
refactor 代码重构
style 代码格式修改, 注意不是 css 修改
test 测试用例修改
revert 回滚到上一个版本

主题切换方案
采用 css变量+类名切换+scss变量 方案
在样式文件中预先定义好 白天和黑暗两个主题色样式文件
style/light.scss

$light-text: #8c8c8c;
$light-border: #d9d9d9;
$light-background: #f8f8f8;
$light-color: #262626;

style/dark.scss

$dark-text: #dbdbdb;
$dark-border: #434343;
$dark-background: #262626;
$dark-color: #ffffff;

在theme.scss中使用这些scss变量来定义css变量值
注意:使用#{}语法嵌套scss变量才可以生效
style/theme.scss

@import './light.scss';
@import './dark.scss';
:root {
  --theme-color: #{$light-color};
  --theme-background: #{$light-background};
  --theme-border: #{$light-border};
}
.dark {
  --theme-color: #{$dark-color};
  --theme-background: #{$dark-background};
  --theme-border: #{$dark-border};
}

样式文件都需要在main.js中引入。
通过一个方法来控制html根节点上的class切换
utils/theme.ts

export function setTheme(type: string) {
  const htmlDom = document.documentElement
  const htmlClassNames = htmlDom.classList
  if (type === 'light' && htmlClassNames.contains('dark')) {
    htmlDom.classList.remove('dark')
  }
  if (type === 'dark') {
    htmlDom.classList.add('dark')
  }
}

在主题切换按钮上使用这个方法
components/Navigation/ThemeButton.vue

<template>
  <button class="switch" @click="handleSwitch">
    <span :class="['icon', isDark ? 'dark' : 'light']">
      <i :class="['iconfont', isDark ? 'icon-yueliang' : 'icon-taiyang']"></i>
    </span>
  </button>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { setTheme } from '@/utils/theme'
import { getLocalStorage, setLocalStorage } from '@/utils/storage'
let isDark = ref(false)
function handleSwitch() {
  isDark.value = !isDark.value
  let type = isDark.value ? 'dark' : 'light'
  setTheme(type)
  setLocalStorage('theme', type)
}
function initTheme() {
  let theme = getLocalStorage('theme')
  if (theme) {
    isDark.value = theme === 'light' ? false : true
    setTheme(theme)
  }
}
onMounted(() => initTheme())
</script>
<style scoped lang="scss">
.switch {
  position: relative;
  width: 40px;
  height: 22px;
  border-radius: 11px;
  background-color: var(--theme-background);
  border: 1px solid var(--theme-border);
  cursor: pointer;
}
.icon {
  position: absolute;
  top: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  transition: margin-right 2s;
}
.light {
  left: 1px;
  color: var(--theme-color);
}
.dark {
  right: 1px;
  color: var(--theme-color);
}
</style>

国际化方案

安装

安装 vue-i18n 最新版支持 vue3

pnpm add vue-i18n -w

使用

src/lang/index.ts

import { createI18n } from 'vue-i18n'
import zh from './zh'
import en from './en'

export const i18n = createI18n({
  legacy: false,
  locale: 'zh-cn',
  messages: {
    'zh-cn': { ...zh },
    'en-us': { ...en }
  }
})

lang/zh.ts

export default {
  title: '大屏设计器',
  'component-list': '组件列表',
  property: '属性',
  data: '数据',
  event: '事件',
  'canvas-size': '画布大小'
}
lang/zn.ts
export default {
  title: 'Large screen designer',
  'component-list': 'Component list',
  property: 'Property',
  data: 'Data',
  event: 'Event',
  'canvas-size': 'Canvas size'
}

在main.js中引入全局使用
main.js

import { i18n } from '@/lang'
app.use(i18n)

在模板中使用
例如,在头部标题组件中将名称字段改为国际化方案

<template>
  <div class="main">
    <div class="left"></div>
    <div class="title">{
   
   { $t('title') }}</div>
    <div class="right">
      <ThemeButton />
      <SwitchLanguage />
    </div>
  </div>
</template>

在 Composition API 中使用,需要使用computed改为响应式
components/sidebar-component/SidebarComponent.vue

import { useI18n } from 'vue-i18n'

const { t } = useI18n()
const TABS = reactive([
  { component: '1', name: computed(() => t('property')) },
  { component: '2', name: computed(() => t('data')) },
  { component: '3', name: computed(() => t('event')) }
])

代码仓库

zyf-designer项目地址: http://183.213.16.9:9005/zwd/zyf-designer

作者:左文东

猜你喜欢

转载自blog.csdn.net/ekcchina/article/details/129921738