Nhảy tới nội dung

Tạo giao diện sử dụng Tabs layout

Ngoài cách tạo nhanh Tabs layout như đã hướng dẫn tại đây, kể từ version framework 1.7.0, có thể tạo Tabs layout như sau hạn chế reload khi chuyển tab, mang lại trải nghiệm người dùng tốt hơn

TabView Layout

Khởi tạo nhanh project sử dụng Tab layout với TabView với zmp-cli (version 3.8.0)

Khởi tạo project với

zmp init

Tại bước chọn template, chọn Tabs Layout

Init Project

Tạo Tabs layout với TabView

Ví dụ ta có các pages như sau, với index - tab home, article - tab article, search - tab search, menu - tab menu, blogs là trang hiển thị danh sách các blogs khi nhấn vào "xem thêm"

Zalo Mini App
└─── src
└── pages
├── index.jsx
└── article.jsx
└── search.jsx
└── menu.jsx
└── blogs.jsx

Để sử dụng cần import TabView từ zmp-framework/react (framework từ version 1.7.0)

import { TabView, View, zmp } from "zmp-framework/react";

Khai báo Tabs View

Khai báo các tab tương ứng với <View tab được wrap bởi <TabView>

<App {...zmpparams}>
<TabView name="main-app" className="safe-areas">
<View id="view-main" main tabActive tab url="/"></View>
<View id="view-article" name="article" tab url="/article/"></View>
<View id="view-search" name="search" tab url="/search/"></View>
<View id="view-menu" name="menu" tab url="/menu/"></View>
</TabView>
</App>

Prop tabActive để chỉ định định Tab nào sẽ active trong lần đầu khởi động app

Mặc định khi khởi tạo, các View tương ứng với tab sẽ tải, set initRouterOnTabShow={true} vào View tương tứng để chỉ init Page khi tab được kích hoạt

<View id="view-main" main initRouterOnTabShow tabActive tab url="/"></View>
Tips

Trong trường hợp muốn lưu trạng thái Tab đang active có thể sử dụng onTabChange để lưu tab đang active

const [activeTab, setActiveTab] = useState(null);
//...
<View
id="view-article"
initRouterOnTabShow
name="article"
tab
url="/article/"
onTabShow={() => {
setActiveTab("article");
}}
></View>;

Tạo Bottom Navigation Bar

Tạo Navigation Bar

Tạo Bottom Navigation Bar để chuyển giữa các tabs

const NavigationBar = () => (
<Tabbar id="main-nav" bottom>
<Link tabLink="#view-main" tabLinkActive>
Home
</Link>
<Link tabLink="#view-article">Article</Link>
<Link tabLink="#view-search">Search</Link>
<Link tabLink="#view-menu">Menu</Link>
</Tabbar>
);

Thêm prop tabLinkActive để chỉ định tab link nào đang active đồng nhất với Tab View đang active, trong lần đầu khởi tạo View

Thêm NavigationBar vừa tạo vào TabView

<App {...zmpparams}>
<TabView tabs name="main-app" className="safe-areas">
<NavigationBar />
<View id="view-main" main tabActive tab url="/" initRouterOnTabShow></View>
<View
id="view-article"
name="article"
tab
url="/article/"
initRouterOnTabShow
></View>
<View
id="view-search"
name="search"
tab
url="/search/"
initRouterOnTabShow
></View>
<View
id="view-menu"
name="menu"
tab
url="/menu/"
initRouterOnTabShow
></View>
</TabView>
</App>

Chuyển Tab - chuyển trang

Để mở 1 trang tại 1 View cụ thể

  • Chuyển trang tại View hiện tại
zmp.views.current?.router.navigate("/path-to-page");
  • Mở trang tại một View cụ thể

Mở trang tại View cụ thể

// Mở Tab cụ thể
zmp.tab.show("#tab-id");
// Mở page tại views cần mở
zmp.views["view-name"].router.navigate("/path-to-page");

Ví dụ: Khi Tab - View menu đang active cần mở trang blogs tại View main

const openBlogsPage = () => {
zmp.tab.show("#view-main");
zmp.views.main.router.navigate("/blogs/");
};

Hoặc muốn mở trang blogs ngay tại View menu

const openBlogsPage = () => {
zmp.views.menu.router.navigate("/blogs/");
};

Ẩn Bottom Navigation Bar

Ẩn bottom navigation bar khi vào 1 trang cụ thể

Ẩn Bottom Navigation Bar

Ví dụ khi mở trang Blogs cần ẩn Bottom Navigation Bar có id="main-nav"

// pages/blogs.jsx

<Page
onPageBeforeIn={() => {
zmp.toolbar.hide("#main-nav");
}}
></Page>

Cài đặt Pull to refresh làm mới dữ liệu

Thay vì gọi làm mới dữ liệu mỗi khi truy cập trang, chúng ta có thể lưu dữ liệu vào store, chỉ fetch dữ liệu khi cần thiết như lần đầu tiên truy cập, khi user có chủ đích làm mới,...

Một trong số các cách phổ biến để user làm mới lại trang thường thấy trên một mobile app là Pull to refresh, để cài đặt tính năng này tham khảo tại đây

pull to refresh

Ví dụ tại Home Page, khi user kéo đầu trang, dispatch action "getLatestBlogs" để tải lại data

// pages/index.jsx
const Home = () => {
const refreshPage = (done) => {
store.dispatch("getLatestBlogs").finally(() => {
// run callback done sau khi tải lại data
done();
});
};

return (
<Page ptr onPtrRefresh={refreshPage}>
{/* render page-content data*/}
</Page>
);
};

Preview

Trên đây là tóm tắt một số cách cải thiện trải nghiệm với ứng dụng sử dụng Tabs Layout, sau khi tuỳ chỉnh lại UI từ hướng dẫn phía trên ta được một mini app như sau, bạn có thể clone repository này để chạy thử trên máy của mình: Demo Source Code

preview

Sử dụng Zalo quét mã QR trên để xem