Framework7 完整教程:从入门到精通
目录
- 什么是 Framework7?
- 为什么选择 Framework7?
- 准备工作:环境搭建
- 核心概念速览
- 你的第一个 Framework7 应用
- 深入核心功能
- 1 路由与页面导航
- 2 组件
- 3 数据绑定与状态管理
- 4 样式与主题
- 实战:构建一个简单的 To-Do List 应用
- 进阶与资源
什么是 Framework7?
Framework7 (简称 F7) 是一个免费、开源的框架,用于构建原生感觉的移动端、桌面端和 Progressive Web Apps (PWA)。

它的核心设计哲学是:“为 Web 开发者提供构建原生应用所需的一切”,这意味着你可以使用熟悉的 HTML, CSS, 和 JavaScript 来开发应用,但它最终在设备上的外观、感觉和交互方式都非常接近原生应用。
为什么选择 Framework7?
在选择框架时,了解它的优缺点非常重要。
优点
- 原生体验感极强: F7 的交互细节,如滑动返回、侧边栏、无限滚动、列表项滑动操作等,都高度还原了原生应用的行为。
- 组件丰富: 提供了大量开箱即用的 UI 组件,如导航栏、标签栏、表单、弹窗、列表、卡片等,覆盖了绝大多数应用场景。
- 多端支持: 一套代码可以轻松编译成 iOS、Android、PWA 和 桌面端 应用,你可以使用 Capacitor 或 Cordova 进行打包。
- 灵活的渲染方式:
- DOM7: F7 自带了一个轻量级的、类似 jQuery 的 DOM 操作库
Dom7,非常高效。 - Virtual List: 专为高性能渲染长列表而设计,即使有数千条数据也能保持流畅滚动。
- React/Vue/Angular 支持: 如果你熟悉现代前端框架,F7 提供了官方的 React 和 Vue 绑定,让你可以结合两者的优势。
- DOM7: F7 自带了一个轻量级的、类似 jQuery 的 DOM 操作库
- 强大的模板引擎: 内置了 XTemplate,一个简单、快速且功能强大的模板引擎,用于动态渲染页面内容。
缺点
- 学习曲线: 相比一些简单的 UI 库,F7 的概念和配置项较多,需要投入一定时间学习。
- 主要面向移动端: 虽然支持桌面端,但其核心设计和组件都是为移动优先的,在桌面端的体验可能不如专门为桌面设计的框架(如 Ant Design)。
- 社区生态: 相较于 React、Vue 或 Angular 这样的大生态,F7 的社区和第三方组件库规模较小。
准备工作:环境搭建
我们使用最简单的方式来开始,即直接引入 Framework7 的 CSS 和 JS 文件,这种方式非常适合快速原型开发和学习。
-
创建项目文件夹
(图片来源网络,侵删)mkdir my-f7-app cd my-f7-app
-
创建
index.html文件 在my-f7-app文件夹中,创建一个index.html文件,并填入以下基本结构:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <title>My App</title> <!-- F7 CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/framework7@8.3.0/framework7-bundle.min.css"> <!-- PWA Icons --> <link rel="icon" href="img/f7-icon.png"> <link rel="apple-touch-icon" href="img/f7-icon.png"> </head> <body> <!-- App Root --> <div id="app"></div> <!-- F7 JS --> <script src="https://cdn.jsdelivr.net/npm/framework7@8.3.0/framework7-bundle.min.js"></script> <!-- Your App --> <script> // 这里我们将编写我们的应用逻辑 </script> </body> </html>viewportmeta 标签: 这是移动端开发的关键,它告诉浏览器如何控制页面的尺寸和缩放。framework7-bundle.min.css: 包含了所有 F7 组件的样式。framework7-bundle.min.js: 包含了 F7 的核心库和所有组件的 JavaScript。<div id="app"></div>: 这是 F7 应用的根容器,所有页面内容都将在这里渲染。
核心概念速览
在写代码前,了解几个核心概念会让你事半功倍。
- App / Framework7 Instance: 你的应用需要一个“主实例”,这是通过
new Framework7({...})创建的,它包含了应用的全局配置和方法。 - View / Router:
View是一个页面容器,Router负责管理View中的页面导航(前进、后退、切换等),一个应用可以有多个View。 - Page: 这是用户看到的一个完整屏幕,一个
Page通常包含page-content来放置主要内容。 - Component: F7 提供的可复用 UI 元素,如
navbar,toolbar,searchbar,list等。 - Template: 用于动态生成 HTML 片段的脚本,F7 使用 XTemplate。
你的第一个 Framework7 应用
让我们在 index.html 的 <script> 标签里,编写代码来创建一个简单的欢迎页面。
<script>
// 1. 创建 App 实例
const app = new Framework7({
// App 根元素
root: '#app',
// App 名称
name: 'My App',
// App ID
id: 'com.myapp.test',
// 启用 Cordova 插件
cordova: false,
// 启用推送通知
push: {
enabled: true,
},
// 自定义主题
theme: 'auto', // 自动选择 'ios' 或 'md' (Material Design)
});
// 2. 创建一个 View
const mainView = app.views.create('.view-main');
// 3. 定义一个页面内容,使用 XTemplate
const homePageContent = `
<div class="page" data-name="home">
<!-- 顶部导航栏 -->
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-title">首页</div>
</div>
<!-- 页面内容 -->
<div class="page-content">
<div class="block">
<p>欢迎使用 Framework7!</p>
<p>这是一个简单的示例页面。</p>
<p><a href="/about/" class="link">关于我们</a></p>
</div>
</div>
</div>
`;
// 4. 加载首页
// 使用 router.load() 方法将页面内容加载到 View 中
mainView.router.load({
content: homePageContent,
});
</script>
代码解释:
new Framework7({...}): 初始化 F7 应用,传入配置对象。app.views.create('.view-main'): 在 CSS 选择器.view-main的元素中创建一个 View 实例,我们稍后会把这个类名加到 HTML 中。`...`: 这是 ES6 的模板字符串,用于定义页面 HTML 结构,F7 的 XTemplate 语法也嵌入在这里。data-name="home": 给页面一个唯一的名称,方便路由识别。.navbar: F7 的导航栏组件。.page-content: 页面主要内容区域。mainView.router.load(...): 调用 View 的router对象的load方法,将我们定义的homePageContent加载到屏幕上。
修改 HTML 结构:
为了上面的代码生效,你需要修改 <body> 中的 <div id="app">:
<body>
<!-- App Root -->
<div id="app">
<!-- View 主容器 -->
<div class="view-main"></div>
</div>
<!-- F7 JS -->
<script src="https://cdn.jsdelivr.net/npm/framework7@8.3.0/framework7-bundle.min.js"></script>
<!-- Your App -->
<script>
// ... 上面的 JavaScript 代码 ...
</script>
</body>
在浏览器中打开 index.html,你应该能看到一个具有原生感觉的移动端页面了!
深入核心功能
1 路由与页面导航
F7 的路由系统非常强大,支持多种页面加载方式。
-
声明式导航 (推荐): 在 HTML 中使用
link标签,并添加data-view属性来指定目标 View。<!-- 在首页的 page-content 中 --> <p><a href="/about/" data-view="main" class="link">关于我们</a></p>
-
编程式导航: 在 JavaScript 中通过
router对象进行导航。// 跳转到新页面 mainView.router.navigate('/about/'); // 带参数的跳转 mainView.router.navigate('/user/123/'); // 返回上一页 mainView.router.back(); -
多页面路由:
data-name可以定义多级路径。data-name="about"->/about/data-name="user/profile"->/user/profile/
2 组件
F7 的组件是其魅力的核心,你只需要在 HTML 中添加特定的类名,F7 就会自动将其渲染成对应的组件。
示例:一个带列表的页面
<div class="page" data-name="contacts">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-title">联系人</div>
</div>
<div class="page-content">
<!-- 搜索栏 -->
<form class="searchbar">
<div class="searchbar-inner">
<div class="searchbar-input-wrap">
<input type="search" placeholder="搜索联系人...">
<i class="searchbar-icon"></i>
</div>
<span class="searchbar-clear"></span>
</div>
</form>
<!-- 联系人列表 -->
<div class="list contacts-list">
<ul>
<!-- 列表项 -->
<li class="item-content item-link">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">张三</div>
<div class="item-after">在线</div>
</div>
<div class="item-subtitle">zhangsan@example.com</div>
</div>
</li>
<li class="item-content item-link">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">李四</div>
<div class="item-after">离线</div>
</div>
<div class="item-subtitle">lisi@example.com</div>
</div>
</li>
</ul>
</div>
</div>
</div>
你只需要把这个页面的内容通过 router.load() 加载进来,一个功能完整的联系人列表页面就出现了。
3 数据绑定与状态管理
对于复杂应用,直接操作 DOM 是不现实的,F7 提供了两种主要方式来处理数据和视图的同步。
-
使用 XTemplate 和
app.methodsF7 的 XTemplate 支持简单的数据绑定和逻辑。
const data = { name: 'Framework7', version: 8.3, features: ['Fast', 'Native', 'Flexible'] }; const templateContent = ` <div class="page"> <div class="navbar"> <div class="navbar-bg"></div> <div class="navbar-title">数据绑定</div> </div> <div class="page-content"> <div class="block"> <p>你好, {{name}}!</p> <p>当前版本是: {{version}}</p> <p>特性:</p> <ul> {{#each features}} <li>{{this}}</li> {{/each}} </ul> <p>{{#if version > 8.0}}这是一个新版本!{{/if}}</p> </div> </div> </div> `; mainView.router.load({ content: app.methods.parseTemplate(templateContent, data) }); -
使用 Vue.js 或 React (推荐)
这是现代前端开发的主流方式,F7 的官方 Vue/React 绑定将 F7 的组件封装成 Vue 组件或 React 组件,让你可以使用声明式的方式构建应用,并结合 Vuex 或 Redux 进行状态管理。
Vue 示例:
<template> <f7-page> <f7-navbar title="Vue 绑定"></f7-navbar> <f7-block> <p>计数器: {{ counter }}</p> <f7-button @click="increment">增加</f7-button> </f7-block> </f7-page> </template> <script> export default { data() { return { counter: 0 } }, methods: { increment() { this.counter++; } } } </script>
4 样式与主题
F7 使用 CSS 变量来定义主题颜色,使得切换主题(如从 iOS 切换到 Material Design)变得非常容易。
- iOS 主题: 默认主题,使用圆角、蓝色高亮等。
- Material Design (MD) 主题: 通过设置
theme: 'md'来启用,使用扁平化设计和波纹效果。
你可以通过修改 CSS 变量来自定义颜色、字体等,而无需重写大量 CSS。
实战:构建一个简单的 To-Do List 应用
让我们整合所学知识,创建一个可以添加、删除和标记完成任务的 To-Do List 应用。
index.html 最终代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">F7 To-Do List</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/framework7@8.3.0/framework7-bundle.min.css">
</head>
<body>
<div id="app">
<div class="view-main"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/framework7@8.3.0/framework7-bundle.min.js"></script>
<script>
// 1. 初始化 App
const app = new Framework7({
root: '#app',
name: 'F7 To-Do',
id: 'com.f7.todo',
theme: 'auto',
});
const mainView = app.views.create('.view-main');
// 2. 数据
let todos = [
{ id: 1, text: '学习 Framework7', done: false },
{ id: 2, text: '构建一个 To-Do 应用', done: true },
];
// 3. 模板
const todoListPage = `
<div class="page" data-name="todo-list">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-title">任务列表</div>
<div class="navbar-right">
<a class="link icon-only panel-open" data-panel="right">
<i class="f7-icons">bars</i>
</a>
</div>
</div>
<div class="page-content">
<div class="list simple-list">
<ul>
{{#each todos}}
<li class="item-content">
<div class="item-inner">
<div class="item-title">
<label class="checkbox item-content">
<input type="checkbox" name="todo-checkbox" value="{{id}}" {{#if done}}checked{{/if}}>
<i class="icon-checkbox"></i>
<div class="item-title">{{text}}</div>
</label>
</div>
<div class="item-after">
<a class="link icon-only color-red" data-todo-id="{{id}}" data-action="delete">
<i class="f7-icons">trash_fill</i>
</a>
</div>
</div>
</li>
{{/each}}
</ul>
</div>
<div class="block">
<a href="/add-todo/" class="button button-fill">添加新任务</a>
</div>
</div>
</div>
`;
const addTodoPage = `
<div class="page" data-name="add-todo">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-title">添加任务</div>
<div class="navbar-right">
<a class="link" href="/todo-list/">完成</a>
</div>
</div>
<div class="page-content">
<div class="list no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">任务内容</div>
<div class="item-input-wrap">
<input type="text" id="new-todo-input" placeholder="输入任务...">
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
`;
// 4. 加载首页
mainView.router.load({
content: app.methods.parseTemplate(todoListPage, { todos: todos }),
});
// 5. 事件处理
// 使用事件委托来处理动态生成的元素
$$(document).on('change', 'input[name="todo-checkbox"]', function () {
const id = parseInt($$(this).val());
const todo = todos.find(t => t.id === id);
if (todo) {
todo.done = $$(this).prop('checked');
// 刷新列表
mainView.router.refreshPage();
}
});
$$(document).on('click', 'a[data-action="delete"]', function (e) {
e.preventDefault();
const id = parseInt($$(this).attr('data-todo-id'));
todos = todos.filter(t => t.id !== id);
mainView.router.refreshPage();
});
$$(document).on('click', 'a[href="/add-todo/"]', function () {
mainView.router.load({
content: addTodoPage,
});
});
// 添加任务
$$(document).on('click', '.navbar a:contains("完成")', function (e) {
if (mainView.router.currentRoute.url === '/add-todo/') {
e.preventDefault();
const inputText = $$('#new-todo-input').val().trim();
if (inputText) {
const newTodo = {
id: Date.now(), // 简单生成唯一ID
text: inputText,
done: false,
};
todos.push(newTodo);
mainView.router.navigate('/todo-list/');
}
}
});
</script>
</body>
</html>
这个例子展示了:
- 多页面路由: 在列表页和添加页之间切换。
- 数据绑定: 使用 XTemplate 渲染
todos数组。 - 事件委托: 为动态生成的复选框和删除按钮绑定事件。
- 状态管理: 通过修改
todos数组并刷新页面来更新应用状态。
进阶与资源
当你掌握了基础后,可以探索以下方向:
- PWA: 了解如何将 F7 应用配置成 PWA,添加到主屏幕、离线缓存等。
- 打包工具: 学习使用 Vite 或 Webpack 来构建和打包 F7 应用,这能让你使用模块化开发和更现代的 ES6+ 语法。
- 官方文档: https://framework7.io/zh-cn/docs/ - 这是最权威、最全面的资源。
- 示例与组件: https://framework7.io/zh-cn/components/ - 查看所有组件的用法和演示。
- 社区: 在 GitHub、论坛或 Discord 上寻求帮助。
Framework7 是一个功能强大且专注于提供原生体验的移动端开发框架,它通过丰富的组件和灵活的路由系统,极大地简化了移动应用的开发流程。
这份教程为你提供了从零开始学习 F7 的路径,最好的学习方式就是动手实践,尝试修改示例,构建你自己的小应用,祝你编码愉快!
