创建react 项目
npm create vite@latest my-project-name -- --template react
cd my-project
# 安装依赖
npm install
# 运行项目
npm run dev
安装flowbite react
安装tailwindfcss
npm install -D tailwindcss postcss autoprefixer
# 添加tailwindcss 配置文件 tailwind.config.js
npx tailwindcss init -p
对tailwind.config.js 文件配置
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{js,jsx,ts,tsx}',
],
theme: {
extend: {},
},
plugins: [],
}
在react 全局css 文件中 添加tailwindcss 配置 ./src/index.css
// ./src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
安装 flowbite
npm install flowbite flowbite-react
在tailwindcss 配置中添加 flowbite ui 组件 tailwind.config.js
配置插件 已经 添加组件
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{js,jsx,ts,tsx}',
'node_modules/flowbite-react/lib/esm/**/*.js'
],
theme: {
extend: {},
},
plugins: [
require('flowbite/plugin')
]
}
react-i18next
安装
npm install react-i18next i18next --save
创建language文件夹
创建 i18next配置文件 i18n.js
// 不抽离
// i18n.js
// 不抽离 多语言
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import translation_en from './en.json';
import translation_zh from './zh.json';
const resources = {
en: {
translation: translation_en,
},
zh: {
translation: translation_zh,
},
};
i18n.use(initReactI18next).init({
resources,
// 默认语言 zh/en 中文/英文
lng: 'zh',
fallbackLng: "zh",
// 失败加载语言
interpolation: {
escapeValue: false,
},
});
export default i18n;
// 抽离
zh.json
{
"translation": {
"Welcome to React": "欢迎使用 react-i18next",
"about": "关于",
"home":"首页",
"services": "服务",
"pricing": "价格",
"contact": "联系",
"wallet": "钱包",
"settings":"设置",
"profile":"我的"
}
}
en.json
{
"translation": {
"Welcome to React": "Welcome to React and react-i18next",
"about": "about",
"home":"Home",
"services": "Services",
"pricing": "Pricing",
"contact": "Contact",
"wallet": "Wallet",
"settings":"Settings",
"profile":"Profile"
}
}
// i18n.js
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import en from './en.json'
import zh from './zh.json'
const resources = {
zh,
en
};
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources,
fallbackLng: "zh",
lng: "zh",
interpolation: {
escapeValue: false, // react already safes from xss
},
});
export default i18n;
在main.jsx文件中加入
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import './language/i18n.js' // 引入i18next
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
使用i18next 以及 黑夜模式
import { useTranslation } from "react-i18next";
import {
DarkThemeToggle,
Flowbite
} from "flowbite-react";
function App(){
// i18next 配置
const { t, i18n } = useTranslation();
const changeLanguage = () => {
i18n.changeLanguage(i18n.language === "en" ? "zh" : "en");
};
return (
{/* 用于 黑夜模式切换 使用 <Flowbite>组件包裹需要黑夜模式的组件*/}
<Flowbite>
{/* 其他组件*/}
{/* 黑夜模式换按钮*/}
<DarkThemeToggle />
{/* 其他组件*/}
{/* 语言切换按钮*/}
<Button
color="gray"
className="ml-5 text-gray-800 dark:text-white"
onClick={changeLanguage}
>
{i18n.language}
</Button>
<h2 className="text-center text-lg text-gray-800 dark:text-white">
{t("Welcome to React")}
{/* 多语言替换的占位写法 */}
</h2>
</Flowbite>
)
}
多语言逻辑就是上面两个文件中的对应词组替换
flowbite组件使用
使用flowbite react 官网组件
{/* 顶部导航栏 */}
<Navbar fluid>
<Navbar.Brand href="https://flowbite-react.com">
<img
src="https://flowbite.com/docs/images/logo.svg"
className="mr-3 h-6 sm:h-9"
alt="Flowbite React Logo"
/>
<span className="self-center whitespace-nowrap text-xl font-semibold text-gray-800 dark:text-white">
Flowbite React
</span>
</Navbar.Brand>
<div className="flex md:order-2">
<DarkThemeToggle />
<Button
color="gray"
className="ml-5 text-gray-800 dark:text-white"
onClick={changeLanguage}
>
{i18n.language}
</Button>
<Navbar.Toggle />
</div>
<Navbar.Collapse>
<Navbar.Link href="#" active>
{t("home")}
</Navbar.Link>
<Navbar.Link href="#">{t("about")}</Navbar.Link>
<Navbar.Link href="#">{t("services")}</Navbar.Link>
<Navbar.Link href="#">{t("pricing")}</Navbar.Link>
<Navbar.Link href="#">{t("contact")}</Navbar.Link>
</Navbar.Collapse>
</Navbar>
{/* 底部tabbar */}
<div className="xl:hidden lg:hidden md:hidden sm:block">
<div className="fixed bottom-0 left-0 z-50 w-full h-16 bg-white border-t border-gray-200 dark:bg-gray-700 dark:border-gray-600">
<div className="grid h-full max-w-lg grid-cols-4 mx-auto font-medium">
<button
type="button"
className="inline-flex flex-col items-center justify-center px-5 hover:bg-gray-50 dark:hover:bg-gray-800 group"
>
<svg
className="w-5 h-5 mb-2 text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="m19.707 9.293-2-2-7-7a1 1 0 0 0-1.414 0l-7 7-2 2a1 1 0 0 0 1.414 1.414L2 10.414V18a2 2 0 0 0 2 2h3a1 1 0 0 0 1-1v-4a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v4a1 1 0 0 0 1 1h3a2 2 0 0 0 2-2v-7.586l.293.293a1 1 0 0 0 1.414-1.414Z" />
</svg>
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500">
{t("home")}
</span>
</button>
<button
type="button"
className="inline-flex flex-col items-center justify-center px-5 hover:bg-gray-50 dark:hover:bg-gray-800 group"
>
<svg
className="w-5 h-5 mb-2 text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M11.074 4 8.442.408A.95.95 0 0 0 7.014.254L2.926 4h8.148ZM9 13v-1a4 4 0 0 1 4-4h6V6a1 1 0 0 0-1-1H1a1 1 0 0 0-1 1v13a1 1 0 0 0 1 1h17a1 1 0 0 0 1-1v-2h-6a4 4 0 0 1-4-4Z" />
<path d="M19 10h-6a2 2 0 0 0-2 2v1a2 2 0 0 0 2 2h6a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1Zm-4.5 3.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2ZM12.62 4h2.78L12.539.41a1.086 1.086 0 1 0-1.7 1.352L12.62 4Z" />
</svg>
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500">
{t("wallet")}
</span>
</button>
<button
type="button"
className="inline-flex flex-col items-center justify-center px-5 hover:bg-gray-50 dark:hover:bg-gray-800 group"
>
<svg
className="w-5 h-5 mb-2 text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 20 20"
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M4 12.25V1m0 11.25a2.25 2.25 0 0 0 0 4.5m0-4.5a2.25 2.25 0 0 1 0 4.5M4 19v-2.25m6-13.5V1m0 2.25a2.25 2.25 0 0 0 0 4.5m0-4.5a2.25 2.25 0 0 1 0 4.5M10 19V7.75m6 4.5V1m0 11.25a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5ZM16 19v-2"
/>
</svg>
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500">
{t("settings")}
</span>
</button>
<button
type="button"
className="inline-flex flex-col items-center justify-center px-5 hover:bg-gray-50 dark:hover:bg-gray-800 group"
>
<svg
className="w-5 h-5 mb-2 text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M10 0a10 10 0 1 0 10 10A10.011 10.011 0 0 0 10 0Zm0 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6Zm0 13a8.949 8.949 0 0 1-4.951-1.488A3.987 3.987 0 0 1 9 13h2a3.987 3.987 0 0 1 3.951 3.512A8.949 8.949 0 0 1 10 18Z" />
</svg>
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500">
{t("profile")}
</span>
</button>
</div>
</div>
</div>
{/* 中间内容区域 轮播图 */}
<div className="wrap dark:bg-gray-700 flex justify-center">
<div className="container flex-col ">
<div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
<Carousel>
<img
src="https://flowbite.com/docs/images/carousel/carousel-1.svg"
alt="..."
/>
<img
src="https://flowbite.com/docs/images/carousel/carousel-2.svg"
alt="..."
/>
<img
src="https://flowbite.com/docs/images/carousel/carousel-3.svg"
alt="..."
/>
<img
src="https://flowbite.com/docs/images/carousel/carousel-4.svg"
alt="..."
/>
<img
src="https://flowbite.com/docs/images/carousel/carousel-5.svg"
alt="..."
/>
</Carousel>
</div>
<h2 className="text-center text-lg text-gray-800 dark:text-white">
{t("Welcome to React")}
</h2>
</div>
</div>