From 00c22d3d3a4d08cfc80a2f9beda1735920480f13 Mon Sep 17 00:00:00 2001 From: dntzhang Date: Wed, 14 Aug 2019 09:27:47 +0800 Subject: [PATCH] docs: update tutorial --- tutorial/kbone.md | 256 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 254 insertions(+), 2 deletions(-) diff --git a/tutorial/kbone.md b/tutorial/kbone.md index e7e3dc6de..96f49f961 100644 --- a/tutorial/kbone.md +++ b/tutorial/kbone.md @@ -11,6 +11,10 @@ kbone 是小程序官方出的多端统一框架,市面上就很多跨端开 阅读本文你可以收获: * Kbone 基础原理 +* 使用 preact + kbone 开发小程序 Counter +* 使用 vue + kbone 开发小程序 Counter +* 使用 omis + kbone 开发小程序 TodoApp +* 使用 omis + kbone 开发小程序游戏贪吃蛇 * 领域驱动设计在前端的集成 * 理解 MVC、MVP、MVVM 模式 * 使用 DOM 编写小程序游戏(并非小游戏) @@ -68,20 +72,268 @@ pageId 和 nodeId 两个参数缺一不可,组件内部会根据传入的 page ![](../assets/kbone.png) -其中 v-dom 相当于数据, mp-element 相当于模板,数据+模板完成渲染。其中前面三个步骤都是运行在小程序逻辑层(JSCore)当中,使用逻辑层自己模拟出来的 DOM/BOM API,也就是官方的 miniprogram-render。 +其中 v-dom 相当于数据(这里可能有点绕,dom 作为 dom 渲染的数据,但事实就是如此), mp-element 相当于模板,数据+模板完成渲染。其中前面三个步骤都是运行在小程序逻辑层(JSCore)当中,使用逻辑层自己模拟出来的 DOM/BOM API,也就是官方的 miniprogram-render。 ![](../assets/mp.png) ## 实战 TodoApp + + + +### 快速开始 + +```js +npm i omi-cli -g +omi init-kbone my-app +cd my-app +npm start //开发小程序 +npm run web //开发 web +npm run build //发布 web +``` + +> 也支持一条命令 `npx omi-cli init-kbone my-app` (npm v5.2.0+) + + +## 目录说明 + +``` +├─ build +│ ├─ mp //微信开发者工具指向的目录,用于生产环境 +│ ├─ web //web 编译出的文件,用于生产环境 +├─ config +├─ public +├─ scripts +├─ src +│ ├─ assets +│ ├─ components //存放所有组件 +│ ├─ log.js //入口文件,会 build 成 log.html +│ └─ index.js //入口文件,会 build 成 index.html +``` + +定义结构: + +```jsx +const Todo = (props, { clear, filter, textInput, inputText, todo, left, type, newTodo, done, toggle, deleteItem }) => { + return ( +
+
todos
+
+ + +
+ +
+ {todo.map(item => ( + (type === 'all' || (type === 'active' && !item.done) || (type === 'done' && item.done)) &&
+
+ {item.text} +
+
+ ))} +
+ + +
+ ) +} +``` + +定义 store: + +```jsx + +Todo.store = _ => { + return { + + todo: [{ text: '学习 Kbone', id: 0 }, { text: '学习 Omi', id: 1 }], + id: 1, + inputText: '', + left: 2, + type: 'all', + done: 0, + + + textInput(evt) { + this.inputText = evt.target.value + }, + + gotoAbout() { + wx.navigateTo({ + url: '../about/index' + }) + }, + + toggle(evt) { + for (let i = 0, len = this.todo.length; i < len; i++) { + const item = this.todo[i] + if (item.id === Number(evt.target.dataset.id)) { + item.done = !item.done + this.computeCount() + _.update() + break + } + } + }, + + computeCount() { + this.left = 0 + this.done = 0 + for (let i = 0, len = this.todo.length; i < len; i++) { + this.todo[i].done ? this.done++ : this.left++ + } + }, + + deleteItem(evt) { + for (let i = 0, len = this.todo.length; i < len; i++) { + const item = this.todo[i] + if (item.id === Number(evt.target.dataset.id)) { + this.todo.splice(i, 1) + this.computeCount() + _.update() + break + } + } + }, + + newTodo() { + if (this.inputText.trim() === '') { + wx.showToast({ + title: '内容不能为空', + icon: 'none', + duration: 2000 + }) + + return + } + + this.todo.unshift({ + text: this.inputText, + id: ++this.id, + done: false, + createTime: new Date() + }) + this.computeCount() + this.inputText = '' + _.update() + + }, + + filter(type) { + //因为是自定义事件 + //注意这里的 this 指向,不能直接 this.type = type + _.store.type = type + _.update() + }, + + clear(evt) { + //因为是自定义事件 + //注意这里的 this 指向 + const self = _.store + wx.showModal({ + title: '提示', + content: '确定清空已完成任务?', + success: (res) => { + if (res.confirm) { + for (let i = 0, len = self.todo.length; i < len; i++) { + const item = self.todo[i] + if (item.done) { + self.todo.splice(i, 1) + len-- + i-- + } + } + self.done = 0 + _.update() + + } else if (res.cancel) { + console.log('用户点击取消') + } + } + }) + + }, + + gotoAbout() { + wx.navigateTo({ + url: '../about/index' + }) + }, + + clickHandle() { + if ("undefined" != typeof wx && wx.getSystemInfoSync) { + wx.navigateTo({ + url: '../log/index?id=1' + }) + } else { + location.href = 'log.html' + } + } + } +} + +``` + + +抽取中 todo-footer 组件: + +```jsx +import { h } from 'omis' +import './index.css' + +const TodoFooter = ({ left, type, done }, { showAll, showActive, showDone, clearDone }) => { + return +} + +TodoFooter.store = ({props})=> { + return { + showAll() { + props.onFilter('all') + }, + + showActive() { + props.onFilter('active') + }, + + showDone() { + props.onFilter('done') + }, + + clearDone() { + props.onClear() + } + } +} + +export default TodoFooter +``` + [→ TodoApp 源码](https://github.com/Tencent/omi/tree/master/packages/omi-kbone) ## 实战贪吃蛇 - [→ 贪吃蛇源码](https://github.com/Tencent/omi/tree/master/packages/omi-kbone) +## 实战 preact Counter + +## 实战 vue Counter + + ## 谁在使用 kbone?