/SKILL.md
uni-app cross-platform frontend development with Vue 3 + TypeScript. Use for: (1) Creating new uni-app projects or pages, (2) Integrating UI libraries (uView Plus, uni-ui, TuniaoUI), (3) Implementing multi-theme design systems, (4) Building WeChat Mini Programs, H5, and other platforms, (5) Setting up SCSS theming and global styles, (6) Configuring Vite build system. Includes reusable templates, component patterns, and best practices applicable to any uni-app project.
npx skillsauth add enze00/uniapp-frontend-skills uniapp-frontendInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Comprehensive guide for building cross-platform apps with uni-app, Vue 3, and TypeScript.
# Create page directory
mkdir -p src/pages/newpage
# Create page files
touch src/pages/newpage/index.vue
{
"pages": [
{
"path": "pages/newpage/index",
"style": {
"navigationBarTitleText": "Page Title"
}
}
]
}
See assets/page-template.vue for a complete page template.
Standard uni-app CLI project structure:
src/
├── pages/ # Page components (one per directory)
├── components/ # Shared/reusable components
├── store/ # Pinia state management
├── api/ # API interface definitions
├── utils/ # Utility functions
├── types/ # TypeScript type definitions
├── styles/ # Global styles
│ ├── theme.scss # Theme variables
│ └── common.scss # Common styles
├── static/ # Static assets (images, icons)
├── App.vue # App root component
├── main.ts # App entry point
├── pages.json # Page and tabBar configuration
└── uni.scss # uni-app built-in variables
Installation:
npm install uview-plus
Configuration:
App.vue - Import styles:
<style lang="scss">
@import "uview-plus/index.scss";
@import "@/styles/common.scss";
</style>
main.ts - Register plugin:
import uviewPlus from "uview-plus";
app.use(uviewPlus);
vite.config.ts - Global SCSS:
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/theme.scss";@import "uview-plus/theme.scss";`,
api: "modern-compiler",
},
},
}
uni-ui (official):
npm install @dcloudio/uni-ui
TuniaoUI (Tuniao):
npm install @tuniao/tnui-vue3-uniapp
See references/ui-libraries.md for integration guides.
Implement flexible theming for multi-role or multi-brand applications.
src/styles/theme.scss:
// Theme colors
$theme-primary: #1890ff;
$theme-success: #52c41a;
$theme-warning: #faad14;
$theme-error: #f5222d;
// Neutral colors
$color-text-primary: #333333;
$color-text-regular: #666666;
$color-text-secondary: #999999;
$color-bg-page: #f5f5f5;
$color-bg-card: #ffffff;
// Spacing scale
$spacing-xs: 8rpx;
$spacing-sm: 16rpx;
$spacing-md: 24rpx;
$spacing-lg: 32rpx;
$spacing-xl: 48rpx;
// Typography
$font-size-xs: 20rpx;
$font-size-sm: 24rpx;
$font-size-base: 28rpx;
$font-size-lg: 32rpx;
$font-size-xl: 36rpx;
// Border radius
$border-radius-sm: 4rpx;
$border-radius-md: 8rpx;
$border-radius-lg: 16rpx;
$border-radius-circle: 50%;
vite.config.ts - Inject globally:
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/theme.scss";`,
api: "modern-compiler",
},
},
}
For apps requiring multiple themes (e.g., user/admin, different brands):
Option 1: Theme variables per environment
// src/styles/theme.scss
// Define different theme color sets
$theme-user-primary: #1890ff;
$theme-admin-primary: #0050b3;
// Set active theme
$theme-primary: $theme-user-primary; // Change based on build/env
Option 2: Dynamic theme switching
// store/theme.ts
import { defineStore } from 'pinia';
export const useThemeStore = defineStore('theme', {
state: () => ({
currentTheme: 'default',
}),
getters: {
themeColors() {
const themes = {
default: { primary: '#1890ff' },
dark: { primary: '#0050b3' },
};
return themes[this.currentTheme];
},
},
});
See references/theme-guide.md for complete theming patterns.
# WeChat Mini Program
npm run dev:mp-weixin # Development
npm run build:mp-weixin # Production
# H5
npm run dev:h5 # Development
npm run build:h5 # Production
# Other platforms
npm run dev:mp-alipay # Alipay Mini Program
npm run dev:mp-baidu # Baidu Mini Program
npm run dev:mp-toutiao # Toutiao Mini Program
<script setup lang="ts">
import { ref, onMounted } from "vue";
interface Item {
id: number;
title: string;
}
const items = ref<Item[]>([]);
const loading = ref(false);
const error = ref<string | null>(null);
onMounted(() => {
loadData();
});
const loadData = async () => {
loading.value = true;
error.value = null;
try {
const data = await api.getItems();
items.value = data;
} catch (err) {
error.value = "Failed to load data";
uni.showToast({ title: error.value, icon: "none" });
} finally {
loading.value = false;
}
};
</script>
// Navigate to page (adds to history stack)
uni.navigateTo({ url: "/pages/detail/index" });
// Navigate with parameters
uni.navigateTo({ url: `/pages/detail/index?id=${id}&type=parcel` });
// Redirect (replaces current page, no back button)
uni.redirectTo({ url: "/pages/login/index" });
// Switch to tabBar page
uni.switchTab({ url: "/pages/home/index" });
// Navigate back
uni.navigateBack();
// Launch another mini program
uni.navigateToMiniProgram({
appId: "xxxxx",
path: "pages/index/index",
});
Toast:
uni.showToast({
title: "Success",
icon: "success",
duration: 2000,
});
uni.showToast({
title: "Error message",
icon: "none",
});
// Loading toast
uni.showLoading({ title: "Loading..." });
uni.hideLoading();
Modal:
uni.showModal({
title: "Confirm",
content: "Are you sure?",
success: (res) => {
if (res.confirm) {
// User clicked confirm
}
},
});
Action Sheet:
uni.showActionSheet({
itemList: ["Option 1", "Option 2", "Option 3"],
success: (res) => {
console.log("Selected:", res.tapIndex);
},
});
<script setup lang="ts">
import {
onLaunch,
onShow,
onHide,
onUnload,
} from "@dcloudio/uni-app";
import { onLoad, onReady, onReachBottom, onPullDownRefresh } from "@dcloudio/uni-app";
// App-level hooks (use in App.vue)
onLaunch(() => {
console.log("App launched");
});
onShow(() => {
console.log("App shown");
});
// Page-level hooks (use in pages)
onLoad((options) => {
console.log("Page loaded with params:", options);
});
onReady(() => {
console.log("Page ready");
});
onReachBottom(() => {
console.log("Reached bottom - load more");
});
onPullDownRefresh(() => {
console.log("Pull down refresh");
// Stop loading after data fetch
uni.stopPullDownRefresh();
});
</script>
// Get platform info
const systemInfo = uni.getSystemInfoSync();
console.log("Platform:", systemInfo.platform); // ios, android, devtools
console.log("System:", systemInfo.system); // iOS 14.5, Android 10
// Conditional code based on platform
// #ifdef H5
console.log("Running on H5");
// #endif
// #ifdef MP-WEIXIN
console.log("Running on WeChat Mini Program");
// #endif
// #ifdef MP-ALIPAY
console.log("Running on Alipay Mini Program");
// #endif
Store definition:
// src/store/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
userInfo: null,
token: '',
}),
getters: {
isLoggedIn: (state) => !!state.token,
},
actions: {
async login(credentials) {
const data = await api.login(credentials);
this.token = data.token;
this.userInfo = data.user;
},
logout() {
this.token = '';
this.userInfo = null;
},
},
});
Use in component:
<script setup lang="ts">
import { useUserStore } from "@/store/user";
const userStore = useUserStore();
// Access state
console.log(userStore.userInfo);
// Call actions
await userStore.login({ username, password });
// Use getters
if (userStore.isLoggedIn) {
// ...
}
</script>
API module:
// src/api/index.ts
const BASE_URL = "https://api.example.com";
export const api = {
// GET request
async getItems() {
const res = await uni.request({
url: `${BASE_URL}/items`,
method: "GET",
});
return res.data;
},
// POST request
async createItem(data: any) {
const res = await uni.request({
url: `${BASE_URL}/items`,
method: "POST",
data,
});
return res.data;
},
};
With interceptors:
// src/utils/request.ts
let token = "";
export const request = (options: UniApp.RequestOptions) => {
// Add token
if (token) {
options.header = {
...options.header,
Authorization: `Bearer ${token}`,
};
}
return uni.request(options);
};
// Set token after login
export const setToken = (newToken: string) => {
token = newToken;
};
Error: Undefined variable $spacing-md
Solutions:
vite.config.ts has additionalData configurationCheck:
pages.json@/ alias)Common fixes:
rm -rf node_modules dist && npm installWeChat Mini Program:
manifest.jsonH5:
Complete theme system design with multi-theme patterns, color theory, and implementation strategies.
Integration guides for uView Plus, uni-ui, TuniaoUI, and other popular UI libraries.
Reusable page patterns: list pages, detail pages, forms, search/filter, empty states, etc.
Platform-specific considerations and best practices for WeChat, Alipay, H5, etc.
Minimal Vue 3 + TypeScript page template ready to customize.
Common component templates (card, button-group, list-item, etc.).
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.