├── .eslintrc.json ├── .gitignore ├── README.md ├── babel.config.js ├── package.json ├── preview.gif ├── sign └── debug │ ├── certificate.pem │ └── private.pem └── src ├── app.vue ├── common ├── css │ └── common.css └── logo.png ├── components ├── app-header.vue ├── list-info.vue ├── page-list-item.vue ├── page-list.vue └── select-box.vue ├── index ├── index.vue └── service.js └── manifest.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "commonjs": true 4 | }, 5 | "extends": "eslint:recommended", 6 | "parser": "babel-eslint", 7 | "parserOptions": { 8 | "sourceType": "module", 9 | "ecmaFeatures": { 10 | "experimentalObjectRestSpread": true, 11 | "jsx": true 12 | } 13 | }, 14 | "globals": { 15 | "loadData": false, 16 | "saveData": false, 17 | "history": false, 18 | "console": false, 19 | "setTimeout": false, 20 | "clearTimeout": false, 21 | "setInterval": false, 22 | "clearInterval": false 23 | }, 24 | "plugins": [ 25 | "hybrid" 26 | ], 27 | "rules": { 28 | "indent": [ 29 | "warn", 30 | 2 31 | ], 32 | "no-console": [ 33 | "warn", 34 | { 35 | "allow": [ 36 | "info", 37 | "warn", 38 | "error" 39 | ] 40 | } 41 | ], 42 | "no-unused-vars": [ 43 | "warn", 44 | { 45 | "varsIgnorePattern": "prompt" 46 | } 47 | ], 48 | "quotes": [ 49 | "warn", 50 | "single", 51 | { 52 | "avoidEscape": true, 53 | "allowTemplateLiterals": true 54 | } 55 | ], 56 | "linebreak-style": [ 57 | "warn", 58 | "unix" 59 | ], 60 | "semi": [ 61 | "warn", 62 | "never" 63 | ] 64 | } 65 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | dist 4 | package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TodoMVC • Vue 2 | 3 | ### 简介 4 | 5 | 快应用是基于手机硬件平台的新型应用形态,具备传统APP完整的应用体验,无需安装、即点即用 6 | 7 | 该项目是一个快应用版本的TodoMVC应用示例,与[同组织下的todos项目](https://github.com/quickappcn/todos)的区别在于: 8 | 9 | 本项目使用了**Vue2开源框架(vue作为文件后缀名)**进行开发,后者使用的是快应用**原有标准语法(ux作为文件后缀名)**开发的; 10 | 11 | 项目中开发者开发方式与网页Vue项目开发一致,可以使用同样的Vue语法; 12 | 13 | ### 原理 14 | 15 | 快应用在运行时会将Vue框架注入,以Vue全局变量的形式暴露出来; 16 | 17 | 开发者在项目开发时,与网页Vue项目开发一致,可以使用Vue本身的各种DSL语法特性; 18 | 19 | DOM渲染层面与浏览器相似,且实现不同,所以请不要使用DOM本身的API能力(如:addEventListener),这块能力暂未开放规范; 20 | 21 | ### 注意事项 22 | 23 | - 使用Vue开发并查看效果,需要配合使用1050版本的预览版APK,以达到运行时支持; 24 | 25 | - 快应用1050版本开始邀请开发者参与内测; 26 | 27 | - 项目接下来可能会有较大的变动,运行时仅支持该项目最新版本,请及时更新; 28 | 29 | ### 效果预览 30 | 31 | ![效果预览](./preview.gif) 32 | 33 | ### 相关链接 34 | 35 | [快应用官网](https://www.quickapp.cn/) 36 | 37 | [快应用官网开发文档](https://doc.quickapp.cn/) -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(api) { 3 | api.cache(true); 4 | return { 5 | "presets":["@babel/preset-env"], 6 | "ignore": [/@babel[\/\\]runtime/], 7 | "plugins":["@babel/plugin-transform-runtime", "@babel/plugin-transform-modules-commonjs"], 8 | "babelrcRoots": [".", "node_modules"] 9 | }; 10 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hap-vue-todomvc", 3 | "version": "1.0.0", 4 | "subversion": { 5 | "toolkit": "0.3.0-beta.1" 6 | }, 7 | "description": "", 8 | "scripts": { 9 | "build": "hap build", 10 | "release": "hap release", 11 | "server": "hap server", 12 | "watch": "hap watch" 13 | }, 14 | "devDependencies": { 15 | "@babel/plugin-transform-runtime": "^7.3.4", 16 | "hap-toolkit": "^0.4.1", 17 | "quickapp-dsls": "^0.1.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quickappcn/todomvc-vue/65d185457cbd2c20eba4ed8c09c90a8e3bda84cf/preview.gif -------------------------------------------------------------------------------- /sign/debug/certificate.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDMTCCAhmgAwIBAgIJAMKpjyszxkDpMA0GCSqGSIb3DQEBCwUAMC4xCzAJBgNV 3 | BAYTAkNOMQwwCgYDVQQKDANSUEsxETAPBgNVBAMMCFJQS0RlYnVnMCAXDTE3MDQx 4 | OTAyMzE0OVoYDzIxMTYwMzI2MDIzMTQ5WjAuMQswCQYDVQQGEwJDTjEMMAoGA1UE 5 | CgwDUlBLMREwDwYDVQQDDAhSUEtEZWJ1ZzCCASIwDQYJKoZIhvcNAQEBBQADggEP 6 | ADCCAQoCggEBAK3kPd9jzvTctTIA3XNZVv9cHHDbAc6nTBfdZp9mtPOTkXFpvyCb 7 | kL0QjOog0+1pv8D7dFeP4ptWXU5CT3ImvaPR+16dAtMRcsxEr5q4zieJzx3O6huL 8 | UBa1k+xrzjXpRzkcOysmc8fTxt0tAwbDgJ2AA5TlXLTcVyb7GmJ+hl5CjnhoG5NN 9 | LrkqI7S29c1U3uokj8Q7hzaj0TURu/uB5ZIMCLZY9KFDugqaEcvmUyJiD0fuV6sA 10 | O/4kpiZUOnhV8/xWpRbMI4WFQsfgLOCV+X9uzUa29D677y//46t/EDSuQTHyBZbl 11 | AcNMENkpMWZsH7J/+F19+U0/Hd5bJgneVRkCAwEAAaNQME4wHQYDVR0OBBYEFKDN 12 | SZtt47ttOBDQzIchFYyxsg3mMB8GA1UdIwQYMBaAFKDNSZtt47ttOBDQzIchFYyx 13 | sg3mMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABaZctNrn4gLmNf/ 14 | eNJ3x5CJIPjPwm6j9nwKhtadJ6BF+TIzSkJuHSgxULjW436F37otv94NPzT5PCBF 15 | WxgXoqgLqnWwvsaqC4LUEjsZviWW4CB824YDUquEUVGFLE/U5KTZ7Kh1ceyUk4N8 16 | +mtkXkanWoBBk0OF24lNrAsNLB63yTLr9HxEe75+kmvxf1qVJUGtaOEWIhiFMiAB 17 | 5D4w/j2EFWktumjuy5TTwU0zhl52bc8V9SNixM1IaqzNrVPrdjv8viUX548pU3WT 18 | xZ5ylDsxhMC1q4BXQVeIY8C0cMEX+WHOmOCvWrkxCkP91pKsSPkuVrWlzrkn8Ojo 19 | swP6sBw= 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /sign/debug/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCt5D3fY8703LUy 3 | AN1zWVb/XBxw2wHOp0wX3WafZrTzk5Fxab8gm5C9EIzqINPtab/A+3RXj+KbVl1O 4 | Qk9yJr2j0ftenQLTEXLMRK+auM4nic8dzuobi1AWtZPsa8416Uc5HDsrJnPH08bd 5 | LQMGw4CdgAOU5Vy03Fcm+xpifoZeQo54aBuTTS65KiO0tvXNVN7qJI/EO4c2o9E1 6 | Ebv7geWSDAi2WPShQ7oKmhHL5lMiYg9H7lerADv+JKYmVDp4VfP8VqUWzCOFhULH 7 | 4Czglfl/bs1GtvQ+u+8v/+OrfxA0rkEx8gWW5QHDTBDZKTFmbB+yf/hdfflNPx3e 8 | WyYJ3lUZAgMBAAECggEBAJTnCBBdUB+fSs1prjeS/gsmnfgJoY+K9H7PCIxgj3yw 9 | FXAvZAmRDKzJGlF2EOOQlTG0YNiGDj6EAtv7rjoKcINyULSg8IU6wLmn61MrAuUa 10 | fa+Bujgh4E/B5swhOHAztNhzkzsM70Hi17wXSislh+HWd7qteOgqcbqgdOR4gaj+ 11 | HUqtcxG3H3hCL3dWugnjLZMtestLKGHSSZvbQNjYM3kKy2LvO8NpxmDE4a+TXygK 12 | qhaZjmS/dc/nJBJzOfkzby58RvGbzlJflfW/Uu3/gizj13GFQKWonq1xh630RAhv 13 | xX5ySok2aAx/+/SiJSpNXvM09grQuoORSr7D1tm+5rECgYEA3vf0hRfua0XAOu6f 14 | pyzNvLRRJ/pEew7XpNPCyS2TuMTd1yvXjGVxQfP46N6x1IM3SRU0zE+LSk80EF7l 15 | u1Or7GyCEhabYNe/7P2F8ENP73Do0HwvcI1jGrgr6r9oK0J27Xei+f6Q0bgJOPI2 16 | qaLj+V37cOjkNSM1mhTjtDwK8k0CgYEAx6cMrkjHl1+lDIIOc3qAEL3jb3xQveYk 17 | WrMF/B+j048k6boU4VvFJAIyQxOxMNxLjw3/9+zXCFJT4WaZK3TMXlg614ASGx3H 18 | tKjJM9O07ywwMq1gbutFS4nHCg3L3Os6esL0SPwMdATR3Yh22n5OGI9o+/aURulL 19 | GPEXef1Z2/0CgYEAgmwp5LxV4vu+8Pnp+4DSq4ISQr861XyeGTUhKEp3sUm+tgFY 20 | KTChakHKpHS3Mqa6bQ5xft08je/8dWL9IHFWDIqAHxKIOsKY6oh1k0/cbyPtmx45 21 | Ja4efV+jmMHzrfJH3KnxdCg7D+GFy4CrBtlYXuJhlO81pft9fC6h7yh8ArUCgYBq 22 | gvkl5Zftbs4rnRq+iqTVyagTKvwcQzIz3PwdZHfO/rfPpUFMdNv4eN99n3zRN0Vs 23 | HSjoiEazntA3GLgwUdBRqLpDi4SdSMbo337vkksdqbJQ5uPiaMuAIBG6kF+pDSkW 24 | ovkWErlGD+gySoI10FozihaVDRhPuFgjB0PiBcIxtQKBgGNSzX+Bx5+ux1Qny0Sn 25 | SUcBtepLnO8M8wafoGNyehbMnLzfuMbaDiJOdozGlBNHZTtPB3r4AYb8WnltdKW0 26 | 7i3fk26YZGiMVeUJvewA6/LOBEaqMdwoNwnoptvbR6ehHeE/PPtRtge2cD3bPIM7 27 | U9VlWgfgj9Dxfwhslqb9hmyp 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /src/app.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/common/css/common.css: -------------------------------------------------------------------------------- 1 | .common-h1 { 2 | line-height: 200px; 3 | font-size: 100px; 4 | text-align: center; 5 | } 6 | 7 | .common-h2 { 8 | line-height: 100px; 9 | font-size: 40px; 10 | text-align: center; 11 | } -------------------------------------------------------------------------------- /src/common/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quickappcn/todomvc-vue/65d185457cbd2c20eba4ed8c09c90a8e3bda84cf/src/common/logo.png -------------------------------------------------------------------------------- /src/components/app-header.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 76 | 77 | 116 | -------------------------------------------------------------------------------- /src/components/list-info.vue: -------------------------------------------------------------------------------- 1 | 14 | 29 | 43 | -------------------------------------------------------------------------------- /src/components/page-list-item.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 69 | 70 | 131 | -------------------------------------------------------------------------------- /src/components/page-list.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 31 | 32 | 37 | -------------------------------------------------------------------------------- /src/components/select-box.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 27 | 28 | 38 | -------------------------------------------------------------------------------- /src/index/index.vue: -------------------------------------------------------------------------------- 1 | 26 | 35 | 36 | 156 | 157 | -------------------------------------------------------------------------------- /src/index/service.js: -------------------------------------------------------------------------------- 1 | import storage from '@system.storage' 2 | 3 | const STORAGE_KEY = 'todos-vuejs-2.0' 4 | const todoList = [{ 5 | id: 0, 6 | title: 'react', 7 | completed: false 8 | }, 9 | { 10 | id: 1, 11 | title: 'vue', 12 | completed: false 13 | }] 14 | 15 | export const storageService = { 16 | fetch() { 17 | return new Promise((resolve, reject) => { 18 | storage.get({ 19 | key: STORAGE_KEY, 20 | success(data) { 21 | const todos = data && JSON.parse(data) || todoList 22 | todos.forEach((todo, index) => { 23 | todo.id = index 24 | }) 25 | storageService.uid = todos.length 26 | resolve(todos) 27 | }, 28 | fail() { 29 | console.info('read fail') 30 | }, 31 | complete() { 32 | console.info('read complete') 33 | } 34 | }) 35 | }) 36 | }, 37 | save(todos) { 38 | return new Promise((resolve, reject) => { 39 | storage.set({ 40 | key: STORAGE_KEY, 41 | value: JSON.stringify(todos), 42 | success() { 43 | resolve() 44 | console.log('save success') 45 | }, 46 | fail() { 47 | reject() 48 | console.log('save fail') 49 | } 50 | }) 51 | }) 52 | } 53 | } 54 | 55 | export const filters = { 56 | all(todos) { 57 | return todos 58 | }, 59 | active(todos) { 60 | return todos.filter(todo => { 61 | return !todo.completed 62 | }) 63 | }, 64 | completed(todos) { 65 | return todos.filter(todo => { 66 | return todo.completed 67 | }) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": "com.application.demo", 3 | "name": "todomvc", 4 | "versionName": "1.0.0", 5 | "versionCode": "1", 6 | "minPlatformVersion": "101", 7 | "icon": "/common/logo.png", 8 | "features": [ 9 | { "name": "system.prompt" }, 10 | { "name": "system.router" }, 11 | { "name": "system.shortcut" }, 12 | { "name": "system.storage" } 13 | ], 14 | "permissions": [ 15 | { "origin": "*" } 16 | ], 17 | "config": { 18 | "logLevel": "log", 19 | "dsl": { 20 | "name": "vue" 21 | } 22 | }, 23 | "router": { 24 | "entry": "index", 25 | "pages": { 26 | "index": { 27 | "component": "index" 28 | } 29 | } 30 | }, 31 | "display": { 32 | "titleBarBackgroundColor": "#f2f2f2", 33 | "titleBarTextColor": "#414141", 34 | "menu": true 35 | } 36 | } --------------------------------------------------------------------------------