feat: 整合UnoCSS和添加Tabbar

This commit is contained in:
ray
2024-09-20 22:52:20 +08:00
parent 0b7fe814d1
commit f106f84646
21 changed files with 959 additions and 163 deletions

15
.editorconfig Normal file
View File

@@ -0,0 +1,15 @@
# http://editorconfig.org
root = true
# 表示所有文件适用
[*]
charset = utf-8 # 设置文件字符集为 utf-8
end_of_line = lf # 控制换行类型(lf | cr | crlf)
indent_style = space # 缩进风格tab | space
indent_size = 2 # 缩进大小
insert_final_newline = true # 始终在文件末尾插入一个新行
# 表示仅 md 文件适用以下规则
[*.md]
max_line_length = off # 关闭最大行长度限制
trim_trailing_whitespace = false # 关闭末尾空格修剪

View File

@@ -3,8 +3,9 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
"source.fixAll": "explicit",
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"stylelint.validate": ["css", "scss", "vue", "html"]
}

View File

@@ -1,58 +1,32 @@
import globals from "globals"; // 全局变量配置
import jsPlugin from "@eslint/js"; // JavaScript 推荐配置
import tsPlugin from "@typescript-eslint/eslint-plugin"; // TypeScript 插件
import tsParser from "@typescript-eslint/parser"; // TypeScript 解析器
import vuePlugin from "eslint-plugin-vue"; // Vue 插件
import prettierConfig from "eslint-config-prettier"; // 禁用 ESLint 冲突规则
import pluginPrettier from "eslint-plugin-prettier"; // 引入 Prettier 插件
import pluginJs from "@eslint/js"; // JavaScript 推荐配置
import tseslint from "typescript-eslint"; // TypeScript 配置
import pluginVue from "eslint-plugin-vue"; // Vue 配置
export default [
// 1. 适用于所有文件的配置 (JavaScript、TypeScript、Vue)
{
files: ["**/*.{js,mjs,cjs,ts,vue}"], // 校验的文件类型
languageOptions: {
globals: globals.browser, // 设置浏览器环境的全局变量
},
},
{ files: ["**/*.{js,mjs,cjs,ts,vue}"] }, // 校验的文件类型
{ languageOptions: { globals: globals.browser } }, // 设置浏览器环境的全局变量
pluginJs.configs.recommended, // JavaScript 推荐配置
...tseslint.configs.recommended, // TypeScript 推荐配置
...pluginVue.configs["flat/essential"], // Vue 推荐配置
{ files: ["**/*.vue"], languageOptions: { parserOptions: { parser: tseslint.parser } } }, // 对 .vue 文件使用 TypeScript 解析器
// 2. 插件推荐的配置
jsPlugin.configs.recommended, // JavaScript 推荐配置
tsPlugin.configs.recommended, // TypeScript 推荐配置
vuePlugin.configs["flat/essential"], // Vue 推荐配置
// 3. Prettier 插件配置
prettierConfig, // 禁用 ESLint 中与 Prettier 冲突的规则
pluginPrettier.configs.recommended, // 启用 Prettier 插件
// 4. 对 .vue 文件的特殊处理,使用 TypeScript 解析器
{
files: ["**/*.vue"],
languageOptions: {
parserOptions: {
parser: tsParser, // 解析器指定为 TypeScript
},
},
},
// 5. 忽略不需要校验的文件和目录
// 添加忽略的文件或目录
{
ignores: [
"/dist", // 忽略打包生成的文件夹
"/public", // 忽略 public 文件夹
"/node_modules", // 忽略依赖模块文件夹
"**/*.min.js", // 忽略压缩后的 JS 文件
"**/*.config.mjs", // 忽略配置文件
"**/*.tsbuildinfo", // 忽略 TypeScript 构建信息文件
"/src/manifest.json", // 忽略 manifest 文件
"/dist",
"/public",
"/node_modules",
"**/*.min.js",
"**/*.config.mjs",
"**/*.tsbuildinfo",
"/src/manifest.json",
],
},
// 6. 自定义 ESLint 规则配置
// 自定义规则
{
rules: {
// Prettier 规则
"prettier/prettier": "error", // // 将 Prettier 的格式化错误标记为 ESLint 错误
// 通用规则
quotes: ["error", "double"], // 强制使用双引号
"quote-props": ["error", "always"], // 强制对象的属性名使用引号
semi: ["error", "always"], // 要求使用分号

View File

@@ -41,7 +41,7 @@
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
"type-check": "vue-tsc --noEmit",
"lint:eslint": "eslint --fix ./src",
"lint:eslint": "eslint --fix ./src/App.vue",
"lint:stylelint": "stylelint \"**/*.{css,scss,vue,html}\" --fix",
"lint:lint-staged": "lint-staged",
"prepare": "husky",
@@ -124,6 +124,8 @@
"stylelint-prettier": "^5.0.2",
"typescript": "^4.9.4",
"typescript-eslint": "^8.6.0",
"unocss": "^0.62.4",
"unocss-preset-weapp": "^0.62.2",
"vite": "5.2.8",
"vue-tsc": "^1.0.24"
}

742
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,13 +6,8 @@ onLaunch(() => {
onShow(() => {
console.log("App Hide");
});
onHide(() => {
console.log("App Hide");
});
</script>
<style lang="scss">
.container {
position: relative;
width: 100%;
height: 100vh;
padding: 1px;
background-color: #f5f5f5;
}
</style>
<style lang="scss" scoped></style>

View File

@@ -1,5 +1,7 @@
import { createSSRApp } from "vue";
import App from "./App.vue";
import "uno.css";
export function createApp() {
const app = createSSRApp(App);
return {

View File

@@ -1,72 +1,72 @@
{
"name" : "",
"appid" : "",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
"name": "",
"appid": "",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
/* 5+App */
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
/* */
"modules": {},
/* */
"distribute": {
/* android */
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios": {},
/* SDK */
"sdkConfigs": {}
}
},
/* */
"quickapp": {},
/* */
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics": {
"enable": false
},
"vueVersion" : "3"
"usingComponents": true
},
"mp-alipay": {
"usingComponents": true
},
"mp-baidu": {
"usingComponents": true
},
"mp-toutiao": {
"usingComponents": true
},
"uniStatistics": {
"enable": false
},
"vueVersion": "3"
}

View File

@@ -1,16 +1,53 @@
{
"pages": [ //pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/workbench/index",
"style": {
"navigationBarTitleText": "工作台"
}
},
{
"path": "pages/my/index",
"style": {
"navigationBarTitleText": "我的"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "vue-uniapp-template",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"color": "#474747",
"selectedColor": "#3B8DFF",
"backgroundColor": "#F8F8F8",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/tabbar/home.png",
"selectedIconPath": "static/tabbar/home-active.png"
},
{
"pagePath": "pages/workbench/index",
"text": "工作台",
"iconPath": "static/tabbar/workbench.png",
"selectedIconPath": "static/tabbar/workbench-active.png"
},
{
"pagePath": "pages/my/index",
"text": "我的",
"iconPath": "static/tabbar/my.png",
"selectedIconPath": "static/tabbar/my-active.png"
}
]
}
}

View File

@@ -1,25 +1,18 @@
<template>
<view class="content">
<view class="flex-center flex-col">
<image class="logo" src="/static/logo.png" />
<view class="text-area">
<text class="title">{{ title }}</text>
<view>
<text class="text-red font-bold text-lg">{{ title }}</text>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from "vue";
const title = ref("Hello");
const title = ref("Hello YouLai APP");
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
width: 200rpx;
height: 200rpx;
@@ -28,14 +21,4 @@ const title = ref("Hello");
margin-bottom: 50rpx;
margin-left: auto;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>

5
src/pages/my/index.vue Normal file
View File

@@ -0,0 +1,5 @@
<template>
<view class="flex-center flex-col">
<text class="text-blue font-bold text-lg">我的</text>
</view>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<view class="flex-center flex-col">
<text class="text-cyan font-bold text-lg">工作台</text>
</view>
</template>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
src/static/tabbar/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/static/tabbar/my.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,5 +1,4 @@
{
"extends": "@vue/tsconfig/tsconfig.json",
"compilerOptions": {
"sourceMap": true,
"baseUrl": ".",

28
unocss.config.ts Normal file
View File

@@ -0,0 +1,28 @@
import presetWeapp from "unocss-preset-weapp";
import { extractorAttributify, transformerClass } from "unocss-preset-weapp/transformer";
const { presetWeappAttributify, transformerAttributify } = extractorAttributify();
export default {
presets: [
// https://github.com/MellowCo/unocss-preset-weapp
presetWeapp(),
// attributify autocomplete
presetWeappAttributify(),
],
shortcuts: [
{
"border-base": "border border-gray-500_10",
"flex-center": "flex justify-center items-center",
"flex-x-center": "flex justify-center",
},
],
transformers: [
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerAttributify
transformerAttributify(),
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerClass
transformerClass(),
],
};

View File

@@ -1,7 +1,15 @@
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [uni()],
export default defineConfig(async () => {
const UnoCss = await import("unocss/vite").then((i) => i.default);
return {
plugins: [
uni(),
// https://github.com/unocss/unocss
UnoCss(),
],
};
});