feat: 把 docs 仓库移动到本仓库
3
.gitignore
vendored
@ -24,6 +24,9 @@ dist
|
|||||||
.stylelintcache
|
.stylelintcache
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
|
||||||
|
docs/.vitepress/dist
|
||||||
|
docs/.vitepress/cache
|
||||||
|
|
||||||
# lock 文件还是不要了,我主要的版本写死就好了
|
# lock 文件还是不要了,我主要的版本写死就好了
|
||||||
# pnpm-lock.yaml
|
# pnpm-lock.yaml
|
||||||
# package-lock.json
|
# package-lock.json
|
||||||
|
23
docs/.vitepress/components/BuildInfo.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<!-- .vitepress/components/BuildInfo.vue -->
|
||||||
|
<template>
|
||||||
|
<div class="build-info" :data-build-time="buildTime" :data-version="version">
|
||||||
|
<p>构建时间: {{ buildTime }}</p>
|
||||||
|
<p>版本号: {{ version }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { inject } from 'vue'
|
||||||
|
|
||||||
|
const buildTime = inject('buildTime')
|
||||||
|
const version = inject('version')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.build-info {
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
</style>
|
220
docs/.vitepress/config.mts
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { defineConfig } from 'vitepress'
|
||||||
|
import packageJson from '../../package.json'
|
||||||
|
|
||||||
|
const buildTime = dayjs().format('yyyy-MM-dd HH:mm:ss')
|
||||||
|
|
||||||
|
// https://vitepress.dev/reference/site-config
|
||||||
|
export default defineConfig({
|
||||||
|
lang: 'zh-CN',
|
||||||
|
base: '/unibest-docs/',
|
||||||
|
// base: '/',
|
||||||
|
title: 'unibest',
|
||||||
|
description: '最好用的 uniapp 开发模板',
|
||||||
|
lastUpdated: true,
|
||||||
|
cleanUrls: true,
|
||||||
|
head: [
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
name: 'keywords',
|
||||||
|
content: 'unibest, uniapp, uni-app, vue, vue3, vite,template, typescript, ts',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
name: 'author',
|
||||||
|
content: '菲鸽, 菲哥, 鸽鸽, feige996, feige996, 1020103647@qq.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
['link', { rel: 'icon', href: './favicon.ico' }], // 这里要加上 base 前缀,否则资源访问不到
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
name: 'twitter:title',
|
||||||
|
content: '最好用的 uniapp 开发模板',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 添加 ICP 备案信息
|
||||||
|
['meta', { name: 'icp', content: '粤ICP备2024160998号' }],
|
||||||
|
['link', { rel: 'license', href: 'https://beian.miit.gov.cn/' }],
|
||||||
|
// 其他杂七杂八的 meta 标签
|
||||||
|
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
|
||||||
|
['meta', { name: 'twitter:site', content: 'feige996' }],
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
name: 'twitter:image:src',
|
||||||
|
content:
|
||||||
|
'https://opengraph.githubassets.com/1cac1150838995e1f7d1643c00eee51a5d884f2054f995c9d3225b07b0eddb39/feige996/unibest',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
property: 'og:image',
|
||||||
|
content:
|
||||||
|
'https://opengraph.githubassets.com/1cac1150838995e1f7d1643c00eee51a5d884f2054f995c9d3225b07b0eddb39/feige996/unibest',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
property: 'og:image:alt',
|
||||||
|
content: '最好用的 uniapp 开发模板',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
['meta', { property: 'og:image:width', content: '1200' }],
|
||||||
|
['meta', { property: 'og:image:height', content: '600' }],
|
||||||
|
['meta', { property: 'og:site_name', content: 'GitHub' }],
|
||||||
|
['meta', { property: 'og:type', content: 'object' }],
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
property: 'og:title',
|
||||||
|
content: '最好用的 uniapp 开发模板',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
['meta', { property: 'og:url', content: 'https://github.com/feige996/unibest' }],
|
||||||
|
[
|
||||||
|
'meta',
|
||||||
|
{
|
||||||
|
property: 'og:description',
|
||||||
|
content: '最好用的 uniapp 开发模板',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 增加构建信息
|
||||||
|
['meta', { name: 'build-time', content: buildTime }],
|
||||||
|
['meta', { name: 'version', content: packageJson.version }],
|
||||||
|
// 下面是百度统计代码
|
||||||
|
['script', { async: '', src: 'https://hm.baidu.com/hm.js?081c2ec121383d9e7d5a35c5833ab6ff' }],
|
||||||
|
// 下面是不蒜子统计代码
|
||||||
|
['script', { async: '', src: '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js' }],
|
||||||
|
],
|
||||||
|
markdown: {
|
||||||
|
theme: {
|
||||||
|
light: 'vitesse-light',
|
||||||
|
dark: 'vitesse-dark',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
themeConfig: {
|
||||||
|
// https://vitepress.dev/reference/default-theme-config
|
||||||
|
logo: './logo.svg',
|
||||||
|
siteTitle: 'unibest',
|
||||||
|
nav: [
|
||||||
|
{
|
||||||
|
text: '快速开始',
|
||||||
|
link: '/base/2-start',
|
||||||
|
activeMatch: '/base',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '🥤 打赏',
|
||||||
|
link: '/advanced/rewards/rewards',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '相关链接',
|
||||||
|
link: '/other/links/links',
|
||||||
|
activeMatch: '/other',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sidebar: [
|
||||||
|
{
|
||||||
|
text: '基础·必看',
|
||||||
|
base: '/base/',
|
||||||
|
items: [
|
||||||
|
{ text: '介绍', link: '1-introduction' },
|
||||||
|
{
|
||||||
|
text: '快速开始',
|
||||||
|
link: '2-start',
|
||||||
|
},
|
||||||
|
{ text: 'uni 插件', link: '3-plugin' },
|
||||||
|
{ text: '样式篇', link: '4-style' },
|
||||||
|
{ text: '图标篇', link: '5-icons' },
|
||||||
|
{ text: 'SVG篇', link: '6-svg' },
|
||||||
|
{ text: 'UI库选型篇', link: 'ui/ui' },
|
||||||
|
{ text: 'UI库替换篇', link: '7-ui' },
|
||||||
|
{ text: '请求篇', link: '8-request' },
|
||||||
|
{ text: '状态篇', link: '9-state' },
|
||||||
|
{ text: '多语言篇', link: '10-i18n' },
|
||||||
|
{ text: '运行发布', link: '11-build' },
|
||||||
|
{ text: '环境变量', link: '12-env' },
|
||||||
|
{ text: 'hbx 模板', link: '13-hbx' },
|
||||||
|
{ text: '常见问题', link: '14-faq' },
|
||||||
|
{ text: '常见问题2', link: '15-faq' },
|
||||||
|
{ text: '最佳实践', link: '20-best' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '社交',
|
||||||
|
base: '/advanced/',
|
||||||
|
items: [
|
||||||
|
{ text: '🥤 打赏', link: 'rewards/rewards' },
|
||||||
|
{ text: '微信交流群', link: 'wechat/wechat' },
|
||||||
|
{ text: '赞助榜', link: 'sponsor/sponsor' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '延伸',
|
||||||
|
base: '/other/',
|
||||||
|
items: [
|
||||||
|
{ text: '相关链接', link: 'links/links' },
|
||||||
|
{ text: '图片占位图', link: 'image/image' },
|
||||||
|
{ text: 'iconfont详细版', link: 'iconfont/iconfont' },
|
||||||
|
{ text: 'Git 提交优化', link: 'czg/czg' },
|
||||||
|
{ text: '文件资源展示优化', link: 'files/files' },
|
||||||
|
{ text: 'unibest博客', link: 'blog' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
footer: {
|
||||||
|
message: 'Released under the MIT License.',
|
||||||
|
copyright: 'Copyright (c) 2024 菲鸽',
|
||||||
|
},
|
||||||
|
socialLinks: [
|
||||||
|
{ icon: 'github', link: 'https://github.com/feige996/unibest' },
|
||||||
|
{
|
||||||
|
icon: {
|
||||||
|
svg: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12a12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.016 0m6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.592.592 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296Z"/></svg>`,
|
||||||
|
},
|
||||||
|
link: 'https://gitee.com/feige996/unibest',
|
||||||
|
ariaLabel: 'Gitee',
|
||||||
|
},
|
||||||
|
// #1f80ff 是掘金的 logo 的颜色
|
||||||
|
{
|
||||||
|
icon: {
|
||||||
|
svg: `<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2449" width="200" height="200">
|
||||||
|
<path fill="#1f80ff" d="M465.189 161.792c-22.967 18.14-44.325 35.109-47.397 37.742l-5.851 4.68 10.971 8.632c5.998 4.827 11.85 9.508 13.02 10.532 1.17 1.024 17.993 14.336 37.156 29.696l34.962 27.795 5.267-3.95c2.925-2.194 23.259-18.432 45.348-35.986 21.943-17.555 41.253-32.768 42.716-33.646 1.609-1.024 2.779-2.194 2.779-2.78 0-0.438-9.655-8.63-21.504-17.846-11.995-9.363-22.674-17.847-23.845-18.871-15.945-13.02-49.737-39.059-50.76-39.059-0.586 0.147-19.896 14.922-42.862 33.061z m233.325 180.37C507.465 493.275 508.928 492.105 505.417 489.911c-3.072-1.902-11.556-8.485-64.073-50.03-9.07-7.168-18.578-14.775-21.358-16.823-2.78-2.194-8.777-6.875-13.312-10.532-4.68-3.657-10.679-8.339-13.312-10.533-13.165-10.24-71.095-56.027-102.107-80.457-5.852-4.681-11.41-8.485-12.142-8.485-0.731 0-10.971 7.754-22.674 17.116-11.703 9.508-22.674 18.286-24.284 19.456-1.755 1.17-5.12 3.95-7.46 6.144-2.34 2.34-4.828 4.096-5.413 4.096-3.072 0-0.731 3.072 6.437 8.777 4.096 3.218 8.777 6.875 10.094 8.046 1.316 1.024 10.24 8.045 19.748 15.506s23.26 18.286 30.428 23.99c19.31 15.215 31.89 25.308 127.853 101.084 47.836 37.742 88.796 69.779 90.844 71.095 3.657 2.487 3.95 2.487 7.46-0.292a1041.42 1041.42 0 0 0 16.092-12.727c6.875-5.413 14.775-11.703 17.554-13.897 30.135-23.699 80.018-63.05 81.774-64.512 1.17-1.024 12.434-9.802 24.868-19.603s37.888-29.696 56.32-44.324c18.579-14.629 46.227-36.425 61.733-48.567 15.506-12.142 27.794-22.528 27.502-23.26-0.878-1.17-57.637-47.104-59.978-48.274-0.731-0.439-18.578 12.727-39.497 29.257z"></path>
|
||||||
|
<path fill="#1f80ff" d="M57.93 489.326c-15.215 12.288-28.527 23.405-29.697 24.576-2.34 2.194-5.412-0.44 80.018 66.852 33.207 26.185 32.622 25.747 57.637 45.495 10.386 8.192 36.279 28.672 57.783 45.495 38.18 30.135 44.91 35.401 52.663 41.545 2.048 1.756 22.967 18.14 46.372 36.572 23.26 18.432 74.167 58.514 112.933 89.088 38.912 30.573 71.095 55.734 71.826 56.027 0.732 0.293 7.46-4.389 14.921-10.386 21.797-16.97 90.259-70.949 101.523-79.872 5.705-4.535 12.873-10.24 15.945-12.58 3.072-2.488 6.436-5.12 7.314-5.852 0.878-0.878 11.85-9.509 24.283-19.31 20.773-16.091 59.1-46.226 64.366-50.615 1.17-1.024 5.12-4.096 8.777-6.875 3.657-2.78 7.9-6.29 9.509-7.607 1.609-1.317 14.775-11.703 29.257-23.113 29.11-22.82 42.277-33.207 88.503-69.632 17.262-13.605 32.475-25.454 33.646-26.478 2.486-2.048 31.451-24.869 44.617-35.255 4.827-3.657 9.07-7.168 9.508-7.607 0.44-0.585 5.998-4.827 12.435-9.8 6.436-4.828 13.165-10.24 15.067-11.85l3.365-2.926-9.948-7.753c-5.412-4.388-10.24-8.192-10.679-8.63-1.17-1.317-22.381-18.433-30.135-24.284-3.95-3.072-7.314-5.998-7.606-6.73-1.317-3.071-6.73 0.147-29.258 17.994-13.458 10.532-25.746 20.187-27.355 21.504-1.61 1.463-10.533 8.338-19.749 15.652-9.216 7.168-17.115 13.459-17.554 13.898-0.439 0.438-6.583 5.412-13.897 10.971-7.168 5.559-15.214 11.703-17.7 13.75-4.974 4.097-5.413 4.39-20.334 16.239-5.56 4.388-11.264 8.777-12.435 9.8-1.17 1.025-20.333 16.092-42.422 33.354-22.09 17.408-41.546 32.768-43.155 34.084-1.609 1.463-14.482 11.557-28.525 22.528s-40.814 32.037-59.539 46.812c-18.578 14.775-42.276 33.353-52.516 41.399s-23.26 18.285-28.965 22.82l-10.386 8.339-4.389-3.072c-2.34-1.756-4.68-3.511-5.12-3.95-0.439-0.439-4.973-4.096-10.24-8.046-11.849-9.216-14.482-11.264-16.676-13.166-0.878-0.877-4.243-3.51-7.46-5.851-3.22-2.487-6.145-4.681-6.584-5.12-0.439-0.439-6.875-5.705-14.482-11.703-7.607-5.851-14.921-11.556-16.091-12.58-1.317-1.17-17.116-13.605-35.255-27.795-17.993-14.19-35.109-27.648-38.035-29.842-5.705-4.681-33.499-26.624-125.074-98.743-34.523-27.209-72.704-57.344-84.846-66.852-49.737-39.498-55.15-43.594-56.905-43.447-0.877 0-14.043 10.24-29.257 22.528z" >
|
||||||
|
</path>
|
||||||
|
</svg>`,
|
||||||
|
},
|
||||||
|
link: 'https://juejin.cn/user/3263006241460792/posts',
|
||||||
|
ariaLabel: '菲鸽的掘金主页',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
search: {
|
||||||
|
provider: 'local',
|
||||||
|
options: {
|
||||||
|
locales: {
|
||||||
|
zh: {
|
||||||
|
translations: {
|
||||||
|
button: {
|
||||||
|
buttonText: '搜索文档',
|
||||||
|
buttonAriaLabel: '搜索文档',
|
||||||
|
},
|
||||||
|
modal: {
|
||||||
|
noResultsText: '无法找到相关结果',
|
||||||
|
resetButtonTitle: '清除查询条件',
|
||||||
|
footer: {
|
||||||
|
selectText: '选择',
|
||||||
|
navigateText: '切换',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
26
docs/.vitepress/layouts/Default.vue
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<!-- .vitepress/layouts/Default.vue -->
|
||||||
|
<template>
|
||||||
|
<div class="custom-layout">
|
||||||
|
<VPLayout>
|
||||||
|
<template #layout-bottom>
|
||||||
|
<footer class="footer">
|
||||||
|
<p>© 2024 菲鸽科技</p>
|
||||||
|
<p><a href="https://beian.miit.gov.cn" target="_blank">粤ICP备2024160998号</a></p>
|
||||||
|
<BuildInfo />
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
</VPLayout>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import VPLayout from '@theme-default/Layout.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.footer {
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
</style>
|
50
docs/.vitepress/theme/components/HomeStar.vue
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<p class="home-star">
|
||||||
|
<a href="https://github.com/codercup/unibest">
|
||||||
|
<img
|
||||||
|
alt="GitHub Repo stars"
|
||||||
|
src="https://img.shields.io/github/stars/codercup/unibest?logo=github&color=%234d80f0&link=https%3A%2F%2Fgithub.com%2Fcodercup%2Funibest"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/feige996/unibest">
|
||||||
|
<img
|
||||||
|
alt="GitHub Repo stars"
|
||||||
|
src="https://img.shields.io/github/stars/feige996/unibest?logo=github&color=%234d80f0&link=https%3A%2F%2Fgithub.com%2Ffeige996%2Funibest"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://gitee.com/codercup/unibest/stargazers">
|
||||||
|
<img src="https://gitee.com/codercup/unibest/badge/star.svg?theme=gray" alt="star" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- <a href="https://gitee.com/feige996/unibest/stargazers">
|
||||||
|
<img src="https://gitee.com/feige996/unibest/badge/star.svg?theme=gray" alt="star" />
|
||||||
|
</a> -->
|
||||||
|
|
||||||
|
<a href="https://github.com/feige996/unibest">
|
||||||
|
<img alt="GitHub" src="https://img.shields.io/github/license/feige996/unibest?logo=github" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://www.npmjs.com/package/create-unibest">
|
||||||
|
<img
|
||||||
|
alt="npm"
|
||||||
|
src="https://img.shields.io/npm/dw/create-unibest?logo=npm&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fcreate-unibest"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- <a href="https://www.npmjs.com/package/create-unibest">
|
||||||
|
<img src="https://img.shields.io/npm/dt/create-unibest?style=flat-square" />
|
||||||
|
</a> -->
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.home-star {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 24px;
|
||||||
|
}
|
||||||
|
</style>
|
21
docs/.vitepress/theme/components/NavBarTitleAfter.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
// TODO: 从远程地址获取版本号
|
||||||
|
const version = '2.5.0'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span
|
||||||
|
style="
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 4px;
|
||||||
|
margin-left: 4px;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: green;
|
||||||
|
background-color: azure;
|
||||||
|
border-radius: 4px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ version }}
|
||||||
|
</span>
|
||||||
|
</template>
|
84
docs/.vitepress/theme/custom.css
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Colors
|
||||||
|
* -------------------------------------------------------------------------- */
|
||||||
|
:root {
|
||||||
|
--vp-c-brand-1: hsl(128, 56%, 38%);
|
||||||
|
--vp-c-brand-2: hsl(128, 56%, 55%);
|
||||||
|
--vp-c-brand-3: hsl(128, 56%, 45%);
|
||||||
|
--vp-c-brand-soft: rgba(98, 133, 208, 0.16);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Component: Home
|
||||||
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--vp-home-hero-name-color: transparent;
|
||||||
|
--vp-home-hero-name-background: -webkit-linear-gradient(
|
||||||
|
120deg,
|
||||||
|
hsl(128, 56%, 38%) 30%,
|
||||||
|
hsl(128, 56%, 60%)
|
||||||
|
);
|
||||||
|
--vp-home-hero-image-background-image: linear-gradient(
|
||||||
|
120deg,
|
||||||
|
hsl(100, 56%, 45%) 30%,
|
||||||
|
hsl(120, 56%, 38%)
|
||||||
|
);
|
||||||
|
--vp-home-hero-image-filter: blur(40px);
|
||||||
|
}
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
:root {
|
||||||
|
--vp-home-hero-image-filter: blur(56px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 960px) {
|
||||||
|
:root {
|
||||||
|
--vp-home-hero-image-filter: blur(72px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-center > p {
|
||||||
|
display: flex;
|
||||||
|
/* justify-content: center; */
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: -4px;
|
||||||
|
margin-right: -4px;
|
||||||
|
}
|
||||||
|
.md-center img {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1.4em;
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.md-center2 img {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.busuanzi_container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 960px) {
|
||||||
|
.busuanzi_container {
|
||||||
|
flex-direction: column;
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 961px) {
|
||||||
|
.busuanzi_container {
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icp_container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
22
docs/.vitepress/theme/index.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// https://vitepress.dev/guide/custom-theme
|
||||||
|
import type { Theme } from 'vitepress'
|
||||||
|
import DefaultTheme from 'vitepress/theme'
|
||||||
|
import { h } from 'vue'
|
||||||
|
import './custom.css'
|
||||||
|
|
||||||
|
import HomeStar from './components/HomeStar.vue'
|
||||||
|
import NavBarTitleAfter from './components/NavBarTitleAfter.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: DefaultTheme,
|
||||||
|
Layout: () => {
|
||||||
|
return h(DefaultTheme.Layout, null, {
|
||||||
|
// https://vitepress.dev/guide/extending-default-theme#layout-slots
|
||||||
|
'home-hero-info-after': () => h(HomeStar),
|
||||||
|
'nav-bar-title-after': () => h(NavBarTitleAfter),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
enhanceApp({ app, router, siteData }) {
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
} satisfies Theme
|
BIN
docs/advanced/me/image-2.png
Normal file
After Width: | Height: | Size: 282 KiB |
BIN
docs/advanced/me/image-3.png
Normal file
After Width: | Height: | Size: 358 KiB |
30
docs/advanced/me/me.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# 关于我
|
||||||
|
|
||||||
|
我叫 `菲鸽`,江西宋城人。前端工程师,全栈实践者,精通 `vue`、`react`、`uniapp`、`typescript`、`小程序`、`Nodejs` 等。
|
||||||
|
|
||||||
|
热爱编程,喜欢分享,平时比较宅,喜欢撸代码,偶尔打篮球和玩王者荣耀。
|
||||||
|
|
||||||
|
<!--  -->
|
||||||
|
|
||||||
|
## 找到我
|
||||||
|
|
||||||
|
- Github: [feige996](https://github.com/feige996)
|
||||||
|
- Gitee: [feige996](https://gitee.com/feige996)
|
||||||
|
- 掘金:[菲鸽](https://juejin.cn/user/3263006241460792/posts)
|
||||||
|
- 微信:`feige996` = `菲鸽`,大家都叫我 `鸽鸽`
|
||||||
|
- QQ:`1020103647`
|
||||||
|
- 邮箱:`1020103647@qq.com`
|
||||||
|
|
||||||
|
## 微信公众号
|
||||||
|
|
||||||
|
微信公众号:`菲鸽爱编程`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<!-- ## 靓照
|
||||||
|
|
||||||
|
五一陪儿子玩,不料给我拍出来美美的靓照,正好没有合适的照片,就用它了。
|
||||||
|
|
||||||
|
`2024年5月5日`,最新鲜的照片了。
|
||||||
|
|
||||||
|
 -->
|
BIN
docs/advanced/me/screenshots/pay-wx.png
Normal file
After Width: | Height: | Size: 141 KiB |
BIN
docs/advanced/me/screenshots/wx-gzh.png
Normal file
After Width: | Height: | Size: 286 KiB |
BIN
docs/advanced/me/screenshots/wx-me.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
docs/advanced/rewards/assets/group-qq.jpg
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
docs/advanced/rewards/assets/group-wx.jpg
Normal file
After Width: | Height: | Size: 159 KiB |
BIN
docs/advanced/rewards/assets/pay-1.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
docs/advanced/rewards/assets/pay-2.png
Normal file
After Width: | Height: | Size: 134 KiB |
BIN
docs/advanced/rewards/assets/pay-ali.png
Normal file
After Width: | Height: | Size: 154 KiB |
BIN
docs/advanced/rewards/assets/pay-w-5.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
docs/advanced/rewards/assets/pay-wx-10.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
docs/advanced/rewards/assets/pay-wx-2.png
Normal file
After Width: | Height: | Size: 146 KiB |
BIN
docs/advanced/rewards/assets/pay-wx-5-doc.png
Normal file
After Width: | Height: | Size: 146 KiB |
BIN
docs/advanced/rewards/assets/pay-wx-5.png
Normal file
After Width: | Height: | Size: 146 KiB |
BIN
docs/advanced/rewards/assets/pay-wx.png
Normal file
After Width: | Height: | Size: 141 KiB |
8
docs/advanced/rewards/rewards.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 🥤 打赏
|
||||||
|
|
||||||
|
如果本项目对你的工作起到了帮助,加快了您的项目进展,解决了您的问题,欢迎 `打赏` !
|
||||||
|
|
||||||
|
<p align='center'>
|
||||||
|
<img alt="special sponsor appwrite" src="./assets/pay-1.png" height="330" style="display:inline-block; height:330px;">
|
||||||
|
<img alt="special sponsor appwrite" src="./assets/pay-2.png" height="330" style="display:inline-block; height:330px; margin-left:10px;">
|
||||||
|
</p>
|
61
docs/advanced/sponsor/sponsor.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# 赞助榜
|
||||||
|
|
||||||
|
感谢所有赞助者!
|
||||||
|
|
||||||
|
如需更改展示信息,或者需要展示更详细的信息,请联系我。
|
||||||
|
|
||||||
|
如果需要展示产品、博客、友链啥的,也可以联系我,很乐意为您展示。
|
||||||
|
|
||||||
|
> 金牌赞助者将额外获得首页产品展示位。
|
||||||
|
|
||||||
|
## 200 元
|
||||||
|
|
||||||
|
- 麦可
|
||||||
|
- 程序员云创 [https://www.codecommitter.com/](https://www.codecommitter.com/)
|
||||||
|
|
||||||
|
## 50 元
|
||||||
|
|
||||||
|
- \*皮
|
||||||
|
- 暗月隐落 [飞鸟快验 - 一个通用网络验证后台](https://www.fnkuaiyan.cn)
|
||||||
|
|
||||||
|
## 20 元
|
||||||
|
|
||||||
|
- \*捷
|
||||||
|
- \*度
|
||||||
|
- \*恼
|
||||||
|
|
||||||
|
## 10-20 元
|
||||||
|
|
||||||
|
- 薛柳(15)
|
||||||
|
- 是魔王哒(12)
|
||||||
|
|
||||||
|
## 10 元
|
||||||
|
|
||||||
|
- \*辛
|
||||||
|
- \*y
|
||||||
|
- \*边
|
||||||
|
|
||||||
|
## 5-10 元
|
||||||
|
|
||||||
|
- Leo (9.90)
|
||||||
|
- \*熙 (6.66)
|
||||||
|
- 阿森纳 (6.66)
|
||||||
|
- I am 小萝北 ²º²4 (6.60)
|
||||||
|
- SUMMER (5)
|
||||||
|
- \*峰 (5)
|
||||||
|
- 阿云 (5)
|
||||||
|
- nuYoah (5)
|
||||||
|
- 许志成 (5)
|
||||||
|
- JY_en_ke_hao (5)
|
||||||
|
|
||||||
|
## 2 元及以下
|
||||||
|
|
||||||
|
有 `15` 人,这里不一一列出。(如果希望展示,请联系我)
|
||||||
|
|
||||||
|
## 红包打赏
|
||||||
|
|
||||||
|
还有一部分群友是发 `专属红包` 打赏的,这里没有统计,如果需要展示,请联系我。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 再次感谢所有赞助者、打赏者!
|
BIN
docs/advanced/wechat/image-1.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
docs/advanced/wechat/image-2.png
Normal file
After Width: | Height: | Size: 848 KiB |
BIN
docs/advanced/wechat/image.png
Normal file
After Width: | Height: | Size: 451 KiB |
14
docs/advanced/wechat/wechat.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# 微信交流群
|
||||||
|
|
||||||
|
> 作者最近比较忙,本来想隐藏交流群的,但是还是有人通过加我微信,要去交流群,索性还是放开吧。
|
||||||
|
|
||||||
|
最近作者在复习,准备面试,群消息关注较少,希望见谅。
|
||||||
|
|
||||||
|
再次提醒,千万记得 `先看一遍文档`,两个小时就看完了吧。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 如果上面的微信群满了,请使用下面的 QQ 群,QQ 群不会过期,长期有效。
|
||||||
|
|
||||||
|
① 群已满,下面是 ② 群。
|
||||||
|

|
196
docs/base/1-introduction.md
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
# 简介
|
||||||
|
|
||||||
|
<div class="md-center" style="margin-top: 20px;">
|
||||||
|
|
||||||
|
[](https://github.com/codercup/unibest)
|
||||||
|
[](https://github.com/feige996/unibest)
|
||||||
|
[](https://gitee.com/codercup/unibest)
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
> 上面前 2 个 `star` 分别是旧仓库 `codercup` 和新仓库 `feige996` 的 `star` 数。
|
||||||
|
|
||||||
|
`unibest` 是最好的 `uniapp` 开发框架,由 `uniapp` + `Vue3` + `Ts` + `Vite5` + `UnoCss` + `VSCode`(可选 `webstorm`) + `uni插件`+ `wot-ui`(可选其他 UI 库)构建,集成了多种工具和技术,使用了最新的前端技术栈,无需依靠 `HBuilderX`,通过命令行方式即可运行 `web`、`小程序` 和 `App`。(注:`App` 还是需要 `HBuilderX`)
|
||||||
|
|
||||||
|
`unibest` 内置了 `约定式路由`、`layout布局`、`请求封装`、`请求拦截`、`登录拦截`、`UnoCSS`、`i18n多语言` 等基础功能,提供了 `代码提示`、`自动格式化`、`统一配置`、`代码片段` 等辅助功能,让你编写 `uniapp` 拥有 `best` 体验 ( `unibest 的由来`)。
|
||||||
|
|
||||||
|
> `unibest` 目前支持 `H5`、`小程序` 和 `App`。
|
||||||
|
|
||||||
|
## ⭐ Star History
|
||||||
|
|
||||||
|
Github Star History 实时地址:[https://star-history.com/#codercup/unibest&Date](https://star-history.com/#codercup/unibest&Date) 。
|
||||||
|
|
||||||
|
[](https://star-history.com/#codercup/unibest&Date)
|
||||||
|
|
||||||
|
与同类型模板对比,如下图,红色的为 `unibest`,后来居上,遥遥领先。
|
||||||
|
|
||||||
|
:::details
|
||||||
|
|
||||||
|
[](https://star-history.com/#codercup/unibest&Ares-Chang/uni-vitesse&uni-helper/vitesse-uni-app&Date)
|
||||||
|
|
||||||
|
同类模板对比实时地址:[https://star-history.com/#codercup/unibest&Ares-Chang/uni-vitesse&uni-helper/vitesse-uni-app&Date](https://star-history.com/#codercup/unibest&Ares-Chang/uni-vitesse&uni-helper/vitesse-uni-app&Date)
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 🗂 生成过程
|
||||||
|
|
||||||
|
`unibest` 由最初始的官方 cli 脚手架模板生成,执行的命令如下:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project
|
||||||
|
```
|
||||||
|
|
||||||
|
`uniapp` 官方链接:[点击跳转 - quickstart-cli](https://uniapp.dcloud.net.cn/quickstart-cli.html)
|
||||||
|
|
||||||
|
在官方生成的项目基础上,增加了如下内容:
|
||||||
|
|
||||||
|
- 前端基础配置六件套
|
||||||
|
- prettier
|
||||||
|
- eslint
|
||||||
|
- stylelint
|
||||||
|
- husky
|
||||||
|
- lint-staged
|
||||||
|
- commitlint
|
||||||
|
- UnoCSS
|
||||||
|
- UnoCSS Icons
|
||||||
|
- Uni 插件
|
||||||
|
- vite-plugin-uni-pages
|
||||||
|
- vite-plugin-uni-layouts
|
||||||
|
- vite-plugin-uni-manifest
|
||||||
|
- vite-plugin-uni-platform
|
||||||
|
- UI 库(默认 `wot-ui`,支持替换其他 `UI库`)
|
||||||
|
- pinia + pinia-plugin-persistedstate
|
||||||
|
- 通用功能
|
||||||
|
- 请求封装
|
||||||
|
- 请求拦截
|
||||||
|
- 路由拦截
|
||||||
|
|
||||||
|
## ✨ 特性
|
||||||
|
|
||||||
|
- ⚡️ [Vue 3](https://github.com/vuejs/core), [Vite](https://github.com/vitejs/vite), [pnpm](https://pnpm.io/), [esbuild](https://github.com/evanw/esbuild) - 就是快!
|
||||||
|
|
||||||
|
- 🔥 最新语法 - `<script lang="ts" setup>` 语法
|
||||||
|
|
||||||
|
- 🎨 [UnoCSS](https://unocss.dev/) - 高性能且极具灵活性的即时原子化 CSS 引擎
|
||||||
|
|
||||||
|
- 😃 [UnoCSS Icons](https://unocss.dev/presets/icons) & [icones](https://icones.js.org/) - 海量图标供你选择
|
||||||
|
|
||||||
|
- 🍍 [pinia](https://pinia.vuejs.org/) & [pinia-plugin-persistedstate](https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/) - 全端适配的全局数据管理
|
||||||
|
|
||||||
|
- 🗂 `uni.request` 请求封装 - 一键引入,快捷使用
|
||||||
|
|
||||||
|
- 📦 `路由拦截` 基础封装,支持扩展,快捷使用,拒绝黑盒
|
||||||
|
|
||||||
|
- 📥 [API 自动加载](https://github.com/antfu/unplugin-auto-import) - 直接使用 Composition API 无需引入
|
||||||
|
|
||||||
|
- 🎉 `v3` Code Snippets 加快你的页面生成
|
||||||
|
|
||||||
|
- 🦾 `Pritter` & `ESLint` & `Stylelint` & `husky` & `lint-staged` + `commitlint` - 保证代码质量
|
||||||
|
|
||||||
|
- 🌈 `TypeScript` 加持,同时又兼容 `js` ,同时满足不同人群
|
||||||
|
|
||||||
|
- 💡 `ES6 import` 自动排序,`css 属性` 自动排序,增强编码一致性
|
||||||
|
|
||||||
|
- 🖥 `多环境` 配置分开,想则怎么配置就怎么配置
|
||||||
|
|
||||||
|
## 📦 目录结构
|
||||||
|
|
||||||
|
通过 `tree -I node_modules -I dist -I .git -a > tree.md` 命令生成。
|
||||||
|
|
||||||
|
```txt
|
||||||
|
.
|
||||||
|
├── .editorconfig
|
||||||
|
├── .eslintignore
|
||||||
|
├── .eslintrc-auto-import.json
|
||||||
|
├── .eslintrc.cjs
|
||||||
|
├── .gitignore
|
||||||
|
├── .husky
|
||||||
|
├── .npmrc
|
||||||
|
├── .prettierignore
|
||||||
|
├── .prettierrc.cjs
|
||||||
|
├── .stylelintignore
|
||||||
|
├── .stylelintrc.cjs
|
||||||
|
├── .vscode
|
||||||
|
├── LICENSE
|
||||||
|
├── README.md
|
||||||
|
├── commitlint.config.cjs
|
||||||
|
├── env
|
||||||
|
│ ├── .env
|
||||||
|
│ ├── .env.development
|
||||||
|
│ ├── .env.production
|
||||||
|
│ └── .env.test
|
||||||
|
├── favicon.ico
|
||||||
|
├── index.html
|
||||||
|
├── manifest.config.ts
|
||||||
|
├── package.json
|
||||||
|
├── pages.config.ts
|
||||||
|
├── src
|
||||||
|
│ ├── App.vue
|
||||||
|
│ ├── components
|
||||||
|
│ │ └── .gitkeep
|
||||||
|
│ ├── env.d.ts
|
||||||
|
│ ├── hooks
|
||||||
|
│ │ ├── .gitkeep
|
||||||
|
│ │ ├── useRequest.ts
|
||||||
|
│ │ └── useUpload.ts
|
||||||
|
│ ├── interceptors
|
||||||
|
│ │ ├── index.ts
|
||||||
|
│ │ ├── prototype.ts
|
||||||
|
│ │ ├── request.ts
|
||||||
|
│ │ └── route.ts
|
||||||
|
│ ├── layouts
|
||||||
|
│ │ ├── default.vue
|
||||||
|
│ │ └── demo.vue
|
||||||
|
│ ├── main.ts
|
||||||
|
│ ├── manifest.json
|
||||||
|
│ ├── pages
|
||||||
|
│ │ ├── about
|
||||||
|
│ │ │ ├── about.vue
|
||||||
|
│ │ │ └── components
|
||||||
|
│ │ │ ├── request.vue
|
||||||
|
│ │ │ └── upload.vue
|
||||||
|
│ │ └── index
|
||||||
|
│ │ └── index.vue
|
||||||
|
│ ├── pages-sub
|
||||||
|
│ │ └── demo
|
||||||
|
│ │ └── index.vue
|
||||||
|
│ ├── pages.json
|
||||||
|
│ ├── service
|
||||||
|
│ │ └── index
|
||||||
|
│ │ └── foo.ts
|
||||||
|
│ ├── static
|
||||||
|
│ │ ├── images
|
||||||
|
│ │ │ └── .gitkeep
|
||||||
|
│ │ ├── logo.svg
|
||||||
|
│ │ └── tabbar
|
||||||
|
│ │ ├── example.png
|
||||||
|
│ │ ├── exampleHL.png
|
||||||
|
│ │ ├── home.png
|
||||||
|
│ │ ├── homeHL.png
|
||||||
|
│ │ ├── personal.png
|
||||||
|
│ │ └── personalHL.png
|
||||||
|
│ ├── store
|
||||||
|
│ │ ├── index.ts
|
||||||
|
│ │ └── user.ts
|
||||||
|
│ ├── style
|
||||||
|
│ │ └── index.scss
|
||||||
|
│ ├── types
|
||||||
|
│ │ ├── auto-import.d.ts
|
||||||
|
│ │ ├── global.d.ts
|
||||||
|
│ │ ├── shims-uni.d.ts
|
||||||
|
│ │ └── uni-pages.d.ts
|
||||||
|
│ ├── typings.ts
|
||||||
|
│ ├── uni.scss
|
||||||
|
│ ├── uni_modules
|
||||||
|
│ │ └── .gitkeep
|
||||||
|
│ └── utils
|
||||||
|
│ ├── http.ts
|
||||||
|
│ ├── index.ts
|
||||||
|
│ └── platform.ts
|
||||||
|
├── tsconfig.json
|
||||||
|
├── uni-pages.d.ts
|
||||||
|
├── uno.config.ts
|
||||||
|
└── vite.config.ts
|
||||||
|
```
|
163
docs/base/10-i18n.md
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
# 多语言篇
|
||||||
|
|
||||||
|
`多语言` 是一个常见的需求, `unibest` 专门开发了一个 `i18n`模板,可以直接生成 `多语言模板项目`。
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm create unibest my-project -t i18n
|
||||||
|
```
|
||||||
|
|
||||||
|
`vue组件` 里面使用方式如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view class="m-4">{{ $t('app.name') }}</view>
|
||||||
|
```
|
||||||
|
|
||||||
|
`非vue组件` 里面怎么使用呢?比如 `ts` 文件。
|
||||||
|
|
||||||
|
这时需要用到作者编写的 `translate` 函数,使用方式如下:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { translate as t } from '@/locale/index'
|
||||||
|
|
||||||
|
/** 非vue 文件使用 i18n */
|
||||||
|
export const testI18n = () => {
|
||||||
|
console.log(t('app.name'))
|
||||||
|
// 下面同样生效
|
||||||
|
uni.showModal({
|
||||||
|
title: 'i18n 测试',
|
||||||
|
content: t('app.name'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上面基本的使用都是没问题的,但是传递参数时,只有 `H5端` 生效,`其他端` 是不生效的,代码如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view class="m-4">{{ $t('weight', { heavy: 100 }) }}</view>
|
||||||
|
```
|
||||||
|
|
||||||
|
`H5端` 效果如下,正常显示:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
`非H5端` 效果如下,异常显示:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
下面我们就来处理这个问题。
|
||||||
|
|
||||||
|
## 多语言传参
|
||||||
|
|
||||||
|
上面提到 `vue-i18n` 在 `非H5端` 传参时显示异常,那我们就来处理一下,主要方式就是通过 `正则` 替换 `多语言字符串`。
|
||||||
|
|
||||||
|
编写一个函数 `formatI18n`,如下:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
/**
|
||||||
|
* formatI18n('我是{name},身高{detail.height},体重{detail.weight}',{name:'张三',detail:{height:178,weight:'75kg'}})
|
||||||
|
* 暂不支持数组
|
||||||
|
* @param template 多语言模板字符串,eg: `我是{name}`
|
||||||
|
* @param obj 需要传递的对象,里面的key与多语言字符串对应,eg: `{name:'菲鸽'}`
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function formatI18n(template, data) {
|
||||||
|
const match = /\{(.*?)\}/g.exec(template)
|
||||||
|
if (match) {
|
||||||
|
const variableList = match[0].replace('{', '').replace('}', '').split('.')
|
||||||
|
let result = data
|
||||||
|
for (let i = 0; i < variableList.length; i++) {
|
||||||
|
result = result[variableList[i]] || ''
|
||||||
|
}
|
||||||
|
return formatStr(template.replace(match[0], result), data)
|
||||||
|
} else {
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`vue组件` 里面使用方式如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view class="m-4">{{ formatI18n(translate('introduction'), user) }}</view>
|
||||||
|
```
|
||||||
|
|
||||||
|
用到的函数引入如下:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { formatI18n, translate } from '@/locale/index'
|
||||||
|
```
|
||||||
|
|
||||||
|
对应的 en.json 文件如下:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "introduction": "I am {name},height:{detail.height},weight:{detail.weight}" }
|
||||||
|
```
|
||||||
|
|
||||||
|
`user` 对象如下:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{name:'张三',detail:{height:178,weight:'75kg'}}
|
||||||
|
```
|
||||||
|
|
||||||
|
这样,在 `H5端` 和 `非H5端` 都能正常显示,如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
very good !
|
||||||
|
|
||||||
|
## 导航栏标题
|
||||||
|
|
||||||
|
目前发现 `导航栏标题` 在 `小程序端` 不会跟随多语言切换而切换,比如说刚开始是中文,切换成英文后,页面内容都变成英文了,标题栏还是中文。
|
||||||
|
|
||||||
|
> `App端` 说明:`App模拟器`,以我的 `mac电脑` `ios模拟器` 来说,是正常的,可以直接切换,多语言也是生效的。
|
||||||
|
>
|
||||||
|
> 但是 `安卓真机` 会出现`切换多语言后,自动重启,然后界面多语言是生效的`。
|
||||||
|
>
|
||||||
|
> 既然 `App 正常`,这里主要说 `小程序端` 不正常的处理。
|
||||||
|
|
||||||
|
`小程序端` 需要使用 `uni.setNavigationBarTitle` 来手动处理,`API` 使用如下:
|
||||||
|
|
||||||
|
```js
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: '新的标题',
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
结合 `translate` 函数,则:
|
||||||
|
|
||||||
|
```js
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: translate('app.name'),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
可以满足大部分场景。
|
||||||
|
|
||||||
|
## tabbar 标题
|
||||||
|
|
||||||
|
同 `导航栏标题`。
|
||||||
|
|
||||||
|
## App 端视频
|
||||||
|
|
||||||
|
这里给出 `2` 个 `App端` 的视频,加深开发者的认识和印象。
|
||||||
|
|
||||||
|
:::details
|
||||||
|
|
||||||
|
### `ios模拟器` 多语言直接就是生效的
|
||||||
|
|
||||||
|
<video src="./assets/10-ios.mp4" controls="controls" width="100%" height="100%"></video>
|
||||||
|
|
||||||
|
### `安卓真机` 会自动重启,重启后界面多语言是生效的
|
||||||
|
|
||||||
|
<video src="./assets/10-android.mp4" controls="controls" width="100%" height="100%"></video>
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文介绍了 `unibest` 里面使用 `多语言` 的基本方式,还处理了 `3` 个多端异常的问题:
|
||||||
|
|
||||||
|
- `多语言传参` 不生效 BUG
|
||||||
|
- `导航栏标题` 切换多语言不生效 BUG
|
||||||
|
- `tabbar标题` 切换多语言不生效 BUG
|
||||||
|
|
||||||
|
全文完~
|
111
docs/base/11-build.md
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# 运行发布
|
||||||
|
|
||||||
|
## 运行
|
||||||
|
|
||||||
|
- `h5 平台`: `pnpm dev:h5`( 或者简单点 `pnpm dev` ),然后浏览器打开 `http://localhost:9000/`。
|
||||||
|
- `wx 小程序`:`pnpm dev:mp-weixin`,然后打开微信开发者工具,导入本地文件夹,选择本项目的 `dist/dev/mp-weixin` 文件。
|
||||||
|
- 
|
||||||
|
|
||||||
|
- `APP 平台`:`pnpm dev:app`,然后打开 `HBuilderX`,导入刚刚生成的 `dist/dev/app` 文件夹,选择运行到 `模拟器`( `开发时优先使用` ),或者 `运行到安卓/ios 基座` (真机调试时使用) 。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
> 如果需要配置其他模拟器,可以参考:[安装模拟器](https://uniapp.dcloud.net.cn/tutorial/run/installSimulator.html)
|
||||||
|
|
||||||
|
> 这样操作的话,开发时都会有热更新,开发体验很爽!
|
||||||
|
|
||||||
|
## 发布
|
||||||
|
|
||||||
|
- `h5 平台`: `pnpm build:h5`,打包后的文件在 `dist/build/h5`,可以放到 web 服务器,如 nginx 运行。如果最终不是放在根目录,可以在 `manifest.config.ts` 文件的 `h5.router.base` 属性进行修改。
|
||||||
|
- `wx 小程序`:`pnpm build:mp-weixin`,打包后的文件在 `dist/build/mp-weixin`,然后通过微信开发者工具导入,并点击右上角的“上传”按钮进行上传。
|
||||||
|
- `APP 平台`:`pnpm build:app`,然后打开 `HBuilderX`,导入刚刚生成的 `dist/build/app` 文件夹,选择 `发行` - `原生APP-云打包`。
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
> 熟悉原生 APP 开发的开发者也可以使用 `原生APP-本地打包`。
|
||||||
|
|
||||||
|
## APP 打包注意事项(上)
|
||||||
|
|
||||||
|
很多开发者发现打包失败,或者打包白屏,这里简单说明一下。
|
||||||
|
|
||||||
|
- 1. 重新获取自己的 `AppId`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 2. 根据上面获取到的 `AppId` 修改 `env/.env` 文件的 `VITE_UNI_APPID` 字段
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 3. (可选)云打包如果有出现解析时出问题的,把 `minSdkVersion` 版本改低一点就好了,比如 `21`。(最低 `21`,不能低于 `21`;我模板里面设置的是 `30`)。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## APP 打包注意事项 (下)
|
||||||
|
|
||||||
|
### `uni-app SDK` 版本
|
||||||
|
|
||||||
|
> 特别备注:`2024-05-03`,新的 `base` 模板的 `uni-app SDK` 版本已经升级到 `4.14` 了。
|
||||||
|
>
|
||||||
|
> 
|
||||||
|
|
||||||
|
`2024-04-14`,新的 `base` 模板的 `uni-app SDK` 版本已经升级到 `4.08` ,记得更新您的 `HBuilderx` 版本。
|
||||||
|
|
||||||
|
`"@dcloudio/uni-app": "3.0.0-4000820240401001"` 表示 `uni-app` 为 `3.0.0` 版本,对应的 `HBuilderx` 版本为 `4.08`,后面的 `20240401001` 是发布日期。
|
||||||
|
|
||||||
|
> `40008` 第一个数字 `4` 表示主要版本,后面每 `2` 位数为一组,所以代表 `4.0.8`。
|
||||||
|
>
|
||||||
|
> 类似的,`30812` 代表 `3.8.12` 版本,`30909` 代表 `3.9.9` 版本。
|
||||||
|
>
|
||||||
|
> 另外,从 `3.99` 开始,后面 2 个小版本合并书写,于是 `3.9.9` 变成 `3.99`,`4.0.8` 变成 `4.08`。
|
||||||
|
|
||||||
|
`unibest` 历史用过的 `@dcloudio/uni-app` 版本:
|
||||||
|
|
||||||
|
```text
|
||||||
|
"@dcloudio/uni-app": "3.0.0-3081220230817001", => 3.8.12
|
||||||
|
"@dcloudio/uni-app": "3.0.0-3090920231225001", => 3.99
|
||||||
|
"@dcloudio/uni-app": "3.0.0-4000820240401001", => 4.08
|
||||||
|
"@dcloudio/uni-app": "3.0.0-4010420240430001", => 4.14
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### `uni-app SDK` 版本匹配 `HBuilderX`
|
||||||
|
|
||||||
|
> 温馨提示:下面的部分是使用 `uni-app` 版本为 `3.8.12` 时写的文档,适当参考~
|
||||||
|
|
||||||
|
本模板使用的是 `3.8.12` 的库版本(`"@dcloudio/uni-app": "3.0.0-3081220230817001",`),所以尽量使用 `3.8.12` 版本的 `HBuilderX` 来打包,否则可能有未知的风险,出现情况如下图。
|
||||||
|
|
||||||
|
> 原来的图不见了,重新补了一张。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
上图表示您的 `HBuilderX` 版本是 `4.08`,但是代码 `uni-app SDK` (即 `"@dcloudio/uni-app": "3.0.0-4010420240430001"` ) 是 `4.14`,版本不匹配。
|
||||||
|
|
||||||
|
- 点击 `ignore`(忽略) 后若可以正常使用,那就不用管。(可选添加如下配置)
|
||||||
|
|
||||||
|
```json
|
||||||
|
"app-plus" : { "compatible": { "ignoreVersion": true } }
|
||||||
|
```
|
||||||
|
|
||||||
|
- 如果出现白屏啥的,请更新您的 `HBuilderX` 到 `uni-app SDK` 相同版本(这里是 `4.14` )。
|
||||||
|
|
||||||
|
### 多个 `HBuilderX` 版本安装
|
||||||
|
|
||||||
|
> 温馨提示:下面的部分是使用 `uni-app` 版本为 `3.8.12` 时写的文档,适当参考~
|
||||||
|
|
||||||
|
`MAC` 可以安装多个版本的软件,如下图我安装了 `3.8.12` (3.8.12.20230817) 和最新的 `3.99` (3.99.2023122611) 两个版本,平时的项目使用 `3.99`, 打包 `unibest` 的时候使用 `3.8.12`。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> `window` 系统也可以同时安装多个 `HBuilderX` 版本,安装时选择安装到不同目录下即可。
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文描述了多端的运行和发布,希望对您有帮助。
|
||||||
|
|
||||||
|
全文完~
|
89
docs/base/12-env.md
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# 环境变量
|
||||||
|
|
||||||
|
主要介绍 `vite` 环境变量和 `uni` 环境变量。
|
||||||
|
|
||||||
|
## `vite` 环境变量
|
||||||
|
|
||||||
|
`Vite` 在一个特殊的 `import.meta.env` 对象上暴露环境变量。环境变量定义在 `.env` 文件里。
|
||||||
|
|
||||||
|
### .env 文件
|
||||||
|
|
||||||
|
创建环境文件:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
.env # 所有情况下都会加载
|
||||||
|
.env.local # 所有情况下都会加载,但会被 git 忽略
|
||||||
|
.env.[mode] # 只在指定模式下加载
|
||||||
|
.env.[mode].local # 只在指定模式下加载,但会被 git 忽略
|
||||||
|
|
||||||
|
# 注意 .env.local 无法覆盖 .env.[mode]
|
||||||
|
```
|
||||||
|
|
||||||
|
环境文件只包含环境变量的 `键值对` :
|
||||||
|
|
||||||
|
```yml
|
||||||
|
VITE_SOME_KEY=123
|
||||||
|
DB_PASSWORD=foobar
|
||||||
|
```
|
||||||
|
|
||||||
|
> 为了防止意外地将一些环境变量泄漏到客户端,只有以 `VITE_` 为前缀的变量才会暴露给经过 `vite` 处理的代码。
|
||||||
|
|
||||||
|
如上配置,只有 `VITE_SOME_KEY` 会被暴露为 `import.meta.env.VITE_SOME_KEY` 提供给客户端源码,而 `DB_PASSWORD` 则不会。
|
||||||
|
|
||||||
|
```js
|
||||||
|
console.log(import.meta.env.VITE_SOME_KEY) // "123"
|
||||||
|
console.log(import.meta.env.DB_PASSWORD) // undefined
|
||||||
|
```
|
||||||
|
|
||||||
|
### mode 模式
|
||||||
|
|
||||||
|
Vite 允许你为不同的构建环境指定不同的模式。通常在 `npm scripts` 里面指定 `mode` 参数:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
"scripts": {
|
||||||
|
"dev": "uni",
|
||||||
|
"dev-dev": "uni --mode development",
|
||||||
|
"dev-test": "uni --mode test",
|
||||||
|
"dev-prod": "uni --mode production",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
运行不同模式的脚本时,`Vite` 会自动加载对应的 `.env.[mode]` 文件,就能获取到不同的环境变量。
|
||||||
|
|
||||||
|
`Vite` 运行 `dev` 时默认会加载 `.env.development` 文件(若有)。
|
||||||
|
|
||||||
|
`Vite` 运行 `build` 时默认会加载 `.env.production` 文件(若有)。
|
||||||
|
|
||||||
|
故,如上配置 `pnpm dev` 与 `pnpm dev-dev` 是一个效果。
|
||||||
|
|
||||||
|
## `uni` 环境变量
|
||||||
|
|
||||||
|
`uni` 环境变量这里指运行 `uni` 的平台变量,通过 `vite` 的 `define` 配置可以暴露出来。
|
||||||
|
|
||||||
|
```
|
||||||
|
define: {
|
||||||
|
__UNI_PLATFORM__: JSON.stringify(UNI_PLATFORM),
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
代码里面使用:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export const platform = __UNI_PLATFORM__
|
||||||
|
export const isH5 = __UNI_PLATFORM__ === 'h5'
|
||||||
|
export const isApp = __UNI_PLATFORM__ === 'app'
|
||||||
|
export const isMp = __UNI_PLATFORM__.startsWith('mp-')
|
||||||
|
const PLATFORM = {
|
||||||
|
platform,
|
||||||
|
isH5,
|
||||||
|
isApp,
|
||||||
|
isMp,
|
||||||
|
}
|
||||||
|
export default PLATFORM
|
||||||
|
```
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文描写了 `vite` 环境变量和 `uni` 环境变量如何配置和使用。
|
||||||
|
|
||||||
|
全文完~
|
67
docs/base/13-hbx.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# hbx 模板
|
||||||
|
|
||||||
|
为了方便使用 `HBuilderX` 的开发者,`unibest` 也提供 `hbx` 模板。
|
||||||
|
|
||||||
|
`hbx 模板` 适用于 `2 类用户`
|
||||||
|
|
||||||
|
- 使用 `uniCloud` 云开发的用户,必须使用 `hbx 版本`,因为 `uniCloud` 跟 `HBuilderX` 是绑定的。
|
||||||
|
- 开发 `App` 的用户,可选使用 `hbx 版本`。
|
||||||
|
|
||||||
|
## 仓库地址
|
||||||
|
|
||||||
|
- gitee: [https://gitee.com/feige996/unibest-hbx.git](https://gitee.com/feige996/unibest-hbx.git)
|
||||||
|
- github: [https://github.com/feige996/unibest-hbx.git](https://github.com/feige996/unibest-hbx.git)
|
||||||
|
|
||||||
|
没有梯子的用户优先推荐使用 `gitee` 仓库,速度更快。(两个仓库会实时同步,无差别。)
|
||||||
|
|
||||||
|
## 导入项目
|
||||||
|
|
||||||
|
有 2 种方式导入项目:
|
||||||
|
|
||||||
|
- 从 `Git` 导入...
|
||||||
|
- 从本地目录导入...
|
||||||
|
|
||||||
|
## 运行项目
|
||||||
|
|
||||||
|
此时运行菜单会提示 `本项目类型无法运行`,如下图
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
需要执行如下 2 步:
|
||||||
|
|
||||||
|
- 项目下执行 `pnpm i`
|
||||||
|
- 右键项目,选择 `重新识别项目类型`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 运行效果
|
||||||
|
|
||||||
|
经过上面的操作后,就可以正常运行了。
|
||||||
|
|
||||||
|
- ios 模拟器运行效果如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 微信小程序运行效果如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 目前微信小程序静态资源还有点问题,如下图 `logo 不见了`,后续会修复。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 另外还发现 `UnoCSS Icon` 不生效,原因未知。
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文描述了 `hbx` 模板的由来,使用方式。
|
||||||
|
|
||||||
|
有需要的可以试试,但是不太建议使用。另外精力有限,该模板不再维护。
|
||||||
|
|
||||||
|
全文完~
|
116
docs/base/14-faq.md
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# 常见问题
|
||||||
|
|
||||||
|
本篇介绍一些常见的问题,会持续更新。
|
||||||
|
|
||||||
|
## 1. 如何设置/修改首页?
|
||||||
|
|
||||||
|
`vue` 文件的 `route-block` 块里面设置 `type="home"` 即可,请确保项目里面 `只有一个页面` 是这个配置。
|
||||||
|
|
||||||
|
> 注意:如果有多个,会按照字母顺序排列,第一个是首页。(可能不是您的想要的效果。)
|
||||||
|
|
||||||
|
## 2. 修改 `pages.json`、`manifest.json` 被覆盖问题
|
||||||
|
|
||||||
|
- `pages.json`
|
||||||
|
|
||||||
|
本项目引入了 `@uni-helper/vite-plugin-uni-pages`,`pages.json` 文件将会自动生成,手动修改 `pages.json` 将会被覆盖。
|
||||||
|
|
||||||
|
全局的东西请在 `pages.config.ts` 里面配置,页面的东西请在 `vue` 文件的 `route-block` 配置。
|
||||||
|
|
||||||
|
- `manifest.json`
|
||||||
|
|
||||||
|
与上面类似。本项目引入了 `@uni-helper/vite-plugin-uni-manifest`,`manifest.json` 文件将会自动生成,手动修改 `manifest.json` 将会被覆盖。
|
||||||
|
|
||||||
|
如需修改,请在 `manifest.config.ts` 里面修改。
|
||||||
|
|
||||||
|
## 3. 怎么分包?
|
||||||
|
|
||||||
|
`vite.config.ts` 里面有一个配置,如下:(其中 `subPackages` 就是用来分包的)
|
||||||
|
|
||||||
|
```ts [vite.config.ts]{3}
|
||||||
|
UniPages({
|
||||||
|
exclude: ['**/components/**/**.*'],
|
||||||
|
subPackages: ['src/pages-sub'], // 是个数组,可以配置多个
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 首次运行 `pnpm:mp` 时报错。
|
||||||
|
|
||||||
|
首次运行 `pnpm:mp` 时报错,报错如下:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Error: ENOENT: no such file or directory, open '/Users/burtlai/unibest-projects/unibest/src/manifest.json'
|
||||||
|
```
|
||||||
|
|
||||||
|
首次运行 `非h5端` 时都可能出现上面的问题,需要先执行一下 `pnpm i` 以生成 `src/manifest.json` 文件,后面就不会报错了。
|
||||||
|
|
||||||
|
## 5. `git commit` 报错。
|
||||||
|
|
||||||
|
请看 `commitlint.config.ts` 里面的配置,需要满足对应的设定。根据自己的需要,可以修改 `commitlint.config.ts` 里面的配置。
|
||||||
|
|
||||||
|
如果是一次的(比如引入了某个第三方库),可以通过 `--no-verify` 参数跳过校验:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git commit -m "feat: xxx" --no-verify
|
||||||
|
```
|
||||||
|
|
||||||
|
第三方库还有另外一种处理方式,放到特定的文件夹,然后在 `.eslintignore` 和 `.styleintignore` 里面加上该文件夹。
|
||||||
|
|
||||||
|
## 6. `uni-app` 无法使用 `process.env` 变量,怎么办?
|
||||||
|
|
||||||
|
使用 `import.meta.env` 替代!
|
||||||
|
|
||||||
|
## 7. 如何跟随 `uni-app` 官方升级?
|
||||||
|
|
||||||
|
项目下,执行 `npx @dcloudio/uvm@latest` 即可更新。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 注意,上面的命令会自动安装 `vue-i18n`,可以手动删除(`pnpm un vue-i18n`),也可以不理它(没多大影响)。
|
||||||
|
|
||||||
|
## 8. 如何把已经加入 `git` 管理的文件移出 `git` 管理?
|
||||||
|
|
||||||
|
- 第一步,先把文件移出`git` 管理,操作如下:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# git rm -r --cached file1 file2 ## 针对某些文件
|
||||||
|
# git rm -r --cached dir1 dir2 ## 针对某些文件夹
|
||||||
|
# git rm -r --cached . ## 针对所有文件
|
||||||
|
```
|
||||||
|
|
||||||
|
- 第二步,提交 `commit` 以正式删除的文件
|
||||||
|
|
||||||
|
> 总结:`git rm -r --cached .` + `git commit` 即可。
|
||||||
|
|
||||||
|
## 9. 支付宝小程序运行报错。
|
||||||
|
|
||||||
|
- 默认运行是会报错的,如下图
|
||||||
|

|
||||||
|
|
||||||
|
- 只需要勾上 `本地开发跳过 ES5 转译` 即可正常运行,如下图
|
||||||
|

|
||||||
|
|
||||||
|
> 总结:勾上 `本地开发跳过 ES5 转译` 即可。
|
||||||
|
|
||||||
|
## 10. 支持 `uni-app x` 吗?
|
||||||
|
|
||||||
|
不支持。但我们一直保持关注。[uni-app x 传送门](https://doc.dcloud.net.cn/uni-app-x/)
|
||||||
|
|
||||||
|
目前 `unibest` 已经有 `hbx` 模板,后续接入 `uni-app x` 会很容易,坐等官方发布。
|
||||||
|
|
||||||
|
## 11. 为啥 `vue` 已经 `3.4+` 了,还不支持 `defineModel` ?
|
||||||
|
|
||||||
|
`uni-app` 官方虽然已经把 `vue` 升级到 `3.4+` 了,但是目前只有 `H5端` 支持 `defineModel`,其他端目前运行报错,详情请看 `uni-app` 官网的发布日志:
|
||||||
|
|
||||||
|
[HBuilder X - Release Notes](https://3085868976.hiecheimaetu.com:22443/qn-GO8xCsKgpKDZWIBAkVCUkI1EnGmQUMT4.update.dcloud.net.cn/hbuilderx/changelog/4.14.2024043013.html)
|
||||||
|
|
||||||
|
关键截图如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
真实运行报错截图如下:(分别是 `小程序` 和 `APP` )
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
全文完~
|
267
docs/base/15-faq.md
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
# 常见问题 2
|
||||||
|
|
||||||
|
## 1. `wot-ui` 的 `toast` + `message-box` 不生效。
|
||||||
|
|
||||||
|
- 1. `layout` 引入 `wot-ui` 的 `toast` + `message-box`。
|
||||||
|
|
||||||
|
```vue [src/layouts/default.vue]
|
||||||
|
<!-- src/layouts/default.vue -->
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<slot />
|
||||||
|
<wd-toast />
|
||||||
|
<wd-message-box />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
> `unibest@2.1.0` 开始已经默认引入。
|
||||||
|
|
||||||
|
- 2.页面使用
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { useMessage } from 'wot-design-uni'
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
const handleClick = () => {
|
||||||
|
// 顺便测试 message 的使用
|
||||||
|
message.show('显示隐藏切换')
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. `uni-app` 插件市场的插件如何使用?
|
||||||
|
|
||||||
|
`hbx` 模板可以直接引入,不在讨论范围内,下面描述的是 `普通模板`。
|
||||||
|
|
||||||
|
> 如果该插件支持 `npm` 安装,则直接安装即可,推荐统一使用 `pnpm` 安装。接着根据该插件的文档使用即可。
|
||||||
|
|
||||||
|
下面描写的是不支持 `npm` 安装的插件。
|
||||||
|
|
||||||
|
这里以 `sp-editor` 富文本插件为例,[插件地址](https://ext.dcloud.net.cn/plugin?id=14726)
|
||||||
|
|
||||||
|
- 1. 下载 `uni-app` 插件市场的代码。(居然要登录+看广告)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 2. 解压并拷贝到 `unibest` 项目的 `uni_modules` 目录下。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 3. 整理插件文件夹名称,把 `sp-editor_1.3.7` 改为 `sp-editor`。
|
||||||
|
|
||||||
|
> 不改会报错,因为内部代码都是用 `sp-editor` 不带版本号的。会导致查找文件失败。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 4. 代码直接使用,无需引入组件。( `uni-app插件` 有一套规范,`uni-app` 会自动查找,跟 `easycom` 类似。)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<view class="home">
|
||||||
|
<view class="editor-box">
|
||||||
|
<sp-editor
|
||||||
|
:toolbar-config="{
|
||||||
|
excludeKeys: ['direction', 'date', 'lineHeight', 'letterSpacing', 'listCheck'],
|
||||||
|
iconSize: '18px',
|
||||||
|
}"
|
||||||
|
@init="initEditor"
|
||||||
|
@input="inputOver"
|
||||||
|
@upinImage="upinImage"
|
||||||
|
@overMax="overMax"
|
||||||
|
@addLink="addLink"
|
||||||
|
@exportHtml="exportHtml"
|
||||||
|
></sp-editor>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
完整版见下:
|
||||||
|
:::details
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<route lang="json5">
|
||||||
|
{
|
||||||
|
layout: 'demo',
|
||||||
|
style: { navigationBarTitleText: '富文本' },
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="home">
|
||||||
|
<view class="editor-box">
|
||||||
|
<sp-editor
|
||||||
|
:toolbar-config="{
|
||||||
|
excludeKeys: ['direction', 'date', 'lineHeight', 'letterSpacing', 'listCheck'],
|
||||||
|
iconSize: '18px',
|
||||||
|
}"
|
||||||
|
@init="initEditor"
|
||||||
|
@input="inputOver"
|
||||||
|
@upinImage="upinImage"
|
||||||
|
@overMax="overMax"
|
||||||
|
@addLink="addLink"
|
||||||
|
@exportHtml="exportHtml"
|
||||||
|
></sp-editor>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const editorIns = ref(null)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取输入内容
|
||||||
|
* @param {Object} e {html,text} 内容的html文本,和text文本
|
||||||
|
*/
|
||||||
|
function inputOver(e) {
|
||||||
|
// 可以在此处获取到编辑器已编辑的内容
|
||||||
|
console.log('==== inputOver :', e)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 超出最大内容限制
|
||||||
|
* @param {Object} e {html,text} 内容的html文本,和text文本
|
||||||
|
*/
|
||||||
|
function overMax(e) {
|
||||||
|
// 若设置了最大字数限制,可在此处触发超出限制的回调
|
||||||
|
console.log('==== overMax :', e)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑器就绪
|
||||||
|
* @param {Object} editor 编辑器实例,你可以自定义调用editor实例的方法
|
||||||
|
* @tutorial editor组件 https://uniapp.dcloud.net.cn/component/editor.html#editor-%E7%BB%84%E4%BB%B6
|
||||||
|
* @tutorial 相关api https://uniapp.dcloud.net.cn/api/media/editor-context.html
|
||||||
|
*/
|
||||||
|
function initEditor(editor) {
|
||||||
|
editorIns.value = editor // 保存编辑器实例
|
||||||
|
// 保存编辑器实例后,可以在此处获取后端数据,并赋值给编辑器初始化内容
|
||||||
|
preRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
function preRender() {
|
||||||
|
setTimeout(() => {
|
||||||
|
// 异步获取后端数据后,初始化编辑器内容
|
||||||
|
editorIns.value.setContents({
|
||||||
|
html: `<div> 猫猫<img src="https://img.yzcdn.cn/vant/cat.jpeg"/></div>`,
|
||||||
|
})
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接运行示例工程插入图片无法正常显示的看这里
|
||||||
|
* 因为插件默认采用云端存储图片的方式
|
||||||
|
* 以$emit('upinImage', tempFiles, this.editorCtx)的方式回调
|
||||||
|
* @param {Object} tempFiles
|
||||||
|
* @param {Object} editorCtx
|
||||||
|
*/
|
||||||
|
function upinImage(tempFiles, editorCtx) {
|
||||||
|
/**
|
||||||
|
* 本地临时插入图片预览
|
||||||
|
* 注意:这里仅是示例本地图片预览,因为需要将图片先上传到云端,再将图片插入到编辑器中
|
||||||
|
* 正式开发时,还请将此处注释,并解开下面 使用 uniCloud.uploadFile 上传图片的示例方法 的注释
|
||||||
|
* @tutorial https://uniapp.dcloud.net.cn/api/media/editor-context.html#editorcontext-insertimage
|
||||||
|
*/
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 注意微信小程序的图片路径是在tempFilePath字段中
|
||||||
|
editorCtx.insertImage({
|
||||||
|
src: tempFiles[0].tempFilePath,
|
||||||
|
width: '80%', // 默认不建议铺满宽度100%,预留一点空隙以便用户编辑
|
||||||
|
success: function () {},
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
editorCtx.insertImage({
|
||||||
|
src: tempFiles[0].path,
|
||||||
|
width: '80%', // 默认不建议铺满宽度100%,预留一点空隙以便用户编辑
|
||||||
|
success: function () {},
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 uniCloud.uploadFile 上传图片的示例方法(可适用多选上传)
|
||||||
|
* 正式开发环境中,请将上面 本地临时插入图片预览 注释后,模仿以下写法
|
||||||
|
*/
|
||||||
|
// tempFiles.forEach(async (item) => {
|
||||||
|
// uni.showLoading({
|
||||||
|
// title: '上传中请稍后',
|
||||||
|
// mask: true
|
||||||
|
// })
|
||||||
|
// let upfile = await uniCloud.uploadFile({
|
||||||
|
// filePath: item.path,
|
||||||
|
// // 同名会导致报错 policy_does_not_allow_file_overwrite
|
||||||
|
// // cloudPath可由 想要存储的文件夹/文件名 拼接,若不拼文件夹名则默认存储在cloudstorage文件夹中
|
||||||
|
// cloudPath: `cloudstorage/${item.name}`,
|
||||||
|
// cloudPathAsRealPath: true
|
||||||
|
// })
|
||||||
|
// editorCtx.insertImage({
|
||||||
|
// src: upfile.fileID,
|
||||||
|
// width: '80%', // 默认不建议铺满宽度100%,预留一点空隙以便用户编辑
|
||||||
|
// success: function () {
|
||||||
|
// uni.hideLoading()
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出 - toolbar需要开启export工具
|
||||||
|
* @param {string} e 导出的html内容
|
||||||
|
*/
|
||||||
|
function exportHtml(e) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/out/out',
|
||||||
|
success(res) {
|
||||||
|
// 传至导出页面解析即可
|
||||||
|
res.eventChannel.emit('e-transmit-html', {
|
||||||
|
data: e,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加超链接
|
||||||
|
* @param {Object} e { text: '链接描述', href: '链接地址' }
|
||||||
|
*/
|
||||||
|
function addLink(e) {
|
||||||
|
console.log('==== addLink :', e)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 3. Vue-Office 使用哪个版本?
|
||||||
|
|
||||||
|
使用 `1.8x`,而不是 `2.x`,否则出现下面这样的问题:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 4. 为啥不用 `vant-ui`?
|
||||||
|
|
||||||
|
`vant-ui` 是 `WEB` 端 `UI 库`,不适用于 `uni-app`。
|
||||||
|
|
||||||
|
`uni-app` 没有 `window`, `document` 等 `WEB API`,所以凡是使用 `WEB API` 的 `框架`、`UI 库` 等都不适用于 `uni-app`。
|
||||||
|
|
||||||
|
## 4. 控制台报错 `[plugin:uni:mp-using-component] Unexpected token S in JSON at position 208`。
|
||||||
|
|
||||||
|
控制台报错如下:
|
||||||
|

|
||||||
|
|
||||||
|
原因是 `uni-pages` 这个插件最新版本 `0.2.22` 有问题,需要回退到 `0.2.20`。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
执行如下命令即可:
|
||||||
|
|
||||||
|
```
|
||||||
|
pnpm add @uni-helper/vite-plugin-uni-pages@0.2.20
|
||||||
|
```
|
||||||
|
|
||||||
|
> 因为 `unibest` 在 `2.3.0(含)` 之前没有把 `pnpm-lock.yaml` 加入到版本管理,导致小版还是有细微差别。
|
||||||
|
>
|
||||||
|
> 在 `2.4.0` 开始已经加入,不会再出现这个问题。
|
119
docs/base/2-start.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# 快速开始
|
||||||
|
|
||||||
|
- 前置依赖
|
||||||
|
|
||||||
|
- **Node.js** - `>=v18`
|
||||||
|
- **pnpm** - `>=7.30`(推荐使用 `8.12+`)
|
||||||
|
- **`VSCode`** - 可选 `WebStrom`
|
||||||
|
- **`HBuilderX`** - `APP` 的运行和发布还是离不开它
|
||||||
|
- **Vue-Office** - `1.8x`,别升到 `2.x` !
|
||||||
|
|
||||||
|
## 创建项目
|
||||||
|
|
||||||
|
通过下面的命令可以快速生成项目模板,`pnpm create unibest <项目名称>` ,如果不写 `<项目名称>` 会进入命令行交互模式。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 如果没有 pnpm,请先安装: npm i -g pnpm
|
||||||
|
pnpm create unibest my-project
|
||||||
|
```
|
||||||
|
|
||||||
|
npm 创建如下(不推荐)
|
||||||
|
:::details
|
||||||
|
如果使用 `npm`,可能有缓存,需要加上 `@latest` 标识,如果创建失败,请使用 `pnpm` 安装。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm create unibest my-project
|
||||||
|
# 如果提示报错,或者生成的项目版本太旧,请使用下面的命令,增加 @latest 标识
|
||||||
|
npm create unibest@latest my-project
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
实际操作截图如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
`create-unibest` 在 `v1.10.0` 开始会有版本号,如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
`create unibest` 支持 `-t` 参数选择模板,目前已有两大类 `8` 个模板
|
||||||
|
|
||||||
|
- `普通` 模板( `4个` ):分别是 `base`、`tabbar`、`i18n`、`demo`、~~`js`~~
|
||||||
|
- `hbx` 模板(`2个` ):分别是 `hbx-base`、`hbx-demo`。
|
||||||
|
|
||||||
|
不带 `-t` 参数时会默认生成 `base` 模板。
|
||||||
|
|
||||||
|
`base` 模板是最基本的模板,更新最及时,推荐使用 `base` 模板创建新项目。其他几个模板也是基于 `base` 模板得到的。 `demo` 模板则作为参考用。
|
||||||
|
|
||||||
|
`js` 模板不推荐使用,可以使用 `base` 模板替代,里面已经做了兼容配置,可以直接编写 `js`,原本的 `ts` 文件还能提供部分类型,何乐而不为?
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# VS Code 模板
|
||||||
|
pnpm create unibest my-project # 默认用 base 模板
|
||||||
|
|
||||||
|
pnpm create unibest my-project -t base # 基础模板
|
||||||
|
pnpm create unibest my-project -t tabbar # 自定义 tabbar 模板
|
||||||
|
pnpm create unibest my-project -t i18n # 多语言模板
|
||||||
|
pnpm create unibest my-project -t demo # 所有demo的模板(包括i18n)
|
||||||
|
# pnpm create unibest my-project -t js # js 模板
|
||||||
|
|
||||||
|
# HBuilderX 模板,方便使用 uniCloud 云开发 (未来可以对接 uni-app x)
|
||||||
|
pnpm create unibest my-project -t hbx-base # hbx的base模板
|
||||||
|
pnpm create unibest my-project -t hbx-demo # hbx的demo模板,包含所有的demo
|
||||||
|
```
|
||||||
|
|
||||||
|
## 项目仓库地址
|
||||||
|
|
||||||
|
`github` 和 `gitee` 实时同步,代码一致。
|
||||||
|
|
||||||
|
### 普通模板:
|
||||||
|
|
||||||
|
- https://github.com/feige996/unibest
|
||||||
|
- https://gitee.com/feige996/unibest
|
||||||
|
|
||||||
|
> `demo` 模板是在 `hello-unibest` 项目中,仓库地址如下:
|
||||||
|
|
||||||
|
- https://github.com/feige996/hello-unibest
|
||||||
|
- https://gitee.com/feige996/hello-unibest
|
||||||
|
|
||||||
|
### hbx 模板
|
||||||
|
|
||||||
|
- https://github.com/feige996/unibest-hbx
|
||||||
|
- https://gitee.com/feige996/unibest-hbx
|
||||||
|
|
||||||
|
> `hbx` 目前由 `青谷` 大佬维护,微信号:`qingguxixi`,[青谷 github 地址](https://github.com/Xiphin) 。
|
||||||
|
|
||||||
|
## 安装、运行
|
||||||
|
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm i
|
||||||
|
pnpm dev
|
||||||
|
# dev默认运行的是h5,其他平台执行dev:<uni-platform>,如:
|
||||||
|
pnpm dev:mp-weixin
|
||||||
|
```
|
||||||
|
|
||||||
|
`pnpm dev` 之后在浏览器打开 `http://localhost:9000/`。
|
||||||
|
|
||||||
|
> 其他平台构建和发布,查看 [运行发布篇](./11-build)。
|
||||||
|
|
||||||
|
## 第一次 `commit`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: init project"
|
||||||
|
```
|
||||||
|
|
||||||
|
## `v3` 代码块
|
||||||
|
|
||||||
|
在 `vue` 文件中,输入 `v3` 按 `tab` 即可快速生成页面模板,可以大大加快页面生成。
|
||||||
|
|
||||||
|
> 原理:基于 `VSCode` 代码块生成。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- 若代码里面自动引入的 `API` 报错,只需要 `pnpm dev` 即可。
|
||||||
|
- 若代码运行后,`H5端` 浏览器界面底部没有 `tabbar`, 刷新浏览器或者再次 `pnpm dev` 即可。
|
25
docs/base/20-best.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# 最佳实践
|
||||||
|
|
||||||
|
新项目使用 `base` 模板,可选 `tabbar` 模板。如果需要多语言,可以选 `i18n` 模板。
|
||||||
|
|
||||||
|
同时参考 `demo` 模板,可以直接 `clone` `demo` 项目,用来参考用。
|
||||||
|
|
||||||
|
> 推荐先全部体验一下 `demo` 的示例
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 新项目创建
|
||||||
|
pnpm create unibest my-project -b base
|
||||||
|
# 参考项目
|
||||||
|
git clone https://github.com/feige996/hello-unibest unibest-demo
|
||||||
|
# 参考项目-gitee (与 github 同步,无梯子用户优先使用 gitee)
|
||||||
|
git clone https://gitee.com/feige996/hello-unibest unibest-demo
|
||||||
|
```
|
||||||
|
|
||||||
|
## 必看章节
|
||||||
|
|
||||||
|
- [介绍](/base/1-introduction)
|
||||||
|
- [快速开始](/base/2-start)
|
||||||
|
- [uni 插件](/base/3-plugin)
|
||||||
|
- [常见问题](/base/14-faq)
|
||||||
|
- [常见问题 2](/base/15-faq)
|
||||||
|
- [运行发布](/base/11-build)
|
158
docs/base/3-plugin.md
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
# uni 插件
|
||||||
|
|
||||||
|
## 引言
|
||||||
|
|
||||||
|
有群友第一次看到 `unibest` 里面 `vue` 文件 `route-block` 这种写法,表示很奇怪,重来没见过!
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<route lang="json5">
|
||||||
|
{
|
||||||
|
layout: 'demo',
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '标题',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="text-green-500">菲鸽,你好,我喜欢你!</view>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## uni 插件总览
|
||||||
|
|
||||||
|
哈哈,这个当然是 `uni插件` 的功劳了,具体点是 `@uni-helper/vite-plugin-uni-pages` 插件的功劳,该插件由 `uni-helper` 官方团队开发。
|
||||||
|
|
||||||
|
本文就来说说 `unibest` 都引入了哪些有用的 `uni插件`。下面这个表格描述了各个插件的主要作用。
|
||||||
|
|
||||||
|
| 插件名 | 作用 |
|
||||||
|
| :----------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| @dcloudio/vite-plugin-uni | **最核心的 `uni 插件`**,没有它就不能在 vite 项目跑 uniapp,其他所有的 `uni插件` 都需要经通过它的手来编译,所以写法上,都是先写 `UniXXX`,再写 `Uni`,见下文 |
|
||||||
|
| @uni-helper/vite-plugin-uni-pages | `uni 插件`,也是 `unibest 灵魂插件`,`route-block` 就是它的功劳,让你可以直接在本文件就能设置页面的路元信息,无需跑去 `pages.json` 配置,同时支持 `pages.config.ts` 编写 `pages.json` |
|
||||||
|
| @uni-helper/vite-plugin-uni-layouts | `uni 插件`,支多种 `layouts` 布局,群友脑洞大开,充分利用这个特性实现平时不容实现的写法 |
|
||||||
|
| @uni-helper/vite-plugin-uni-manifest | `uni 插件`,支持 `manifest.config.ts` 编写 `manifest.json` |
|
||||||
|
|
||||||
|
`UniXXX()` 插件都需要在 `uni()` 之前引入,因为最终都需要 `Uni` 来处理所有的代码。如下图:
|
||||||
|

|
||||||
|
|
||||||
|
接下来介绍一下 `uni 插件`,其他 `通用插件` 大家都比较熟悉,不再赘述。
|
||||||
|
|
||||||
|
`unibest` 引入了 `uni-helper` 团队的几个重要插件,少了它们 `unibest` 就缺少了灵魂,感谢 `uni-helper` 团队的贡献。`Uni 插件` 列表如下:
|
||||||
|
|
||||||
|
- `vite-plugin-uni-pages`
|
||||||
|
|
||||||
|
- 介绍:为 `Vite` 下的 `uni-app` 提供基于文件系统的路由
|
||||||
|
- 额外:使用 `TypeScript` 来编写 `uni-app` 的 `pages.json`
|
||||||
|
- 访问地址:[@uni-helper/vite-plugin-uni-pages](https://github.com/uni-helper/vite-plugin-uni-pages)
|
||||||
|
|
||||||
|
- `vite-plugin-uni-layouts`
|
||||||
|
|
||||||
|
- 介绍:为 `Vite` 下的 `uni-app` 提供类 `nuxt` 的 `layouts` 系统
|
||||||
|
- 访问地址:[@uni-helper/vite-plugin-uni-layouts](https://github.com/uni-helper/vite-plugin-uni-layouts)
|
||||||
|
|
||||||
|
- `vite-plugin-uni-manifest`
|
||||||
|
|
||||||
|
- 介绍:使用 `TypeScript` 来编写 `uni-app` 的 `manifest.json`
|
||||||
|
- 访问地址:[@uni-helper/vite-plugin-uni-manifest](https://github.com/uni-helper/vite-plugin-uni-manifest)
|
||||||
|
|
||||||
|
## vite-plugin-uni-pages
|
||||||
|
|
||||||
|
得益于 [@uni-helper/vite-plugin-uni-pages](https://github.com/uni-helper/vite-plugin-uni-pages),约定式路由(文件路由)的实现轻而易举。
|
||||||
|
|
||||||
|
`src/pages` 目录下的每个文件都代表着一个路由。要创建新页面,只需要在这个目录里新增 `.vue` 文件,插件会自动生成对应的 `pages.json` 文件。
|
||||||
|
|
||||||
|
`route` 代码块则可以配置页面相关信息,这些信息会自动同步到 `page.json`,无需切换到 `page.json` 进行配置。
|
||||||
|
|
||||||
|
> `pages.json` 文件是自动生成的,请不要手动修改,全局的东西请在 `pages.config.ts` 里面配置,页面上的东西请在 `vue` 文件的 `route` 代码块配置,如下图。
|
||||||
|
|
||||||
|
```vue [src/pages/index.vue]
|
||||||
|
<!-- 使用 type="home" 属性设置首页,其他页面不需要设置,默认为page -->
|
||||||
|
<!-- 推荐使用json5,更强大,且允许注释 -->
|
||||||
|
<route lang="json5" type="home">
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
navigationBarTitleText: '首页',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>欢迎使用 unibest</h1>
|
||||||
|
<h4>unibest 是最好的 uniapp 开发模板</h4>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
```vue [src/pages/about.vue]
|
||||||
|
<route lang="json5">
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '关于',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view>通过 `/pages/about` 来访问这个页面</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 设置首页
|
||||||
|
|
||||||
|
通过在 `route-block` 里面配置 `type="home"` 即可,尽量保证一个项目 `只有一个` 这个配置,如果有多个,会按照字母顺序来排列,最终可能不是您想要的效果。
|
||||||
|
|
||||||
|
### 设置 pages 过滤和分包
|
||||||
|
|
||||||
|
- 过滤:默认 `src/pages` 里面的 `vue` 文件都会生成一个页面,如果不需要生成页面可以对 `vite.config.ts` 中的 `UniPages` 进行 `exclude` 配置。
|
||||||
|
|
||||||
|
- 分包:如果需要设置 `分包` 则可以通过 `subPackages` 进行配置,该配置项是个数组,可以配置多个 `分包`,注意分包的目录不能为 `src/pages` 里面的子目录。
|
||||||
|
|
||||||
|
```ts [vite.config.ts]
|
||||||
|
UniPages({
|
||||||
|
exclude: ['**/components/**/**.*'],
|
||||||
|
subPackages: ['src/pages-sub'], // 是个数组,可以配置多个,但不能为 `src/pages` 里面的子目录
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## vite-plugin-uni-layouts
|
||||||
|
|
||||||
|
得益于 [@uni-helper/vite-plugin-uni-layouts](https://github.com/uni-helper/vite-plugin-uni-layouts),你可以轻松地切换不同的布局。
|
||||||
|
|
||||||
|
`src/layouts` 文件夹下的 `vue` 文件都会自动生成一个布局,默认的布局文件名为 `default` ,路径 `src/layouts/default.vue` 。
|
||||||
|
|
||||||
|
如果需要修改使用的布局,可以通过 `vue` 文件内 `route` 代码块指定需要的布局,如下示例使用 `demo` 布局。
|
||||||
|
|
||||||
|
```vue [src/pages/demo.vue]{3}
|
||||||
|
<route lang="json5">
|
||||||
|
{
|
||||||
|
layout: 'demo',
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '关于',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
```
|
||||||
|
|
||||||
|
```vue [src/layouts/demo.vue]
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<!-- 这里可以写通用的布局,比如导航栏,tabbar等 -->
|
||||||
|
<!-- slot里面装的就是子页面的内容 -->
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## vite-plugin-uni-manifest
|
||||||
|
|
||||||
|
得益于 [@uni-helper/vite-plugin-uni-manifest](https://github.com/uni-helper/vite-plugin-uni-manifest),你可以使用 `TypeScript` 来编写 `manifest.json`。
|
||||||
|
|
||||||
|
> `manifest.json` 文件是自动生成的,请不要手动修改,需要配置的内容请在 `manifest.config.ts` 里面配置。
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文介绍了 `unibest` 引入的几个重要的 `uni插件`。
|
||||||
|
|
||||||
|
如果还想了解更多信息,可以去 `uni-helper` [github 仓库](https://github.com/uni-helper) 看看。
|
220
docs/base/4-style.md
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
# 样式篇
|
||||||
|
|
||||||
|
本篇主要介绍 `UnoCSS` 的使用,以及如何与 `设计稿尺寸` 对应。
|
||||||
|
|
||||||
|
## UnoCSS
|
||||||
|
|
||||||
|
[UnoCSS](https://unocss.dev/) 是按需使用的原子 CSS 引擎,提供了良好的样式支持。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
在 VSCode 中还可以预览,
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 如果原子化 `UnoCSS` 没有预览效果,请安装 `VSCode` 插件 `antfu.unocss`。
|
||||||
|
|
||||||
|
如果不记得原子类,可以查 `UnoCSS 的原子类`,[UnoCSS Interactive](https://unocss.dev/interactive/),如下图
|
||||||
|

|
||||||
|
|
||||||
|
也可以查看 `tailwindcss` 的原子类,更加清晰明了,[链接 - tailwindcss](https://tailwindcss.com/),如下图:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 常用的原子类
|
||||||
|
|
||||||
|
- 宽高内外边距: `w-2`, `h-4`, `px-6`, `mt-8`等
|
||||||
|
- 前景色背景色:`text-green-400`, `bg-green-500`
|
||||||
|
- border: `border-2`, `border-solid`, `border-green-600`, `b-r-2` (注意 `border` = `border-1`,就是说边框 `1px` 时,一般简写为 `border` )
|
||||||
|
- border-radius: `rounded-full`, `rounded-6`, `rounded-sm` (不是 `br-10`, 也不是 `b-r-10`)
|
||||||
|
- line-height: `leading-10` (不是 `l-10`, 也不是 `lh-10`)
|
||||||
|
- hover: `hover:text-green-200`, `hover:bg-green-300`, `hover:border-dashed`
|
||||||
|
- flex: `flex`, `items-center`, `justify-center`, `flex-1`
|
||||||
|
|
||||||
|
## `UnoCSS` 配置
|
||||||
|
|
||||||
|
下面内容选读:
|
||||||
|
|
||||||
|
:::details
|
||||||
|
`unocss.config.ts` 文件内容如下:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// uno.config.ts
|
||||||
|
import {
|
||||||
|
type Preset,
|
||||||
|
defineConfig,
|
||||||
|
presetUno,
|
||||||
|
presetAttributify,
|
||||||
|
presetIcons,
|
||||||
|
transformerDirectives,
|
||||||
|
transformerVariantGroup,
|
||||||
|
} from 'unocss'
|
||||||
|
|
||||||
|
import { presetApplet, presetRemRpx, transformerAttributify } from 'unocss-applet'
|
||||||
|
|
||||||
|
// @see https://unocss.dev/presets/legacy-compat
|
||||||
|
import { presetLegacyCompat } from '@unocss/preset-legacy-compat'
|
||||||
|
|
||||||
|
const isMp = process.env?.UNI_PLATFORM?.startsWith('mp') ?? false
|
||||||
|
|
||||||
|
const presets: Preset[] = []
|
||||||
|
if (isMp) {
|
||||||
|
// 使用小程序预设
|
||||||
|
presets.push(presetApplet(), presetRemRpx())
|
||||||
|
} else {
|
||||||
|
presets.push(
|
||||||
|
// 非小程序用官方预设
|
||||||
|
presetUno(),
|
||||||
|
// 支持css class属性化
|
||||||
|
presetAttributify(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default defineConfig({
|
||||||
|
presets: [
|
||||||
|
...presets,
|
||||||
|
// 支持图标,需要搭配图标库,eg: @iconify-json/carbon, 使用 `<button class="i-carbon-sun dark:i-carbon-moon" />`
|
||||||
|
presetIcons({
|
||||||
|
scale: 1.2,
|
||||||
|
warn: true,
|
||||||
|
extraProperties: {
|
||||||
|
display: 'inline-block',
|
||||||
|
'vertical-align': 'middle',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
// 将颜色函数 (rgb()和hsl()) 从空格分隔转换为逗号分隔,更好的兼容性app端,example:
|
||||||
|
// `rgb(255 0 0)` -> `rgb(255, 0, 0)`
|
||||||
|
// `rgba(255 0 0 / 0.5)` -> `rgba(255, 0, 0, 0.5)`
|
||||||
|
presetLegacyCompat({
|
||||||
|
commaStyleColorFunction: true,
|
||||||
|
}) as Preset,
|
||||||
|
],
|
||||||
|
/**
|
||||||
|
* 自定义快捷语句
|
||||||
|
* @see https://github.com/unocss/unocss#shortcuts
|
||||||
|
*/
|
||||||
|
shortcuts: [['center', 'flex justify-center items-center']],
|
||||||
|
transformers: [
|
||||||
|
// 启用 @apply 功能
|
||||||
|
transformerDirectives(),
|
||||||
|
// 启用 () 分组功能
|
||||||
|
// 支持css class组合,eg: `<div class="hover:(bg-gray-400 font-medium) font-(light mono)">测试 unocss</div>`
|
||||||
|
transformerVariantGroup(),
|
||||||
|
// Don't change the following order
|
||||||
|
transformerAttributify({
|
||||||
|
// 解决与第三方框架样式冲突问题
|
||||||
|
prefixedOnly: true,
|
||||||
|
prefix: 'fg',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
rules: [
|
||||||
|
[
|
||||||
|
'p-safe',
|
||||||
|
{
|
||||||
|
padding:
|
||||||
|
'env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
['pt-safe', { 'padding-top': 'env(safe-area-inset-top)' }],
|
||||||
|
['pb-safe', { 'padding-bottom': 'env(safe-area-inset-bottom)' }],
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最终这一套组合下来会得到:
|
||||||
|
* mp 里面:mt-4 => margin-top: 32rpx == 16px
|
||||||
|
* h5 里面:mt-4 => margin-top: 1rem == 16px
|
||||||
|
*
|
||||||
|
* 另外,我们还可以推算出 UnoCSS 单位与设计稿差别4倍。
|
||||||
|
* 375 * 4 = 1500,把设计稿设置为1500,那么设计稿里多少px,unocss就写多少述职。
|
||||||
|
* 举个例子,设计稿显示某元素宽度100px,就写w-100即可。
|
||||||
|
*
|
||||||
|
* 如果是传统方式写样式,则推荐设计稿设置为 750,这样设计稿1px,代码写1rpx。
|
||||||
|
* rpx是响应式的,可以让不同设备的屏幕显示效果保持一致。
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
### UnoCSS presets
|
||||||
|
|
||||||
|
主要有 `4`个:
|
||||||
|
|
||||||
|
- `presetUno` —— `UnoCSS` 默认的预设,`H5端` 适用,`非H5端` 不支持,代码已经作区别处理。
|
||||||
|
- `presetApplet` 小程序预设,因为默认 `Unocss 预设` 是针对 `WEB` 的,如果不加以处理,会报错,比如小程序不支持 `*`, 没有 `body` 等。该预设同样对 `APP` 生效。
|
||||||
|
- `presetIcons`,专门使用 `UnoCSS Icons` 的,需要搭配图标库使用,eg: `@iconify-json/carbon`, 代码编写如 `<button class="i-carbon-sun dark:i-carbon-moon" />`
|
||||||
|
- `presetLegacyCompat` 针对低端 `APP` 不认识新的函数颜色的兼容性预设,可以将颜色函数 `rgb()和hsl()` 里面空格分隔转换为逗号分隔,更好的兼容性`APP`端,example:
|
||||||
|
> `rgb(255 0 0)` -> `rgb(255, 0, 0)`
|
||||||
|
>
|
||||||
|
> `rgba(255 0 0 / 0.5)` -> `rgba(255, 0, 0, 0.5)`
|
||||||
|
|
||||||
|
### UnoCSS shortcuts
|
||||||
|
|
||||||
|
```ts
|
||||||
|
/**
|
||||||
|
* 自定义快捷语句
|
||||||
|
* @see https://github.com/unocss/unocss#shortcuts
|
||||||
|
*/
|
||||||
|
shortcuts: [['center', 'flex justify-center items-center']],
|
||||||
|
```
|
||||||
|
|
||||||
|
可以编写一些常用的快捷类名,如上表示 `center` 就是 `flex justify-center items-center` 的组合,合理的添加快捷类名可以加快样式编写。
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 设计稿尺寸
|
||||||
|
|
||||||
|
不同的编写方式,需要设置不同的设计稿尺寸,请看下文:
|
||||||
|
|
||||||
|
### 1. 传统编写方式
|
||||||
|
|
||||||
|
如果有设计稿,通常使用传统的编写 `CSS` 的方式,里面的对应尺寸规律如下。以蓝湖为例,假如设计稿宽度为 `750px`,则直接复制样式代码到 css 代码,同时把 `px` 批量替换为 `rpx` 即可。
|
||||||
|
|
||||||
|
如果设计稿不是 `750px` 可以调整蓝湖的设置,让设计稿宽度为 `750px`。
|
||||||
|
|
||||||
|
> 下面为一段辅助说明文案,从 `uniapp` 官网搬运而来。
|
||||||
|
|
||||||
|
`rpx` 是相对于基准宽度的单位,可以根据屏幕宽度进行自适应。`uni-app` 规定屏幕基准宽度 `750rpx`。
|
||||||
|
|
||||||
|
开发者可以通过设计稿基准宽度计算页面元素 `rpx` 值,设计稿 `1px` 与框架样式 `1rpx` 转换公式如下:
|
||||||
|
|
||||||
|
`设计稿 1px / 设计稿基准宽度 = 框架样式 1rpx / 750rpx`
|
||||||
|
|
||||||
|
换言之,页面元素宽度在 `uni-app` 中的宽度计算公式:
|
||||||
|
|
||||||
|
`750 * 元素在设计稿中的宽度 / 设计稿基准宽度`
|
||||||
|
|
||||||
|
举例说明:
|
||||||
|
|
||||||
|
若设计稿宽度为 `750px`,元素 `A` 在设计稿上的宽度为 `100px`,那么元素 `A` 在 `uni-app` 里面的宽度应该设为:`750 * 100 / 750`,结果为:`100rpx`。
|
||||||
|
|
||||||
|
若设计稿宽度为 `640px`,元素 `A` 在设计稿上的宽度为 `100px`,那么元素 `A` 在 `uni-app` 里面的宽度应该设为:`750 * 100 / 640`,结果为:`117rpx`。
|
||||||
|
|
||||||
|
若设计稿宽度为 `375px`,元素 `B` 在设计稿上的宽度为 `200px`,那么元素 `B` 在 `uni-app` 里面的宽度应该设为:`750 * 200 / 375`,结果为:`400rpx`。
|
||||||
|
|
||||||
|
### 2. UnoCSS 编写方式
|
||||||
|
|
||||||
|
经过上一节的 `unocss.config.ts` 配置,可以得到下面的组合:
|
||||||
|
|
||||||
|
> mp 里面:mt-4 => margin-top: 32rpx == 16px
|
||||||
|
>
|
||||||
|
> h5 里面:mt-4 => margin-top: 1rem == 16px
|
||||||
|
|
||||||
|
我们还是把设计稿设置为 `750`,设计稿上多少 `px` 的元素,写成多少 `rpx` 即可。
|
||||||
|
|
||||||
|
元素 `A` 在设计稿上的宽度为 `100px`,则写 `w-100rpx` 即可。
|
||||||
|
|
||||||
|
就是把 `传统编写方式` 中写在 `css` 中的样式搬到了 `UnoCSS` 中。
|
||||||
|
|
||||||
|
如果要想用 `w-100` 这种方式,需要做额外的处理(待验证):
|
||||||
|
|
||||||
|
:::details
|
||||||
|
太忙了,有空再写吧。
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文主要介绍了 `UnoCSS` 的使用,以及 `unocss.config.ts` 中的一些配置项。
|
||||||
|
|
||||||
|
同时说明了设计稿在两种编写方式下的宽度的设置,分别为 `750` 和 `1500`.
|
||||||
|
|
||||||
|
最后说明一下,`原子化CSS` 和 `传统方式` 两者不是互斥的,他们是互补的,合适的地方使用合适的方式。
|
189
docs/base/5-icons.md
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# 图标篇
|
||||||
|
|
||||||
|
本文主要介绍了 `图标` 的使用方式,通常有以下几种方式使用图标:
|
||||||
|
|
||||||
|
- `UI 库 Icons`
|
||||||
|
- `UnoCSS Icons`
|
||||||
|
- `iconfont`
|
||||||
|
|
||||||
|
下面笔者一一介绍
|
||||||
|
|
||||||
|
## UI 库 Icons
|
||||||
|
|
||||||
|
如果您已经引入了 `UI库`,并且正好该 `UI库` 已经有你想要的 `Icons`,那直接用最方便了,无需额外引入其他库,代码也是最少的。
|
||||||
|
|
||||||
|
这里介绍几个常用 `UI库` 的图标使用。
|
||||||
|
|
||||||
|
### `uni-ui Icons`
|
||||||
|
|
||||||
|
> 注意:`uni-ui Icons` 颜色只能通过 `color` 属性设置;使用 `UnoCSS` 设置无效。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<uni-icons type="contact" size="30"></uni-icons>
|
||||||
|
<uni-icons type="contact" size="30" color="red"></uni-icons>
|
||||||
|
<uni-icons type="contact" size="30" class="text-green"></uni-icons>
|
||||||
|
<uni-icons type="contact" size="30" color="red" class="text-green"></uni-icons>
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### `wot-ui Icons`
|
||||||
|
|
||||||
|
> 注意:`wot-ui icons` 颜色可以通过 `color` 属性设置,也可以通过 `UnoCSS` 设置;同时设置时,`color` 属性优先级高。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<wd-icon name="add-circle"></wd-icon>
|
||||||
|
<wd-icon name="add-circle" color="red"></wd-icon>
|
||||||
|
<wd-icon name="add-circle" class="text-green"></wd-icon>
|
||||||
|
<wd-icon name="add-circle" class="text-green" color="red"></wd-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### `uv-ui Icons`
|
||||||
|
|
||||||
|
> 注意:跟 `uni-ui Icons` 一样,`uv-ui Icons` 的颜色只能通过 `color` 属性设置;使用 `UnoCSS` 设置无效。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<uv-icon name="home"></uv-icon>
|
||||||
|
<uv-icon name="home" color="red"></uv-icon>
|
||||||
|
<uv-icon name="home" class="text-green"></uv-icon>
|
||||||
|
<uv-icon name="home" color="red" class="text-green"></uv-icon>
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 注意,经过检测这 `3个UI库Icons` 都不支持使用 `UnoCSS` 改变大小(优先级低被覆盖),必须使用 `size` 属性来设置大小才有效果(行内样式优先于 css 样式)。
|
||||||
|
>
|
||||||
|
> 另外,经过检测,都支持动态 `iconName`和动态 `color` ! 即下面这样的写法是生效的:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const iconName = ref<string>('contact')
|
||||||
|
const colorName = ref<string>('red')
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
iconName.value = 'chat'
|
||||||
|
colorName.value = 'green'
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<uni-icons :type="iconName" :color="colorName" class="text-green w-8"></uni-icons>
|
||||||
|
<!-- 其他2个UI库同样生效 -->
|
||||||
|
```
|
||||||
|
|
||||||
|
## `UnoCSS Icons`
|
||||||
|
|
||||||
|
`UnoCSS Icons` 可以方便接入 `iconify` 图标库,后者拥有 `10万+` 的海量图标,总能找到你想要的。
|
||||||
|
|
||||||
|
### 1. 安装 iconify
|
||||||
|
|
||||||
|
在使用 `iconify` 之前需要安装对应的图标库,安装格式如下:
|
||||||
|
|
||||||
|
`pnpm i -D @iconify-json/[the-collection-you-want]`
|
||||||
|
|
||||||
|
以安装 `carbon` 为例,执行 `pnpm i -D @iconify-json/carbon` 即可。
|
||||||
|
|
||||||
|
> `unibest` 已经装好了 `carbon` 图标库,可以直接使用。
|
||||||
|
|
||||||
|
### 2. 找到 iconify 想要的图标名
|
||||||
|
|
||||||
|
打开网址:<https://icones.js.org/>
|
||||||
|
|
||||||
|
- 在里面找到某个库,如 `carbon`。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 搜索想要的图表,如 `avatar`,出现的搜索结果,查看类名,也可以点击图标,会出现详情( `details` 里面)。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- 如上图( `details` 里面),拿到 `carbon:user-avatar`。
|
||||||
|
|
||||||
|
### 3. 编写代码
|
||||||
|
|
||||||
|
- 代码里面 `class` 填写 `i-carbon-user-avatar`(所有的单词用中划线连接即可)并且支持改颜色。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view class="i-carbon-user-avatar text-red" />
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 如果图标没有预览效果,请安装 `VSCode` 插件 `antfu.iconify`。
|
||||||
|
|
||||||
|
预览效果:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 4. 动态图标名
|
||||||
|
|
||||||
|
昨天有网友反馈,`UnoCSS Icons` 无法使用动态类名,我来试试:(我先说结论:是支持的!)
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const iconName = ref<string>('i-carbon-car')
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
iconName.value = 'i-carbon-user-avatar'
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view :class="iconName" />
|
||||||
|
```
|
||||||
|
|
||||||
|
一秒后会由 `i-carbon-car`(一辆车) 变成 `i-carbon-user-avatar`(一个头像),一切都是 OK 的。
|
||||||
|
|
||||||
|
> 但是注意,跨文件的话动态图标名不能生效。
|
||||||
|
|
||||||
|
## iconfont 图标库
|
||||||
|
|
||||||
|
`iconfont` 同样有海量免费的图标,同时支持上传自己的图标。公司项目通常会有自己的图标,由专业的 `UI设计师` 设计,这时通常会使用 `iconfont` 方式使用图标。
|
||||||
|
|
||||||
|
- 1. 打开`阿里巴巴矢量图标库 iconfont`,地址:[https://www.iconfont.cn/](https://www.iconfont.cn/),并登录。
|
||||||
|
- 2. 寻找需要的图标,加入项目,也可以上传自己的图标。
|
||||||
|
- 3. 图标方式选择 `Font class`,`项目设置` 勾选上 `base64`,否则`非H5端` 不支持,然后点击生成链接。
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
- 4. 把上面的 `css` 链接里面的内容写入在 `style/iconfont.css`,并引入到 `style/index.scss`。
|
||||||
|
- 5. 页面上直接写 `<i class="iconfont icon-package text-red"></i>` 即可!
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view class="m-4">
|
||||||
|
<text mr-2>iconfont:</text>
|
||||||
|
<i class="iconfont icon-package text-red"></i>
|
||||||
|
<i class="iconfont icon-chat text-red"></i>
|
||||||
|
<i class="iconfont icon-my text-red"></i>
|
||||||
|
</view>
|
||||||
|
```
|
||||||
|
|
||||||
|
预览如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 上面的选择有疑问的可以看详细版 - [iconfont 详细版](/other/iconfont/iconfont)
|
||||||
|
|
||||||
|
## 其它图标库
|
||||||
|
|
||||||
|
其他优秀的可以免费商用的图标库:
|
||||||
|
|
||||||
|
- 字节跳动的 `IconPark`,链接 [https://iconpark.oceanengine.com](https://iconpark.oceanengine.com/)。
|
||||||
|
- 不知道谁家的 `yesicon`,链接 [https://yesicon.app](https://yesicon.app/)。
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文介绍了 `3` 种使用图标的方式,分别是 `UI 库 Icons`、`UnoCSS Icons`、`iconfont`。
|
||||||
|
|
||||||
|
- `UI 库 Icons` 颜色和大小属性都主要由 `UI 库` 本身控制,且都支持动态图标名和动态颜色。
|
||||||
|
|
||||||
|
- `UnoCSS Icons` 最省心,强烈推荐使用。
|
||||||
|
|
||||||
|
- `iconfont` 需要勾选 `Base64` 才能兼容多端。
|
||||||
|
|
||||||
|
全文完~
|
181
docs/base/6-svg.md
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
# SVG 篇
|
||||||
|
|
||||||
|
上一章《五、图标篇》主要介绍了 `线上图标` 的使用,今天带给大家本地 `SVG` 图标的使用。
|
||||||
|
|
||||||
|
本地 `SVG` 图标使用方式主要有:
|
||||||
|
|
||||||
|
- `image + src` 方式
|
||||||
|
|
||||||
|
- `static目录` 图标
|
||||||
|
- `相对目录` 图标
|
||||||
|
- `线上地址` 图标
|
||||||
|
|
||||||
|
> **`图片`** 也是使用上面几种方式。
|
||||||
|
|
||||||
|
## `image + src` 方式
|
||||||
|
|
||||||
|
根据图片地址不同,分为 2 种:`static目录`图标 , `相对目录`图标。
|
||||||
|
|
||||||
|
### 1. `static目录` 图标
|
||||||
|
|
||||||
|
这种方式直接编写代码即可,如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<image src="/static/svg/demo.svg" mode="scaleToFill" class="h-20 w-20" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. `相对目录` 图标
|
||||||
|
|
||||||
|
这种方式需要先引入,再使用,代码编写如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<image :src="iconUrl" mode="scaleToFill" class="h-20 w-20" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import iconUrl from './demo.svg'
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. `线上地址` 图标
|
||||||
|
|
||||||
|
这种方式直接使用,代码编写如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<image src="https://xxx.com/demo.svg" mode="scaleToFill" class="h-20 w-20" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 其他
|
||||||
|
|
||||||
|
> `SvgComponent` 方式 和 `SvgIcon` 方式,仅 `H5端` 适用,感兴趣的可以阅读下
|
||||||
|
|
||||||
|
:::details
|
||||||
|
|
||||||
|
### `SvgComponent` 方式
|
||||||
|
|
||||||
|
从 `Web端` 过来的同学都知道 `SvgComponent` 这种方式,只需要引入 `vite-svg-loader` 插件即可,支持 `3种` 方式引入 `svg`: `url`, `raw`, `component`。
|
||||||
|
|
||||||
|
- URL
|
||||||
|
|
||||||
|
SVGs can be imported as URLs using the `?url` suffix:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import iconUrl from './my-icon.svg?url'
|
||||||
|
// 'data:image/svg+xml...'
|
||||||
|
```
|
||||||
|
|
||||||
|
Used in template:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<image :src="iconUrl" mode="scaleToFill" class="h-20 w-20" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
- Raw
|
||||||
|
|
||||||
|
SVGs can be imported as strings using the `?raw` suffix:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import iconRaw from './my-icon.svg?raw'
|
||||||
|
// '<?xml version="1.0"?>...'
|
||||||
|
```
|
||||||
|
|
||||||
|
Used in template:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>{{ iconRaw }}</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
- Component
|
||||||
|
|
||||||
|
SVGs can be explicitly imported as Vue components using the `?component` suffix:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import IconComponent from './my-icon.svg?component'
|
||||||
|
// <IconComponent />
|
||||||
|
```
|
||||||
|
|
||||||
|
Used in template:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<IconComponent />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
但是目前经过测试,只有 `url` 的方式所有端可以使用,与上面的 `image + src - 相对目录 图标` 是一个效果。至于 `component` 只有 `H5端生效`,其他端不行。
|
||||||
|
|
||||||
|
### `SvgIcon` 方式
|
||||||
|
|
||||||
|
从 `Web端` 过来的同学都知道 `SvgIcon` 这种方式,只需要引入 `vite-plugin-svg-icons` 插件 + `vite 配置`,再编写一个通用的 `SvgIcon` 即可,但是同样只有 `H5端生效`,其他端不行。
|
||||||
|
|
||||||
|
`vite` 配置如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
createSvgIconsPlugin({
|
||||||
|
// 指定要缓存的文件夹
|
||||||
|
iconDirs: [path.resolve(process.cwd(), 'src/assets')],
|
||||||
|
// 指定symbolId格式
|
||||||
|
symbolId: 'icon-[dir]-[name]',
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
如上,只需要把 `svg` 放到 `src/assets` 目录即可。
|
||||||
|
|
||||||
|
`SvgIcon` 代码如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<svg aria-hidden="true">
|
||||||
|
<use :href="symbolId" :fill="color" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="SvgIcon">
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
prefix?: string
|
||||||
|
name: string
|
||||||
|
color?: string
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
prefix: 'icon',
|
||||||
|
name: '',
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
使用方式如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- src/assets/demo.svg -->
|
||||||
|
<SvgIcon name="demo" class="h-20 w-20"></SvgIcon>
|
||||||
|
|
||||||
|
<!-- src/assets/dir/demo.svg -->
|
||||||
|
<SvgIcon name="dir-demo" class="h-20 w-20"></SvgIcon>
|
||||||
|
```
|
||||||
|
|
||||||
|
> `SvgComponent` 依赖 `vite-svg-loader` 插件
|
||||||
|
>
|
||||||
|
> `SvgIcon` 依赖 `vite-plugin-svg-icons` 插件
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本地 `svg` 的使用方式,如果要全端适配,那就只能使用 `image + src` 的方式。
|
||||||
|
|
||||||
|
> `SvgComponent` 依赖 `vite-svg-loader` 插件
|
||||||
|
>
|
||||||
|
> `SvgIcon` 依赖 `vite-plugin-svg-icons` 插件
|
||||||
|
|
||||||
|
其他 2 种方式 —— `SvgComponent` + `SvgIcon` 仅 `h5` 端生效,其他端都不能用,既然不能使用,那就删了,对应的 2 个插件也一起删了,目前 `base` 分支已经删了。
|
||||||
|
|
||||||
|
全文完~
|
120
docs/base/7-ui.md
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
# UI 库替换篇
|
||||||
|
|
||||||
|
## 默认 UI 库
|
||||||
|
|
||||||
|
`unibest` 经过几次更迭,先后使用 `uni-ui`、`uv-ui`作为默认 UI 库,目前使用 `wot-ui` 为默认 UI 库。
|
||||||
|
|
||||||
|
`wot-ui` 是 `vue3+ts` 编写的全端支持的 UI 库,编码体验比 `uv-ui` 更好;而官方维护的 `uni-ui` 则样式略丑,组件较少,故弃之。
|
||||||
|
|
||||||
|
> `wot-ui` 全称 `wot-design-uni`,是 `wot-design` 的 `uniapp` 版本,文档地址:[https://wot-design-uni.netlify.app/](https://wot-design-uni.netlify.app/).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
很多群友反馈有其他 `UI` 库的需求,那么更换 `UI 库` 需要哪些步骤呢?
|
||||||
|
|
||||||
|
- 先卸载原有的 `wot-ui` 库
|
||||||
|
- 再安装其他 `UI 库`
|
||||||
|
|
||||||
|
下面我们简单描述一下更换 2 个主流 `UI库` —— `uni-ui` + `uv-ui` 的过程。
|
||||||
|
|
||||||
|
> 当然也支持同时存在多个 `UI 库`,有 ES 摇树特性,不必担心打包后的体积。
|
||||||
|
|
||||||
|
## 卸载 wot-ui 库
|
||||||
|
|
||||||
|
卸载 `wot-ui` 过程如下:
|
||||||
|
|
||||||
|
- 1. 删除 `wot-ui` 库:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm un wot-design-uni
|
||||||
|
```
|
||||||
|
|
||||||
|
- 2. `pages.config.ts` 文件 `easycom.custom` 删除相关配置:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
easycom: {
|
||||||
|
autoscan: true,
|
||||||
|
custom: {
|
||||||
|
- '^wd-(.*)': 'wot-design-uni/components/wd-$1/wd-$1.vue',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
- 3. ` tsconfig.json` 文件 `compilerOptions.types` 删除相关配置:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
"types": [
|
||||||
|
"@dcloudio/types",
|
||||||
|
"@types/wechat-miniprogram",
|
||||||
|
- "wot-design-uni/global.d.ts",
|
||||||
|
"./components.d.ts",
|
||||||
|
"./global.d.ts"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 安装 `uni-ui` 库
|
||||||
|
|
||||||
|
- 1. 安装 `uni-ui` 库:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm add @dcloudio/uni-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
- 2. `pages.config.ts` 文件 `easycom.custom` 添加相关配置:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
easycom: {
|
||||||
|
autoscan: true,
|
||||||
|
custom: {
|
||||||
|
+ '^uni-(.*)': '@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
- 3. ` tsconfig.json` 文件 `compilerOptions.types` 添加相关配置:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
"types": [
|
||||||
|
"@dcloudio/types",
|
||||||
|
"@types/wechat-miniprogram",
|
||||||
|
+ "@uni-helper/uni-ui-types",
|
||||||
|
"./components.d.ts",
|
||||||
|
"./global.d.ts"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 安装 `uv-ui` 库
|
||||||
|
|
||||||
|
- 1. 安装 `uv-ui` 库:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm add @climblee/uv-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
- 2. `pages.config.ts` 文件 `easycom.custom` 添加相关配置:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
easycom: {
|
||||||
|
autoscan: true,
|
||||||
|
custom: {
|
||||||
|
+ '^uv-(.*)': '@climblee/uv-ui/components/uv-$1/uv-$1.vue',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
- 3. ` tsconfig.json` 文件 `compilerOptions.types` 添加相关配置:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
"types": [
|
||||||
|
"@dcloudio/types",
|
||||||
|
"@types/wechat-miniprogram",
|
||||||
|
+ "@ttou/uv-typings/shim",
|
||||||
|
+ "@ttou/uv-typings/v2",
|
||||||
|
"./components.d.ts",
|
||||||
|
"./global.d.ts"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
> 其他 UI 库的安装类似,不再赘述。
|
||||||
|
|
||||||
|
全文完~
|
163
docs/base/8-request.md
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
# 请求篇
|
||||||
|
|
||||||
|
本篇分为三块内容:
|
||||||
|
|
||||||
|
- 普通请求
|
||||||
|
- 图片上传
|
||||||
|
- 多后台地址
|
||||||
|
|
||||||
|
## 普通请求
|
||||||
|
|
||||||
|
普通请求分 2 种处理,一种是只在页面请求一次的一次性请求,这种请求占大多数;一种是项目多处用到的请求,这种请求占小部分,需要单独编写一个请求函数放到 `api文件夹` or `service文件夹`。
|
||||||
|
|
||||||
|
> `unibest` 里面是使用 `service文件夹` 后面不再说明。
|
||||||
|
|
||||||
|
下面来分别演示:
|
||||||
|
|
||||||
|
### 一次性请求
|
||||||
|
|
||||||
|
`template` 部分编码如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<button @click="run">请求</button>
|
||||||
|
<view v-if="loading" class="text-blue h-10">请求中...</view>
|
||||||
|
<view v-if="error" class="text-red h-10">请求错误</view>
|
||||||
|
<view v-else class="text-green h-10">{{ JSON.stringify(data) }}</view>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
`script` 部分使用 `菲鸽` 封装好的 `useRequest` 即可实现请求状态一体化,如下:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
<script setup>
|
||||||
|
type IFooItem = { name: string }
|
||||||
|
const { loading, error, data, run } = useRequest<IFooItem>(() => httpGet('/foo', { name: '菲鸽' }))
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
看吧,使用非常简单。
|
||||||
|
|
||||||
|
### 重复性请求
|
||||||
|
|
||||||
|
`重复性请求` 与 `一次性请求` 的 `html部分` 是一样的,唯一的区别是 `请求函数` 放到了 `service文件夹`,如下所示:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
<script setup>
|
||||||
|
import { getFooAPI, IFooItem } from '@/service/index/foo' // 看这里
|
||||||
|
const { loading, error, data, run } = useRequest<IFooItem>(() => getFooAPI('菲鸽'))
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
对应的 `src/service/index/foo.ts` 文件如下:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { http, httpGet } from '@/utils/http'
|
||||||
|
export interface IFooItem {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** GET 请求 */
|
||||||
|
export const getFooAPI = (name: string) => {
|
||||||
|
return http<IFooItem>({
|
||||||
|
url: `/foo`,
|
||||||
|
method: 'GET',
|
||||||
|
query: { name },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** GET 请求 - 再次简化,看大家是否喜欢这种简化 */
|
||||||
|
export const getFooAPI2 = (name: string) => {
|
||||||
|
return httpGet<IFooItem>('/foo', { name })
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
依然非常简洁,深受妹子喜爱。
|
||||||
|
|
||||||
|
## 图片上传
|
||||||
|
|
||||||
|
`template` 部分编码如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<view class="p-4 text-center">
|
||||||
|
<wd-button @click="run">选择图片并上传</wd-button>
|
||||||
|
<view v-if="loading" class="text-blue h-10">上传...</view>
|
||||||
|
<template v-else>
|
||||||
|
<view class="m-2">上传后返回的图片地址:</view>
|
||||||
|
<view class="m-2">{{ data }}</view>
|
||||||
|
<view class="h-80 w-full">
|
||||||
|
<image v-if="data" :src="data" mode="scaleToFill" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
`script` 部分使用 `菲鸽` 封装好的 `useUpload` 即可实现请求状态一体化,如下:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const { loading, data, run } = useUpload<string>({ user: '菲鸽' })
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
使用非常简单,深受汉子和妹子的喜爱。
|
||||||
|
|
||||||
|
## 多后台地址
|
||||||
|
|
||||||
|
上面的 `普通请求` 默认是只有一个请求地址的,在 `.env` 里面配置 `VITE_SERVER_BASEURL`,如下:
|
||||||
|
|
||||||
|
```text
|
||||||
|
VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
|
||||||
|
```
|
||||||
|
|
||||||
|
并且在 `src/interceptors/request.ts` 里面有设置:
|
||||||
|
|
||||||
|
- 如果是 `http` 开头的请求路径,则直接请求
|
||||||
|
- 如果不是,则拼接上 `VITE_SERVER_BASEURL`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
但在多后台地址时就不能这么玩了,需要处理如下:(关注上图的箭头部分)
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 可以写一个映射对象,如:
|
||||||
|
const proxyMap = {
|
||||||
|
cms:'http://localhost:8080/cms',
|
||||||
|
ums:'http://localhost:8080/ums',
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拦截器部分(上图箭头部分)修改如下
|
||||||
|
Object.keys(proxyMap).forEach(key=>{
|
||||||
|
if(options.url.startsWith(`/${key}`)){
|
||||||
|
options.url = proxyMap[key] + options.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接口调用的地方使用如下格式:
|
||||||
|
export const getFooAPI = (name: string) => {
|
||||||
|
return http<IFooItem>({
|
||||||
|
url: `/cms/foo`, // 看这里,前缀不用!!!
|
||||||
|
method: 'GET',
|
||||||
|
query: { name },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 环境变量配置
|
||||||
|
|
||||||
|
- `普通请求` 需要在 `.env` 里面配置 `VITE_SERVER_BASEURL`,用在 `src/interceptors/request.ts` 文件拼接请求地址;而 `多后台地址` 时则用不上,可以删除。
|
||||||
|
|
||||||
|
```text
|
||||||
|
VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
|
||||||
|
```
|
||||||
|
|
||||||
|
- `图片上传` 需要在 `.env` 里面配置 `VITE_UPLOAD_BASEURL`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
VITE_UPLOAD_BASEURL = 'https://ukw0y1.laf.run/upload'
|
||||||
|
```
|
||||||
|
|
||||||
|
全文完~
|
165
docs/base/9-state.md
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
# 状态篇
|
||||||
|
|
||||||
|
本文主要介绍了全局状态管理 `pinia` 和 简单状态 `ref` + `reactive`。
|
||||||
|
|
||||||
|
## pinia
|
||||||
|
|
||||||
|
`unibest` 已经内置了 `Pinia` + `pinia-plugin-persistedstate`(数据持久化插件),并提供了开箱即用的示例。
|
||||||
|
|
||||||
|
### 兼容性处理
|
||||||
|
|
||||||
|
本身 `pinia-plugin-persistedstate` 是不支持 `uniapp` 的,但是 `pinia-plugin-persistedstate` 提供了修改 `storage` 存储 API 的方式(默认是 `localStorage`,是一个 `WEB API`,`非H5端` 不支持),目前 `unibest` 已经处理好了。关键代码如下:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
import { createPersistedState } from 'pinia-plugin-persistedstate' // 数据持久化
|
||||||
|
|
||||||
|
const store = createPinia()
|
||||||
|
store.use(
|
||||||
|
createPersistedState({
|
||||||
|
storage: {
|
||||||
|
getItem: uni.getStorageSync, // 看这里
|
||||||
|
setItem: uni.setStorageSync, // 看这里
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 定义 `pinia` 全局状态
|
||||||
|
|
||||||
|
`src/store/xxx.ts` 里面编写代码,如下是 `src/store/count.ts` 文件。
|
||||||
|
|
||||||
|
注意 `defineStore` 第三个参数可以设置是否需要持久化,默认不需要。
|
||||||
|
|
||||||
|
```ts [src/store/count.ts]{26}
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export const useCountStore = defineStore(
|
||||||
|
'count',
|
||||||
|
() => {
|
||||||
|
const count = ref(0)
|
||||||
|
const increment = () => {
|
||||||
|
count.value++
|
||||||
|
}
|
||||||
|
const decrement = () => {
|
||||||
|
count.value--
|
||||||
|
}
|
||||||
|
const reset = () => {
|
||||||
|
count.value = 0
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
count,
|
||||||
|
decrement,
|
||||||
|
increment,
|
||||||
|
reset,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 如果需要持久化就写 true, 不需要持久化就写 false(或者去掉这个配置项)
|
||||||
|
persist: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
> 请不要随意把数据丢到 `pinia`,能不用就不用。简单状态尽量使用 `ref` 或者 `reactive`。
|
||||||
|
|
||||||
|
### 使用 `pinia` 全局状态
|
||||||
|
|
||||||
|
在 `vue` 文件中就可以使用了,如下是 `src/pages/demo.vue` 文件:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<view class="flex justify-center items-center text-blue-500 mt-4 mb-4">
|
||||||
|
<view class="w-20">Count: {{ countStore.count }}</view>
|
||||||
|
<button class="ml-2 mr-2" @click="countStore.decrement">-1</button>
|
||||||
|
<button class="ml-2 mr-2" @click="countStore.increment">+1</button>
|
||||||
|
<button class="ml-2 mr-2" @click="countStore.reset">重置</button>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useCountStore } from '@/store'
|
||||||
|
|
||||||
|
const countStore = useCountStore()
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 简单状态
|
||||||
|
|
||||||
|
你可以直接使用 `Vue` 提供的 `ref` 或 `reactive` 方法来做简单状态管理。
|
||||||
|
|
||||||
|
### ref
|
||||||
|
|
||||||
|
如下是 `src/pages/demo/useCount.ts` 文件,定义简单状态。
|
||||||
|
|
||||||
|
```ts [src/pages/demo/useCount.ts]
|
||||||
|
// 全局状态
|
||||||
|
const globalCount = ref(1)
|
||||||
|
export function useCount() {
|
||||||
|
// 本地状态
|
||||||
|
const localCount = ref(1)
|
||||||
|
function increment() {
|
||||||
|
globalCount.value++
|
||||||
|
localCount.value++
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
globalCount,
|
||||||
|
localCount,
|
||||||
|
increment,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
如下是 `src/pages/demo/index.vue`,与 `ref` 简单状态文件放到同一个目录下,方便管理。
|
||||||
|
|
||||||
|
```vue [src/pages/demo/index.vue]
|
||||||
|
<script setup lang="ts">
|
||||||
|
import useCount from './useCount.ts'
|
||||||
|
const { globalCount, localCount, increment } = useCount()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button @click="increment()">
|
||||||
|
{{ globalCount }}
|
||||||
|
{{ localCount }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## reactive
|
||||||
|
|
||||||
|
`reactive` 与 `ref` 类似。
|
||||||
|
|
||||||
|
如下是 `src/pages/demo/count.ts` 文件,定义状态。
|
||||||
|
|
||||||
|
```ts [src/pages/demo/count.ts]
|
||||||
|
export const countStore = reactive({
|
||||||
|
count: 0,
|
||||||
|
increment() {
|
||||||
|
this.count++
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
如下是 `src/pages/demo/index.vue`,与 `reactive` 简单状态文件放到同一个目录下,方便管理。
|
||||||
|
|
||||||
|
```vue [src/pages/demo/index.vue]
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { countStore } from './count.ts'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button @click="countStore.increment()">
|
||||||
|
{{ countStore.count }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
本文介绍了 `unibest` 里面状态管理的 `2` 种方式:`pinia` 全局状态 和 `ref\reactive` 简单状态,分别演示了如何定义状态和使用状态。
|
||||||
|
|
||||||
|
注意需要灵活使用 `pinia` 和 `简单状态`,局部的状态尽量使用 `简单状态` 的方式来处理,减少 `pinia` 里面全局变量的数量。
|
||||||
|
|
||||||
|
全文完~
|
BIN
docs/base/assets/1-1.png
Normal file
After Width: | Height: | Size: 291 KiB |
BIN
docs/base/assets/10-1.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
docs/base/assets/10-2.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
docs/base/assets/10-3.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
docs/base/assets/10-android.mp4
Normal file
BIN
docs/base/assets/10-ios.mp4
Normal file
BIN
docs/base/assets/11-1.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
docs/base/assets/11-10.png
Normal file
After Width: | Height: | Size: 485 KiB |
BIN
docs/base/assets/11-100.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
docs/base/assets/11-11.png
Normal file
After Width: | Height: | Size: 202 KiB |
BIN
docs/base/assets/11-12.png
Normal file
After Width: | Height: | Size: 484 KiB |
BIN
docs/base/assets/11-13.png
Normal file
After Width: | Height: | Size: 245 KiB |
BIN
docs/base/assets/11-2.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
docs/base/assets/11-3.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
docs/base/assets/11-4.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
docs/base/assets/11-5.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
docs/base/assets/11-6.png
Normal file
After Width: | Height: | Size: 236 KiB |
BIN
docs/base/assets/11-7.png
Normal file
After Width: | Height: | Size: 642 KiB |
BIN
docs/base/assets/11-8.png
Normal file
After Width: | Height: | Size: 888 KiB |
BIN
docs/base/assets/11-9.png
Normal file
After Width: | Height: | Size: 705 KiB |
BIN
docs/base/assets/13-1.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
docs/base/assets/13-2.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
docs/base/assets/13-3.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
docs/base/assets/13-4.png
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
docs/base/assets/13-5.png
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
docs/base/assets/13-6.png
Normal file
After Width: | Height: | Size: 220 KiB |
BIN
docs/base/assets/13-7.png
Normal file
After Width: | Height: | Size: 211 KiB |
BIN
docs/base/assets/13-8.png
Normal file
After Width: | Height: | Size: 286 KiB |
BIN
docs/base/assets/14-1.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/base/assets/14-2.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
docs/base/assets/14-3.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/base/assets/14-4.png
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
docs/base/assets/14-5.png
Normal file
After Width: | Height: | Size: 513 KiB |
BIN
docs/base/assets/14-6.png
Normal file
After Width: | Height: | Size: 549 KiB |
BIN
docs/base/assets/15-1.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
docs/base/assets/15-2.png
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
docs/base/assets/15-3.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
docs/base/assets/15-4.png
Normal file
After Width: | Height: | Size: 250 KiB |
BIN
docs/base/assets/15-5.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
docs/base/assets/15-6.png
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
docs/base/assets/2-1.png
Normal file
After Width: | Height: | Size: 246 KiB |
BIN
docs/base/assets/2-2.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
docs/base/assets/2-3.png
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
docs/base/assets/2-4.gif
Normal file
After Width: | Height: | Size: 648 KiB |
BIN
docs/base/assets/3-1.png
Normal file
After Width: | Height: | Size: 536 KiB |
BIN
docs/base/assets/4-1.png
Normal file
After Width: | Height: | Size: 232 KiB |
BIN
docs/base/assets/4-2.png
Normal file
After Width: | Height: | Size: 190 KiB |
BIN
docs/base/assets/4-3.png
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
docs/base/assets/4-4.png
Normal file
After Width: | Height: | Size: 317 KiB |
BIN
docs/base/assets/4-5.png
Normal file
After Width: | Height: | Size: 542 KiB |
BIN
docs/base/assets/5-1.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
docs/base/assets/5-10.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
docs/base/assets/5-100.png
Normal file
After Width: | Height: | Size: 34 KiB |