├── .babelrc ├── .coveralls.yml ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── build └── build.js ├── dist ├── vuet.js ├── vuet.js.map ├── vuet.min.js └── vuet.min.js.map ├── examples ├── base │ ├── index.html │ └── main.js ├── index.html ├── need │ ├── App.vue │ ├── OutputContent.vue │ ├── index.html │ ├── main.js │ └── vuet.js ├── once │ ├── App.vue │ ├── OutputContent.vue │ ├── index.html │ ├── main.js │ └── vuet.js ├── route │ ├── Detail.vue │ ├── List.vue │ ├── index.html │ ├── main.js │ └── vuet.js ├── scroll-cnode │ ├── index.html │ ├── main.js │ ├── pages │ │ └── topic │ │ │ ├── Detail.vue │ │ │ └── List.vue │ ├── router │ │ ├── index.js │ │ └── router.js │ └── vuet │ │ ├── index.js │ │ ├── topic-detail.js │ │ ├── topic-list.js │ │ └── vuet.js ├── scroll-route │ ├── Detail.vue │ ├── List.vue │ ├── index.html │ ├── main.js │ └── vuet.js ├── scroll-self │ ├── App.vue │ ├── index.html │ ├── main.js │ └── vuet.js ├── scroll-sync │ ├── App.vue │ ├── index.html │ ├── main.js │ └── vuet.js ├── server.js ├── store │ ├── index.html │ └── main.js ├── temp │ ├── App.vue │ ├── OutputContent.vue │ ├── index.html │ ├── main.js │ └── vuet.js ├── v-model │ ├── App.vue │ ├── InputContent.vue │ ├── OutputContent.vue │ ├── index.html │ ├── main.js │ └── vuet.js └── webpack.config.js ├── images └── vuet.png ├── package-lock.json ├── package.json ├── packages ├── vuet-route │ ├── README.md │ ├── dist │ │ ├── vuet-route.js │ │ ├── vuet-route.js.map │ │ ├── vuet-route.min.js │ │ └── vuet-route.min.js.map │ ├── package.json │ └── src │ │ └── index.js ├── vuet-scroll │ ├── README.md │ ├── dist │ │ ├── vuet-scroll.js │ │ ├── vuet-scroll.js.map │ │ ├── vuet-scroll.min.js │ │ └── vuet-scroll.min.js.map │ ├── package.json │ └── src │ │ └── index.js └── vuet-store │ ├── README.md │ ├── dist │ ├── vuet-store.js │ ├── vuet-store.js.map │ ├── vuet-store.min.js │ └── vuet-store.min.js.map │ ├── package.json │ └── src │ └── index.js ├── src ├── debug.js ├── index.js ├── rules │ ├── index.js │ ├── need.js │ ├── once.js │ ├── reset.js │ └── temp.js ├── util.js ├── vuet-static.js └── vuet.js └── test ├── e2e ├── base.test.js ├── need.test.js ├── once.test.js ├── scroll-cnode.test.js ├── scroll-route.test.js ├── scroll-self.test.js ├── scroll-sync.test.js ├── store.test.js ├── temp.test.js └── v-model.js └── unit ├── debug.test.js ├── util.test.js ├── vue-route.test.js ├── vuet-store.test.js └── vuet.test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-0" 5 | ], 6 | "plugins": [ 7 | "transform-object-assign" 8 | ] 9 | } -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-pro 2 | repo_token: 0VoNrE29kZiIsy1hNoNrCuClAkWOTR89e -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | dist/* 3 | packages/*/dist/* -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "plugins": [ 4 | "testcafe", 5 | "html" 6 | ], 7 | "extends": [ 8 | "plugin:testcafe/recommended", 9 | "standard" 10 | ], 11 | "env": { 12 | "browser": true 13 | } 14 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .nyc_output/ 2 | coverage/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: "stable" 3 | 4 | after_success: 5 | - npm run coverage 6 | 7 | before_install: 8 | - stty cols 80 9 | 10 | dist: trusty 11 | sudo: required 12 | 13 | addons: 14 | firefox: latest 15 | apt: 16 | sources: 17 | - google-chrome 18 | packages: 19 | - google-chrome-stable fluxbox 20 | 21 | before_script: 22 | - "export DISPLAY=:99.0" 23 | - "sh -e /etc/init.d/xvfb start" 24 | - sleep 3 25 | - fluxbox >/dev/null 2>&1 & 26 | 27 | install: 28 | - npm install 29 | script: 30 | - npm run test -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-present, 成都数联医信科技有限公司 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Vuet 2 | [![Coverage Status](https://coveralls.io/repos/github/medatc/vuet/badge.svg?branch=dev)](https://coveralls.io/github/medatc/vuet?branch=dev) 3 | [![Build Status](https://travis-ci.org/medatc/vuet.svg?branch=dev)](https://travis-ci.org/medatc/vuet) 4 | [![npm](https://img.shields.io/npm/v/vuet.svg)](https://www.npmjs.com/package/vuet) 5 | [![npm](https://img.shields.io/npm/dm/vuet.svg)](https://www.npmjs.com/package/vuet) 6 | [![npm](https://img.shields.io/npm/dt/vuet.svg)](https://www.npmjs.com/package/vuet) 7 | 8 | ## 此项目除了正常的bug修复,不再进行功能更新 9 | 如果对状态管理感兴趣,可以看下 [Tms](https://github.com/FollowmeTech/tms),文档更齐全 10 | 11 |

12 | 13 |

14 | 15 | 16 | ## 索引 17 | - [Vuet.js是什么?](#vuetjs是什么) 18 | - [0.x版本和1.x版本的区别](#0x版本和1x版本的区别) 19 | - [0.x升级指南](https://juejin.im/post/5997c566518825241e220d8a) 20 | - [安装](#安装) 21 | - [快速入门](#快速入门) 22 | - [API](#api) 23 | - [实例的选项](#实例的选项) 24 | - [实例的属性](#实例的属性) 25 | - [实例的方法](#实例的方法) 26 | - [静态属性](#静态属性) 27 | - [静态方法](#静态方法) 28 | - [模块](#模块) 29 | - [什么是模块?](#什么是模块) 30 | - [注册模块](#注册模块) 31 | - [使用计算属性连接模块](#使用计算属性连接模块) 32 | - [在模块中获取路由对象](#在模块中获取路由对象) 33 | - [重置模块状态](#重置模块状态) 34 | - [添加模块公共方法或属性](#添加模块公共方法或属性) 35 | - [规则](#规则) 36 | - [什么是规则?](#什么是规则) 37 | - [内置的规则](#内置的规则) 38 | - [自定义规则](#自定义规则) 39 | - [第三方插件](#第三方插件) 40 | - [第三方项目](#第三方项目) 41 | - [Vuet.js开发交流群](//shang.qq.com/wpa/qunwpa?idkey=cc9b70a903a9df6c86380a6ec03f1488f6386200a2132d7d3a9fab0da37396eb) 42 | 43 | 44 | ## Vuet.js是什么? 45 | 在`vuex`中更新状态的唯一途径,就是通过提交`mutation`,这个过程是琐碎的,而在`Vuet`中是允许在何时何地进行直接赋值更新的,这个过程它是愉快的。`Vuet`是一种集中式状态管理模式,提供了模块系统和规则系统,它存在的意义是为了将状态管理变得简单 46 | 47 | ## 0.x版本和1.x版本的区别 48 | 在`0.x`版本中,我们内置了太多的功能,导致大幅度提升了入门的门槛,`1.x`版本则是化繁为简,只保留了几个核心的API。 49 | `注`:route规则已经从Vuet中删除,后续会以插件的形式进行发布,敬请期待![0.x版本地址](https://github.com/medatc/vuet/tree/0.3.0) 50 | 51 | ## 安装 52 | ```bash 53 | npm install vuet@latest 54 | ``` 55 | 56 | ## 快速入门 57 | ```javascript 58 | 59 | import Vue from 'vue' 60 | import Vuet, { mapModules, mapRules } from 'vuet' 61 | 62 | Vue.use(Vuet) 63 | 64 | const vuet = new Vuet({ 65 | // 实例的选项,详情往下看 66 | }) 67 | vuet.addModules('test', { 68 | data () { 69 | return { 70 | count: 0 71 | } 72 | }, 73 | fetch () { 74 | this.count = 1000 75 | }, 76 | plus () { 77 | this.count++ 78 | }, 79 | reduce () { 80 | this.count-- 81 | }, 82 | modules: { 83 | // 可以添加子模块,会自动继承父模块的名称:路径 = 父模块名称/子模块名称 84 | } 85 | }) 86 | 87 | const App = { 88 | mixins: [ 89 | mapModules({ 90 | test: 'test' // { 别名: '模块路径' } 91 | }), 92 | mapRules({ 93 | once: [{ path: 'test' }] // { 规则: ['模块路径'] } 内置的规则和简写方式可以在下面看 94 | }) 95 | ], 96 | template: ` 97 |
98 |
{{ test.count }}
99 | 100 | 101 | 102 | 103 |
104 | ` 105 | } 106 | 107 | export default new Vue({ 108 | el: '#app', 109 | vuet, 110 | render (h) { 111 | return h(App) 112 | } 113 | }) 114 | 115 | ``` 116 | 117 | ## API 118 | 119 | 120 | ### 实例的选项 121 | `options.pathJoin` 122 | - 描述:子模块继承父模块时分割符 123 | - 默认值:`/` 124 | 125 | `options.modules` 126 | - 描述:要初始化的模块 127 | - 默认值:`{}` 128 | 129 | ### 实例的属性 130 | `vuet.version` 131 | - 描述:当前的版本号 132 | 133 | `vuet.app` 134 | - 描述:`new Vuet({ vuet })`时的`Vue`实例 135 | - 默认值:`null` 136 | 137 | `vuet.modules` 138 | - 描述:添加的模块,全部都在这里 139 | - 默认值:`{}` 140 | 141 | `vuet.options` 142 | - 描述:`new Vuet(options)`实例化时传入的参数 143 | - 默认值:`{ pathJoin: '/', modules: {} }` 144 | 145 | `vuet.store` 146 | - 描述:每个模块存储的状态 147 | - 默认值:`{}` 148 | 149 | `vuet.vm` 150 | - 描述:vuet内部的Vue实例 151 | 152 | 153 | ### 实例的方法 154 | `vuet.addModules(path: string, modules: Object)` 155 | - 描述:注册模块,并返回添加的模块(1.0.3及以上版本支持) 156 | 157 | `vuet.replaceStore(store: Object)` 158 | - 描述:替换整个vuet的store,服务器端渲染时会用到(1.0.3及以上版本支持) 159 | 160 | `vuet.getModule(path: string)` 161 | - 描述:返回该模块的状态和方法 162 | 163 | `vuet.getState(path: string)` 164 | - 描述:只返回模块的状态,不会返回方法 165 | 166 | `vuet.destroy()` 167 | - 描述:销毁程序,释放内存。vue实例销毁时,也会跟着自动销毁 168 | 169 | ### 静态属性 170 | `Vuet.options.rules` 171 | - 描述:存储了`Vuet`内置的规则,以及`Vuet.rule`添加的规则 172 | 173 | `Vuet.options.module` 174 | - 描述:存储了`Vuet`模块公共的方法 175 | 176 | ### 静态方法 177 | `Vuet.mapModules(opts: { 别名: '模块路径' })` 178 | - 描述:在Vue组件中连接模块,这样就可以在组件中使用模块的方法和状态 179 | 180 | `Vuet.mapRules(opts: { 规则: [{ path: '模块路径 }] })` 181 | - 描述:使用对应的规则,来更新模块。支持简写:`{ 规则: '模块路径' }`、`{ 规则: ['模块路径'] }` 182 | 183 | `Vuet.rule(name: string, opts: Object)` 184 | - 描述:注册全局规则,详情可以查看下面的[自定义规则](#自定义规则) 185 | 186 | 187 | ## 模块 188 | 189 | 190 | ### 什么是模块? 191 | 模块好比就是一个人的基本骨架,模块的属性就好比人的手、脚、眼睛等等,而模块的方法就好比大脑,操纵着人的行为,比如用手撸代码,用脚走路,看到漂亮的美女眨眨眼睛 192 | 193 | 194 | ### 注册模块 195 | ```javascript 196 | const vuet = new Vuet() 197 | 198 | // 注册了一个叫test的模块 199 | vuet.addModules('test', { 200 | data () { 201 | return { 202 | count: 0 // 定义了一个count属性 203 | } 204 | }, 205 | plus () { // 定义了一个plus方法 206 | this.count++ 207 | }, 208 | modules: { // 定义子模块 209 | chlid: { // 子模块路径 = 父模块/子模块 = test/chlid 210 | data () { 211 | return { 212 | count: 0 // 定义了一个count属性 213 | } 214 | }, 215 | plus () { // 定义了一个plus方法 216 | this.count++ 217 | } 218 | } 219 | } 220 | }) 221 | 222 | ``` 223 | 224 | 225 | ### 使用计算属性连接模块 226 | ```javascript 227 | { 228 | computed: { 229 | test () { // 虽然可以通过mapModules方法向组件注入模块,但是也可以通过计算属性的方法获取模块 230 | return this.$vuet.getModule('模块路径') 231 | } 232 | }, 233 | beforeCreate () { 234 | // this.test 取得模块,就可以调用模块的方法和属性了 235 | // this.$vuet 取得vuet实例,然后就可以愉快的玩耍了 236 | } 237 | } 238 | ``` 239 | 240 | 241 | ### 在模块中获取路由对象 242 | ```javascript 243 | const vuet = new Vuet() 244 | vuet.addModules('test', { 245 | data () { 246 | return {} 247 | }, 248 | plus () { 249 | this.vuet // 取得vuet实例 250 | this.app // 取得vue根实例 251 | this.app.$router // 获取路由的方法 252 | this.app.$route // 获取路由的状态 253 | } 254 | }) 255 | ``` 256 | 257 | 258 | ### 重置模块状态 259 | ```javascript 260 | const vuet = new Vuet() 261 | vuet.addModules('test', { 262 | data () { 263 | return { 264 | count: 0 265 | } 266 | }, 267 | plus () { 268 | this.count = 100 // 等同于 this.state.count 269 | setTimeout(() => { 270 | this.reset() // 这是vuet内置的一个reset的方法 等同于 this.state = this.data() 271 | }, 2000) 272 | } 273 | }) 274 | ``` 275 | 276 | 277 | ### 添加模块公共方法或属性 278 | 有时候,在Vuet模块中,我们期望能添加一些公共的方法或属性,以便在模块中能够使用`this.xxxx`的形式访问,来减少很多代码量 279 | ```javascript 280 | import Vuet from 'vuet' 281 | 282 | Vuet.options.module.isFunction = (any) => (typeof any === 'function') 283 | 284 | const vuet = new Vuet({ 285 | modules: { 286 | test: { 287 | data () { 288 | return { 289 | count: 0 290 | } 291 | }, 292 | plus () { 293 | // 这样就可以访问到我们公共的方法了 294 | this.isFunction() 295 | } 296 | } 297 | } 298 | }) 299 | ``` 300 | 301 | 302 | ## 规则 303 | 304 | 305 | ### 什么是规则? 306 | 在`Vuet`中,`规则`在`Vuet`中是一种特殊的存在,它允许你将类似的更新一个模块状态的过程抽象出来,你可以使用`规则`来更新任何一个模块。你可以把`Vuet模块`当成一辆车,而`规则`就是定义这辆车应该怎么行走,到底是直走,还是转弯,还是直走一会,然后转弯,这些都是通过来`规则`来定义它 307 | 308 | 309 | ### 内置的规则 310 | `need` 311 | - 描述:组件每次初始化时,在`beforeCreate`钩子中调用一次`fetch`方法 312 | 313 | `once` 314 | - 描述:仅第一次在组件的`beforeCreate`钩子中调用一次`fetch`方法,之后在任何组件都不会再进行更新 315 | 316 | `temp` 317 | - 描述:组件初始化时,在`beforeCreate`钩子中调用一次`fetch`方法,组件销毁时,在`destroyed`钩子中重置模块状态 318 | 319 | `reset` 320 | - 描述:组件销毁时,在`destroyed`钩子中重置模块状态,这个能有效的减少对内存的占用 321 | 322 | 323 | ### 自定义规则 324 | 主要的原理就是获取传入的`模块路径`,`return`一个`mixin`注入到组件中 325 | 我们现在就开始尝试定义一个飙车的过程,就是在组件每次执行`beforeCreate`钩子时,调用一次模块的`fetch`方法,那我们现在尝试定义一个`myRule`规则 326 | ```javascript 327 | Vuet.rule('myRule', { // 注意:规则的注册必须在所有组件执行之前 328 | install (Vuet, Vue) { 329 | // 传入一个Vuet和Vue构造函数。只会调用一次 330 | }, 331 | init (vuet) { 332 | // new Vuet() 实例化后,传入实例,你可以在这里添加一些模块、方法之类的。每new一个Vuet实例,都会执行一次钩子 333 | }, 334 | addModule (vuet, path) { 335 | // new Vuet().addModules 每注册一个模块,都会执行一次钩子,此时模块已经创建完成 336 | } 337 | rule ({ path }) { 338 | // 传入当前模块的路径,返回一个mixin来注入到组件中。执行Vuet的mapRules方法时会调用 339 | return { 340 | beforeCreate () { 341 | // 用路径,取得当前的模块 342 | const vtm = this.$vuet.getModule(path) 343 | // 然后调用一次模块的fetch方法 344 | vtm.fetch() 345 | } 346 | } 347 | }, 348 | destroy (vuet) { 349 | // 传入当前要销毁的vuet实例,你可以做一些自己使用销毁的东西 350 | } 351 | }) 352 | ``` 353 | 向组件中注入更新模块的规则 354 | ```javascript 355 | { 356 | mixins: [ 357 | mapRules({ 358 | 'myRule': '更新的模块路径' 359 | }) 360 | ] 361 | // ...options 362 | } 363 | ``` 364 | 365 | 366 | ## 第三方插件 367 | - [vuet-scroll](./packages/vuet-scroll) 记录滚动条位置 368 | - [vuet-store](./packages/vuet-store) 将模块状态记录在`localStorage`中 369 | - [vuet-route](./packages/vuet-route) 根据`vue-router`的变化,来重新请求数据 370 | 371 | 372 | ## 第三方项目 373 | - [vue-cnode](https://github.com/lzxb/vue-cnode) Vue + Vuet实现的cnode社区 374 | 375 | 376 | ## 许可证 377 | MIT 378 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | const { rollup } = require('rollup') 2 | const uglify = require('rollup-plugin-uglify') 3 | const { minify } = require('uglify-js') 4 | const replace = require('rollup-plugin-replace') 5 | const babel = require('rollup-plugin-babel') 6 | const packages = require('../package.json') 7 | 8 | const build = async (opts) => { 9 | let packagesName = opts.destName.split('/') 10 | packagesName = packagesName[packagesName.length - 1] 11 | const plugins = [ 12 | babel({ 13 | babelrc: false, 14 | presets: [ 15 | ['es2015-rollup'], 16 | 'stage-0' 17 | ], 18 | plugins: ['transform-object-assign'] 19 | }), 20 | replace({ 21 | '__version__': packages.version, 22 | '__name__': packagesName, 23 | 'process.env.NODE_ENV': JSON.stringify(opts.env) 24 | }) 25 | ] 26 | if (opts.env === 'production') { 27 | plugins.push(uglify({ 28 | compress: { 29 | drop_debugger: true, 30 | drop_console: true 31 | } 32 | }, minify)) 33 | } 34 | const bundle = await rollup({ entry: opts.entry, plugins }) 35 | const name = opts.env === 'production' ? opts.destName + '.min' : opts.destName 36 | await bundle.write({ 37 | moduleName: opts.moduleName, 38 | format: 'umd', 39 | dest: `dist/${name}.js`, 40 | sourceMap: true, 41 | exports: 'named' 42 | }) 43 | } 44 | 45 | const builds = [ 46 | { 47 | moduleName: 'Vuet', 48 | destName: 'vuet', 49 | entry: 'src/index.js', 50 | env: 'development' 51 | }, 52 | { 53 | moduleName: 'Vuet', 54 | destName: 'vuet', 55 | entry: 'src/index.js', 56 | env: 'production' 57 | }, 58 | { 59 | moduleName: 'VuetScroll', 60 | destName: '../packages/vuet-scroll/dist/vuet-scroll', 61 | entry: 'packages/vuet-scroll/src/index.js', 62 | env: 'development' 63 | }, 64 | { 65 | moduleName: 'VuetScroll', 66 | destName: '../packages/vuet-scroll/dist/vuet-scroll', 67 | entry: 'packages/vuet-scroll/src/index.js', 68 | env: 'production' 69 | }, 70 | { 71 | moduleName: 'VuetRoute', 72 | destName: '../packages/vuet-route/dist/vuet-route', 73 | entry: 'packages/vuet-route/src/index.js', 74 | env: 'development' 75 | }, 76 | { 77 | moduleName: 'VuetRoute', 78 | destName: '../packages/vuet-route/dist/vuet-route', 79 | entry: 'packages/vuet-route/src/index.js', 80 | env: 'production' 81 | }, 82 | { 83 | moduleName: 'VuetStore', 84 | destName: '../packages/vuet-store/dist/vuet-store', 85 | entry: 'packages/vuet-store/src/index.js', 86 | env: 'development' 87 | }, 88 | { 89 | moduleName: 'VuetStore', 90 | destName: '../packages/vuet-store/dist/vuet-store', 91 | entry: 'packages/vuet-store/src/index.js', 92 | env: 'production' 93 | } 94 | ] 95 | 96 | builds.forEach(opts => build(opts)) 97 | -------------------------------------------------------------------------------- /dist/vuet.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.Vuet=t.Vuet||{})}(this,function(t){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},o=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},n=function(){function t(t,e){for(var o=0;o1?e[1]:e[0]:e[0]&&u.isObject(e[0])&&(t=e[0]),t},isPromise:function(t){return("object"===(void 0===t?"undefined":e(t))||"function"==typeof t)&&!!t&&"function"==typeof t.then}},s=void 0,c={error:function(t){throw new Error("[vuet] "+t)},warn:function(t){},assertModule:function(t,e){e in t.modules||this.error("The '"+e+"' module does not exist")},assertVue:function(){s||this.error("must call Vue.use(Vuet) before creating a store instance")},assertFetch:function(t,e){this.assertModule(t,e),"function"!=typeof t.getModule(e).fetch&&this.error("'"+e+"' module 'fetch' must be the function type")}},a={rule:function(t){var e=t.path;return{beforeCreate:function(){c.assertFetch(this.$vuet,e),this.$vuet.getModule(e).fetch()}}}},f={init:function(t){t.__once__=[]},rule:function(t){var e=t.path;return{beforeCreate:function(){c.assertFetch(this.$vuet,e);var t=this.$vuet;if(!(t.__once__.indexOf(e)>-1)){var o=this.$vuet.getModule(e).fetch();if(u.isPromise(o))return o.then(function(o){t.__once__.push(e)});t.__once__.push(e)}}}}},l={rule:function(t){var e=t.path;return{beforeCreate:function(){c.assertModule(this.$vuet,e)},destroyed:function(){this.$vuet.getModule(e).reset()}}}},h={rule:function(t){var e=t.path;return{beforeCreate:function(){c.assertFetch(this.$vuet,e),this.$vuet.getModule(e).fetch()},destroyed:function(){this.$vuet.getModule(e).reset()}}}},d=function(){function t(e){var n=this;o(this,t),c.assertVue(),this.version="1.0.3",this.modules={},this.store={},this.options={pathJoin:"/",modules:{}},this.app=null,this.vm=new s({data:{modules:this.store}}),i(this.options,e),t.callRuleHook("init",this),Object.keys(this.options.modules).forEach(function(t){n.addModules(t,n.options.modules[t])})}return n(t,[{key:"_init",value:function(t){this.app=t}},{key:"addModules",value:function(e,o){var n=this;if(u.isObject(o.modules)&&Object.keys(o.modules).forEach(function(t){n.addModules(""+e+n.options.pathJoin+t,o.modules[t])}),"function"!=typeof o.data)return this;var r=this,a=i({},t.options.module,o);return s.set(r.store,e,a.data()),r.modules[e]=a,Object.defineProperty(a,"vuet",{get:function(){return r}}),Object.defineProperty(a,"app",{get:function(){return r.app}}),Object.defineProperty(a,"state",{get:function(){return r.store[e]},set:function(t){r.store[e]=t}}),Object.keys(a).forEach(function(t){if("function"==typeof a[t]){var o=a[t];a[t]=function(){return o.apply(r.modules[e],arguments)}}}),u.isObject(a.state)&&Object.keys(a.state).forEach(function(t){if(t in a)return c.warn("'"+e+"' the '"+t+"' already exists on the object");Object.defineProperty(a,t,{get:function(){return r.store[e][t]},set:function(o){r.store[e][t]=o}})}),t.callRuleHook("addModule",this,e),this.getModule(e)}},{key:"getModule",value:function(t){return c.assertModule(this,t),this.modules[t]}},{key:"getState",value:function(t){return c.assertModule(this,t),this.modules[t].state}},{key:"replaceStore",value:function(t){return this.store=this.vm.$data.modules=t,this}},{key:"destroy",value:function(){this.vm.$destroy(),t.callRuleHook("destroy",this)}}]),t}();!function(t){i(t,{installed:!1,options:{rules:{},module:{reset:function(){return this.state=this.data(),this}}},install:function(e){return this.installed?this:(this.installed=!0,s=e,Object.defineProperty(e.prototype,"$vuet",{get:function(){return this.$root._vuet}}),e.mixin({beforeCreate:function(){void 0!==this.$options.vuet&&this.$options.vuet instanceof t&&(this._vuet=this.$options.vuet,this._vuet._init(this))},destroyed:function(){void 0!==this.$options.vuet&&this.$options.vuet instanceof t&&this._vuet.destroy(this)}}),this)},mapModules:function(t){return{mixins:Object.keys(t).map(function(e){var o=t[e];return{computed:r({},e,{get:function(){return c.assertModule(this.$vuet,o),this.$vuet.getModule(o)},set:function(t){c.error("The'"+o+"'module is not allowed to assign")}})}})}},mapRules:function(){var e=u.getArgMerge.apply(null,arguments),o=[],n=function(e,n){var r=t.options.rules[e];u.isObject(r)||c.error("The'"+e+"'rule does not exist. Please make sure that it executes 'Vuet.rule('"+e+"', opts)' before all components"),"string"==typeof n?o.push(r.rule({path:n})):o.push(r.rule(n))};return Object.keys(e).forEach(function(t){var o=e[t];if(Array.isArray(o))return o.forEach(function(e){n(t,e)});n(t,o)}),{mixins:o}},rule:function(){return t.options.rules[arguments[0]]=arguments[1],"function"==typeof arguments[1].install&&arguments[1].install(t,s),this},callRuleHook:function(e){for(var o=arguments.length,n=Array(o>1?o-1:0),r=1;r 1 ? args[1] : args[0]\n } else if (args[0] && util.isObject(args[0])) {\n opt = args[0]\n }\n return opt\n },\n isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function'\n }\n}\n\nexport default util\n","import debug from './debug'\nimport util from './util'\n\nexport let _Vue\n\nexport default function (Vuet) {\n Object.assign(Vuet, {\n installed: false,\n options: {\n rules: {},\n module: {\n reset () {\n this.state = this.data()\n return this\n }\n }\n },\n install (Vue) {\n if (this.installed) return this\n this.installed = true\n _Vue = Vue\n Object.defineProperty(Vue.prototype, '$vuet', {\n get () { return this.$root._vuet }\n })\n Vue.mixin({\n beforeCreate () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet = this.$options.vuet\n this._vuet._init(this)\n }\n }\n },\n destroyed () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet.destroy(this)\n }\n }\n }\n })\n return this\n },\n mapModules (opts) {\n const mixins = Object.keys(opts).map(alias => {\n const path = opts[alias]\n return {\n computed: {\n [alias]: {\n get () {\n debug.assertModule(this.$vuet, path)\n return this.$vuet.getModule(path)\n },\n set (val) {\n debug.error(`The'${path}'module is not allowed to assign`)\n }\n }\n }\n }\n })\n return {\n mixins\n }\n },\n mapRules () {\n const opts = util.getArgMerge.apply(null, arguments)\n const vueRules = []\n const addRule = (ruleName, any) => {\n const rules = Vuet.options.rules[ruleName]\n if (!util.isObject(rules)) debug.error(`The'${ruleName}'rule does not exist. Please make sure that it executes 'Vuet.rule('${ruleName}', opts)' before all components`)\n if (typeof any === 'string') {\n vueRules.push(rules.rule({ path: any }))\n } else {\n vueRules.push(rules.rule(any))\n }\n }\n Object.keys(opts).forEach(ruleName => {\n const any = opts[ruleName]\n if (Array.isArray(any)) {\n return any.forEach(item => {\n addRule(ruleName, item)\n })\n }\n addRule(ruleName, any)\n })\n return {\n mixins: vueRules\n }\n },\n rule () {\n Vuet.options.rules[arguments[0]] = arguments[1]\n if (typeof arguments[1].install === 'function') {\n arguments[1].install(Vuet, _Vue)\n }\n return this\n },\n callRuleHook (hook, ...arg) {\n Object.keys(Vuet.options.rules).forEach(k => {\n if (typeof Vuet.options.rules[k][hook] === 'function') {\n Vuet.options.rules[k][hook].apply(undefined, arg)\n }\n })\n }\n })\n}\n","import { _Vue } from './vuet-static'\n\nconst NAME = '__name__'\n\nexport default {\n error (msg) {\n throw new Error(`[${NAME}] ${msg}`)\n },\n warn (msg) {\n if (process.env.NODE_ENV !== 'production') {\n typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`)\n }\n },\n assertModule (vuet, path) {\n if (path in vuet.modules) {\n return\n }\n this.error(`The '${path}' module does not exist`)\n },\n assertVue () {\n if (!_Vue) {\n this.error('must call Vue.use(Vuet) before creating a store instance')\n }\n },\n assertFetch (vuet, path) {\n this.assertModule(vuet, path)\n if (typeof vuet.getModule(path).fetch !== 'function') {\n this.error(`'${path}' module 'fetch' must be the function type`)\n }\n }\n}\n","import debug from '../debug'\n\nexport default {\n rule ({ path }) {\n return {\n beforeCreate () {\n debug.assertFetch(this.$vuet, path)\n this.$vuet.getModule(path).fetch()\n }\n }\n }\n}\n","import debug from '../debug'\nimport util from '../util'\n\nconst NAME = '__once__'\n\nexport default {\n init (vuet) {\n vuet[NAME] = []\n },\n rule ({ path }) {\n return {\n beforeCreate () {\n debug.assertFetch(this.$vuet, path)\n const vuet = this.$vuet\n if (vuet[NAME].indexOf(path) > -1) return\n const back = this.$vuet.getModule(path).fetch()\n if (util.isPromise(back)) {\n return back.then(res => {\n vuet[NAME].push(path)\n })\n }\n vuet[NAME].push(path)\n }\n }\n }\n}\n","import debug from '../debug'\n\nexport default {\n rule ({ path }) {\n return {\n beforeCreate () {\n debug.assertModule(this.$vuet, path)\n },\n destroyed () {\n this.$vuet.getModule(path).reset()\n }\n }\n }\n}\n","import debug from '../debug'\n\nexport default {\n rule ({ path }) {\n return {\n beforeCreate () {\n debug.assertFetch(this.$vuet, path)\n this.$vuet.getModule(path).fetch()\n },\n destroyed () {\n this.$vuet.getModule(path).reset()\n }\n }\n }\n}\n","import debug from './debug'\nimport util from './util'\nimport { _Vue } from './vuet-static'\nexport default class Vuet {\n constructor (opts) {\n debug.assertVue()\n // debug.assertPromise()\n this.version = '__version__'\n this.modules = {}\n this.store = {}\n this.options = {\n pathJoin: '/',\n modules: {}\n }\n this.app = null\n this.vm = new _Vue({\n data: {\n modules: this.store\n }\n })\n Object.assign(this.options, opts)\n Vuet.callRuleHook('init', this)\n Object.keys(this.options.modules).forEach(k => {\n this.addModules(k, this.options.modules[k])\n })\n }\n _init (app) {\n this.app = app\n }\n addModules (path, modules) {\n if (util.isObject(modules.modules)) {\n Object.keys(modules.modules).forEach(k => {\n this.addModules(`${path}${this.options.pathJoin}${k}`, modules.modules[k])\n })\n }\n if (typeof modules.data !== 'function') return this\n const vuet = this\n const opts = { ...Vuet.options.module, ...modules }\n _Vue.set(vuet.store, path, opts.data())\n vuet.modules[path] = opts\n Object.defineProperty(opts, 'vuet', {\n get: () => (vuet)\n })\n Object.defineProperty(opts, 'app', {\n get: () => (vuet.app)\n })\n Object.defineProperty(opts, 'state', {\n get () {\n return vuet.store[path]\n },\n set (val) {\n vuet.store[path] = val\n }\n })\n Object.keys(opts).forEach(k => {\n if (typeof opts[k] === 'function') {\n const native = opts[k]\n opts[k] = function proxy () {\n return native.apply(vuet.modules[path], arguments)\n }\n }\n })\n if (util.isObject(opts.state)) {\n Object.keys(opts.state).forEach(k => {\n if (k in opts) {\n return debug.warn(`'${path}' the '${k}' already exists on the object`)\n }\n Object.defineProperty(opts, k, {\n get () {\n return vuet.store[path][k]\n },\n set (val) {\n vuet.store[path][k] = val\n }\n })\n })\n }\n Vuet.callRuleHook('addModule', this, path)\n return this.getModule(path)\n }\n getModule (path) {\n debug.assertModule(this, path)\n return this.modules[path]\n }\n getState (path) {\n debug.assertModule(this, path)\n return this.modules[path].state\n }\n replaceStore (store) {\n this.store = this.vm.$data.modules = store\n return this\n }\n destroy () {\n this.vm.$destroy()\n Vuet.callRuleHook('destroy', this)\n }\n}\n","import rules from './rules/index'\nimport VuetStatic from './vuet-static'\nimport Vuet from './vuet'\n\nVuetStatic(Vuet)\nrules(Vuet)\nexport const mapRules = Vuet.mapRules.bind(Vuet)\nexport const mapModules = Vuet.mapModules.bind(Vuet)\n\nexport default Vuet\n","import need from './need'\nimport once from './once'\nimport reset from './reset'\nimport temp from './temp'\n\nexport default function install (Vuet) {\n Vuet\n .rule('need', need)\n .rule('once', once)\n .rule('temp', temp)\n .rule('reset', reset)\n}\n"],"names":["util","obj","Object","prototype","toString","call","opt","args","arguments","length","isObject","then","_Vue","msg","Error","vuet","path","modules","error","assertModule","getModule","fetch","assertFetch","this","$vuet","indexOf","back","isPromise","push","reset","Vuet","opts","assertVue","version","store","options","app","vm","callRuleHook","keys","forEach","addModules","k","_this","_this2","pathJoin","data","module","set","defineProperty","val","native","apply","state","debug","warn","$data","$destroy","Vue","installed","$root","_vuet","mixin","$options","_init","destroy","map","alias","getArgMerge","vueRules","addRule","ruleName","any","rules","rule","Array","isArray","item","install","hook","arg","undefined","need","once","temp","mapRules","bind","mapModules"],"mappings":"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"} -------------------------------------------------------------------------------- /examples/base/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet base 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/base/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet, { mapModules, mapRules } from 'vuet' 3 | 4 | Vue.use(Vuet) 5 | 6 | const vuet = new Vuet() 7 | vuet.addModules('test', { 8 | data () { 9 | return { 10 | count: 0 11 | } 12 | }, 13 | fetch () { 14 | this.count = 1000 15 | }, 16 | plus () { 17 | this.count++ 18 | }, 19 | reduce () { 20 | this.count-- 21 | } 22 | }) 23 | 24 | const App = { 25 | mixins: [ 26 | mapModules({ 27 | test: 'test' // { 别名: '模块路径' } 28 | }), 29 | mapRules({ 30 | once: [{ path: 'test' }] // { 规则: ['模块路径'] } 31 | }) 32 | ], 33 | template: ` 34 |
35 |
{{ test.count }}
36 | 37 | 38 | 39 | 40 |
41 | ` 42 | } 43 | 44 | export default new Vue({ 45 | el: '#app', 46 | vuet, 47 | render (h) { 48 | return h(App) 49 | } 50 | }) 51 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | vuet examples 8 | 9 | 10 | 45 | 46 | -------------------------------------------------------------------------------- /examples/need/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 26 | -------------------------------------------------------------------------------- /examples/need/OutputContent.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /examples/need/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet need 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/need/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import vuet from './vuet' 4 | 5 | export default new Vue({ 6 | el: '#app', 7 | vuet, 8 | render (h) { 9 | return h(App) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/need/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | 4 | Vue.use(Vuet) 5 | 6 | let fetchCount = 0 7 | 8 | export default new Vuet({ 9 | modules: { 10 | test: { 11 | data () { 12 | return { 13 | count: 0, 14 | fetchCount: 0 15 | } 16 | }, 17 | async fetch () { 18 | const { state } = this 19 | this.state = { 20 | count: ++state.count, 21 | fetchCount: ++fetchCount 22 | } 23 | } 24 | } 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /examples/once/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 26 | -------------------------------------------------------------------------------- /examples/once/OutputContent.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /examples/once/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet once 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/once/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import vuet from './vuet' 4 | 5 | export default new Vue({ 6 | el: '#app', 7 | vuet, 8 | render (h) { 9 | return h(App) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/once/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | 4 | Vue.use(Vuet) 5 | 6 | let fetchCount = 0 7 | 8 | export default new Vuet({ 9 | modules: { 10 | test: { 11 | data () { 12 | return { 13 | count: 0, 14 | fetchCount: 0 15 | } 16 | }, 17 | async fetch () { 18 | const { state } = this 19 | this.state = { 20 | count: ++state.count, 21 | fetchCount: ++fetchCount 22 | } 23 | } 24 | } 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /examples/route/Detail.vue: -------------------------------------------------------------------------------- 1 | 10 | 20 | -------------------------------------------------------------------------------- /examples/route/List.vue: -------------------------------------------------------------------------------- 1 | 18 | 50 | -------------------------------------------------------------------------------- /examples/route/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet route 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/route/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import vuet from './vuet' 4 | import List from './List' 5 | import Detail from './Detail' 6 | 7 | Vue.use(VueRouter) 8 | 9 | const router = new VueRouter({ 10 | routes: [ 11 | { 12 | path: '/', 13 | name: 'index', 14 | component: List 15 | }, 16 | { 17 | path: '/:id', 18 | name: 'detail', 19 | component: Detail 20 | } 21 | ] 22 | }) 23 | 24 | export default new Vue({ 25 | el: '#app', 26 | vuet, 27 | router, 28 | render (h) { 29 | return h('router-view') 30 | } 31 | }) 32 | -------------------------------------------------------------------------------- /examples/route/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | import VuetRoute from 'vuet-route' 4 | 5 | Vuet.rule('route', VuetRoute) 6 | 7 | Vue.use(Vuet) 8 | 9 | const listData = () => ([ 10 | { 11 | id: 1, 12 | title: '1 title', 13 | content: '1x1 content', 14 | type: 'good' 15 | }, 16 | { 17 | id: 2, 18 | title: '2 title', 19 | content: '2x1 content', 20 | type: 'share' 21 | }, 22 | { 23 | id: 3, 24 | title: '3 title', 25 | content: '3x1 content', 26 | type: 'share' 27 | }, 28 | { 29 | id: 4, 30 | title: '4 title', 31 | content: '4x1 content', 32 | type: 'good' 33 | } 34 | ]) 35 | 36 | export default new Vuet({ 37 | data () { 38 | return {} 39 | }, 40 | modules: { 41 | topic: { 42 | modules: { 43 | list: { 44 | data () { 45 | return { 46 | list: [], 47 | fetchCount: 0 48 | } 49 | }, 50 | route: { 51 | watch: 'query' 52 | }, 53 | async fetch () { 54 | const { type = 'all' } = this.app.$route.query 55 | let list = listData() 56 | if (type !== 'all') { 57 | list = listData().filter((item) => item.type === type) 58 | } 59 | await new Promise((resolve, reject) => { 60 | setTimeout(() => { 61 | resolve() 62 | }, 1000) 63 | }) 64 | this.list = list 65 | this.fetchCount++ 66 | } 67 | }, 68 | detail: { 69 | data () { 70 | return { 71 | id: null, 72 | title: null, 73 | content: null, 74 | type: null, 75 | fetchCount: 0 76 | } 77 | }, 78 | route: { 79 | watch: 'params.id' 80 | }, 81 | async fetch ({ state }) { 82 | const { id } = this.app.$route.params 83 | await new Promise((resolve, reject) => { 84 | setTimeout(() => { 85 | resolve() 86 | }, 1000) 87 | }) 88 | const arr = listData() 89 | for (let i = 0; i < arr.length; i++) { 90 | if (arr[i].id === Number(id)) { 91 | Object.assign(this, { ...arr[i], fetchCount: ++this.fetchCount }) 92 | } 93 | } 94 | } 95 | } 96 | } 97 | } 98 | } 99 | }) 100 | -------------------------------------------------------------------------------- /examples/scroll-cnode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet scroll-cnode 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/scroll-cnode/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import vuet from './vuet/' 3 | import router from './router/' 4 | 5 | export default new Vue({ 6 | el: '#app', 7 | vuet, 8 | router, 9 | render (h) { 10 | return h('router-view') 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /examples/scroll-cnode/pages/topic/Detail.vue: -------------------------------------------------------------------------------- 1 | 9 | 25 | 28 | -------------------------------------------------------------------------------- /examples/scroll-cnode/pages/topic/List.vue: -------------------------------------------------------------------------------- 1 | 18 | 34 | 62 | -------------------------------------------------------------------------------- /examples/scroll-cnode/router/index.js: -------------------------------------------------------------------------------- 1 | import router from './router' 2 | 3 | export default router 4 | -------------------------------------------------------------------------------- /examples/scroll-cnode/router/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import TopicList from '../pages/topic/List' 4 | import TopicDetail from '../pages/topic/Detail' 5 | 6 | Vue.use(VueRouter) 7 | 8 | const RouterView = { 9 | render (h) { 10 | return h('router-view') 11 | } 12 | } 13 | 14 | const router = new VueRouter({ 15 | routes: [ 16 | { 17 | path: '/', 18 | component: RouterView, 19 | children: [ 20 | { 21 | path: '', 22 | name: 'topic-list', 23 | component: TopicList 24 | }, 25 | { 26 | path: '/:id', 27 | name: 'topic-detail', 28 | component: TopicDetail 29 | } 30 | ] 31 | } 32 | ] 33 | }) 34 | 35 | export default router 36 | -------------------------------------------------------------------------------- /examples/scroll-cnode/vuet/index.js: -------------------------------------------------------------------------------- 1 | import vuet from './vuet' 2 | 3 | export default vuet 4 | -------------------------------------------------------------------------------- /examples/scroll-cnode/vuet/topic-detail.js: -------------------------------------------------------------------------------- 1 | export default { 2 | routeWatch: 'params.id', // 定义页面的更新规则 3 | data () { 4 | return { 5 | id: null, 6 | author_id: null, 7 | tab: null, 8 | content: null, 9 | title: null, 10 | last_reply_at: null, 11 | good: false, 12 | top: false, 13 | reply_count: 0, 14 | visit_count: 0, 15 | create_at: null, 16 | author: { 17 | loginname: null, 18 | avatar_url: null 19 | }, 20 | replies: [], 21 | is_collect: false 22 | } 23 | }, 24 | async fetch () { 25 | const route = this.vuet.app.$route 26 | const { data } = await window.fetch(`https://cnodejs.org/api/v1/topic/${route.params.id}`).then(response => response.json()) 27 | this.state = data 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/scroll-cnode/vuet/topic-list.js: -------------------------------------------------------------------------------- 1 | export default { 2 | routeWatch: 'query', // 定义页面的更新规则 3 | data () { 4 | return { 5 | list: [], 6 | tabs: [ 7 | { 8 | label: '全部', 9 | value: 'all' 10 | }, 11 | { 12 | label: '精华', 13 | value: 'good' 14 | }, 15 | { 16 | label: '分享', 17 | value: 'share' 18 | }, 19 | { 20 | label: '问答', 21 | value: 'ask' 22 | }, 23 | { 24 | label: '招聘', 25 | value: 'job' 26 | } 27 | ] 28 | } 29 | }, 30 | route: { 31 | watch: 'query', 32 | once: false 33 | }, 34 | async fetch () { 35 | const { tab = '' } = this.app.$route.query 36 | const { data } = await window.fetch(`https://cnodejs.org/api/v1/topics?mdrender=false&tab=${tab}&limit=200`).then(response => response.json()) 37 | this.list = data 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/scroll-cnode/vuet/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | import VuetScroll from 'vuet-scroll' 4 | import VuetRoute from 'vuet-route' 5 | import topicList from './topic-list' 6 | import topicDetail from './topic-detail' 7 | 8 | Vue 9 | .use(Vuet) 10 | .use(VuetScroll) 11 | Vuet 12 | .rule('route', VuetRoute) 13 | 14 | export default new Vuet({ 15 | modules: { 16 | topic: { 17 | modules: { 18 | list: topicList, 19 | detail: topicDetail 20 | } 21 | } 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /examples/scroll-route/Detail.vue: -------------------------------------------------------------------------------- 1 | 17 | 47 | 66 | -------------------------------------------------------------------------------- /examples/scroll-route/List.vue: -------------------------------------------------------------------------------- 1 | 20 | 50 | 69 | -------------------------------------------------------------------------------- /examples/scroll-route/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet scroll-route 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/scroll-route/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import vuet from './vuet' 4 | import List from './List' 5 | import Detail from './Detail' 6 | 7 | Vue.use(VueRouter) 8 | 9 | const router = new VueRouter({ 10 | routes: [ 11 | { 12 | path: '/', 13 | name: 'list', 14 | component: List 15 | }, 16 | { 17 | path: '/:id', 18 | name: 'detail', 19 | component: Detail 20 | } 21 | ] 22 | }) 23 | 24 | Vue.prototype.$scrollTo = function scrollTo (el, scrolls) { 25 | if ('scrollTop' in el && el !== window) { 26 | el.scrollLeft = scrolls.x 27 | el.scrollTop = scrolls.y 28 | } else { 29 | el.scrollTo(scrolls.x, scrolls.y) 30 | } 31 | } 32 | 33 | export default new Vue({ 34 | el: '#app', 35 | vuet, 36 | router, 37 | render (h) { 38 | return h('router-view') 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /examples/scroll-route/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | import VuetScroll from 'vuet-scroll' 4 | import VuetRoute from 'vuet-route' 5 | 6 | Vue 7 | .use(Vuet) 8 | .use(VuetScroll) 9 | Vuet 10 | .rule('route', VuetRoute) 11 | 12 | export default new Vuet({ 13 | modules: { 14 | topic: { 15 | modules: { 16 | list: { 17 | data () { 18 | return {} 19 | }, 20 | async fetch () { 21 | return {} 22 | }, 23 | route: { 24 | watch: 'query' 25 | } 26 | }, 27 | detail: { 28 | data () { 29 | return {} 30 | }, 31 | async fetch () { 32 | return {} 33 | }, 34 | route: { 35 | watch: 'params.id' 36 | } 37 | } 38 | } 39 | } 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /examples/scroll-self/App.vue: -------------------------------------------------------------------------------- 1 | 15 | 34 | 49 | 50 | -------------------------------------------------------------------------------- /examples/scroll-self/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet scroll-self 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/scroll-self/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import vuet from './vuet' 4 | 5 | export default new Vue({ 6 | el: '#app', 7 | vuet, 8 | render (h) { 9 | return h(App) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/scroll-self/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | import VuetScroll from 'vuet-scroll' 4 | 5 | Vue 6 | .use(Vuet) 7 | .use(VuetScroll) 8 | 9 | export default new Vuet({ 10 | modules: { 11 | test: { 12 | data () { 13 | return { 14 | active: 'view-1', 15 | scrolls: { 16 | 'view-1': { x: 50, y: 60 }, 17 | 'view-2': { x: 280, y: 300 }, 18 | 'view-3': { x: 0, y: 0 } 19 | } 20 | } 21 | } 22 | } 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /examples/scroll-sync/App.vue: -------------------------------------------------------------------------------- 1 | 41 | 50 | -------------------------------------------------------------------------------- /examples/scroll-sync/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet scroll-sync 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/scroll-sync/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import vuet from './vuet' 4 | 5 | export default new Vue({ 6 | el: '#app', 7 | vuet, 8 | render (h) { 9 | return h(App) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/scroll-sync/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | import VuetScroll from 'vuet-scroll' 4 | 5 | Vue 6 | .use(Vuet) 7 | .use(VuetScroll) 8 | 9 | export default new Vuet({ 10 | modules: { 11 | test: { 12 | data () { 13 | return { 14 | windowScrolls: { 15 | x: 200, 16 | y: 300 17 | }, 18 | areaScrolls: { 19 | x: 100, 20 | y: 500 21 | } 22 | } 23 | }, 24 | windowTo () { 25 | this.windowScrolls.x = 100 26 | this.windowScrolls.y = 200 27 | }, 28 | areaTo () { 29 | this.areaScrolls.x = 200 30 | this.areaScrolls.y = 800 31 | } 32 | } 33 | } 34 | }) 35 | -------------------------------------------------------------------------------- /examples/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs') 3 | const webpack = require('webpack') 4 | const express = require('express') 5 | const webpackConfig = require('./webpack.config') 6 | const rewrite = require('express-urlrewrite') 7 | 8 | const app = express() 9 | const compiler = webpack(webpackConfig) 10 | 11 | const devMiddleware = require('webpack-dev-middleware')(compiler, { 12 | publicPath: webpackConfig.output.publicPath, 13 | stats: 'minimal' 14 | }) 15 | 16 | app.use(devMiddleware) 17 | 18 | fs.readdirSync(__dirname).forEach(file => { 19 | if (fs.statSync(path.join(__dirname, file)).isDirectory()) { 20 | app.use(rewrite('/' + file + '/*', '/' + file + '/index.html')) 21 | } 22 | }) 23 | 24 | app.use(express.static(__dirname)) 25 | 26 | module.exports = app.listen(3000, (err) => { 27 | if (err) return console.log(err) 28 | console.log('http://localhost:3000/') 29 | }) 30 | -------------------------------------------------------------------------------- /examples/store/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet store 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/store/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet, { mapModules, mapRules } from 'vuet' 3 | import VuetStore from 'vuet-store' 4 | 5 | Vue.use(Vuet) 6 | Vuet.rule('store', VuetStore) 7 | 8 | const vuet = new Vuet() 9 | vuet.addModules('test', { 10 | data () { 11 | return { 12 | count: 0 13 | } 14 | }, 15 | fetch () { 16 | this.count = 1000 17 | }, 18 | plus () { 19 | this.count++ 20 | }, 21 | reduce () { 22 | this.count-- 23 | } 24 | }) 25 | 26 | const App = { 27 | mixins: [ 28 | mapModules({ 29 | test: 'test' // { 别名: '模块路径' } 30 | }), 31 | mapRules({ 32 | store: [{ path: 'test' }], // { 规则: ['模块路径'] } 33 | once: [{ path: 'test' }] 34 | }) 35 | ], 36 | template: ` 37 |
38 |
{{ test.count }}
39 | 40 | 41 | 42 | 43 |
44 | ` 45 | } 46 | 47 | export default new Vue({ 48 | el: '#app', 49 | vuet, 50 | render (h) { 51 | return h(App) 52 | } 53 | }) 54 | -------------------------------------------------------------------------------- /examples/temp/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 26 | -------------------------------------------------------------------------------- /examples/temp/OutputContent.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /examples/temp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet temp 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/temp/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import vuet from './vuet' 4 | 5 | export default new Vue({ 6 | el: '#app', 7 | vuet, 8 | render (h) { 9 | return h(App) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/temp/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | 4 | Vue.use(Vuet) 5 | 6 | let fetchCount = 0 7 | 8 | const vuet = new Vuet() 9 | 10 | vuet.addModules('test', { 11 | data () { 12 | return { 13 | count: 0, 14 | fetchCount: 0 15 | } 16 | }, 17 | fetch () { 18 | this.count++ 19 | this.fetchCount = ++fetchCount 20 | } 21 | }) 22 | 23 | export default vuet 24 | -------------------------------------------------------------------------------- /examples/v-model/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 27 | -------------------------------------------------------------------------------- /examples/v-model/InputContent.vue: -------------------------------------------------------------------------------- 1 | 7 | 16 | -------------------------------------------------------------------------------- /examples/v-model/OutputContent.vue: -------------------------------------------------------------------------------- 1 | 4 | 13 | -------------------------------------------------------------------------------- /examples/v-model/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vuet v-model 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/v-model/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import vuet from './vuet' 4 | 5 | export default new Vue({ 6 | el: '#app', 7 | vuet, 8 | render (h) { 9 | return h(App) 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /examples/v-model/vuet.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuet from 'vuet' 3 | 4 | Vue.use(Vuet) 5 | 6 | export default new Vuet({ 7 | modules: { 8 | test: { 9 | data () { 10 | return { 11 | keyname: '' 12 | } 13 | } 14 | } 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /examples/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs') 3 | const webpack = require('webpack') 4 | 5 | module.exports = { 6 | entry: fs.readdirSync(__dirname).reduce((entries, dir) => { 7 | const fullDir = path.join(__dirname, dir) 8 | const entry = path.join(fullDir, 'main.js') 9 | if (fs.statSync(fullDir).isDirectory() && fs.existsSync(entry)) { 10 | entries[dir] = ['babel-polyfill', 'whatwg-fetch', entry] 11 | } 12 | return entries 13 | }, {}), 14 | output: { 15 | filename: 'js/[name].js', 16 | path: path.join(__dirname, '__build__'), 17 | publicPath: '/__build__/' 18 | }, 19 | module: { 20 | rules: [ 21 | { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }, 22 | { test: /\.vue$/, loader: 'vue-loader' } 23 | ] 24 | }, 25 | resolve: { 26 | alias: { 27 | 'vue': 'vue/dist/vue.common.js', 28 | 'vue-router': 'vue-router/dist/vue-router.common.js', 29 | 'vuet': path.join(__dirname, '..', 'src/'), 30 | 'vuet-scroll': path.join(__dirname, '..', 'packages/vuet-scroll/src/index'), 31 | 'vuet-route': path.join(__dirname, '..', 'packages/vuet-route/src/index'), 32 | 'vuet-store': path.join(__dirname, '..', 'packages/vuet-store/src/index') 33 | }, 34 | extensions: ['.js', '.vue', '.json'] 35 | }, 36 | plugins: [ 37 | new webpack.optimize.CommonsChunkPlugin({ 38 | name: 'common', 39 | filename: 'js/common.js' 40 | }), 41 | new webpack.DefinePlugin({ 42 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') 43 | }) 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /images/vuet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lzxb/vuet/da2d2e991f54cc18729491f8e43b90ef45b0ea2c/images/vuet.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuet", 3 | "version": "1.0.3", 4 | "description": "Vue state management plugin", 5 | "main": "dist/vuet.js", 6 | "scripts": { 7 | "dev": "node examples/server", 8 | "watch": "npm-watch", 9 | "watch:test": "clear && npm run lint && npm run unit && npm run build", 10 | "build": "node build/build.js", 11 | "lint": "eslint ./ --ext .vue --ext .js --fix", 12 | "unit": "nyc ava test/unit --verbose", 13 | "test": "npm run lint && npm run unit && npm run e2e && npm run build", 14 | "e2e": "testcafe all test/e2e/**.js --app 'node examples/server.js'", 15 | "coverage": "nyc report --reporter=text-lcov | coveralls" 16 | }, 17 | "files": [ 18 | "dist/", 19 | "src/", 20 | "images" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/medatc/vuet.git" 25 | }, 26 | "homepage": "https://github.com/medatc/vuet#readme", 27 | "bugs": { 28 | "url": "https://github.com/medatc/vuet/issues" 29 | }, 30 | "keywords": [ 31 | "vue", 32 | "vue2", 33 | "vue-router", 34 | "vuex", 35 | "vuet", 36 | "vuex" 37 | ], 38 | "author": "medatc", 39 | "license": "MIT", 40 | "devDependencies": { 41 | "ava": "^0.20.0", 42 | "babel-eslint": "^7.2.3", 43 | "babel-loader": "^7.0.0", 44 | "babel-plugin-transform-object-assign": "^6.22.0", 45 | "babel-polyfill": "^6.23.0", 46 | "babel-preset-es2015-rollup": "^3.0.0", 47 | "babel-preset-stage-0": "^6.24.1", 48 | "babel-register": "^6.24.1", 49 | "coveralls": "^2.13.1", 50 | "css-loader": "^0.28.4", 51 | "eslint": "^4.2.0", 52 | "eslint-config-standard": "^10.2.1", 53 | "eslint-plugin-html": "^3.0.0", 54 | "eslint-plugin-import": "^2.2.0", 55 | "eslint-plugin-node": "^4.2.2", 56 | "eslint-plugin-promise": "^3.5.0", 57 | "eslint-plugin-standard": "^3.0.1", 58 | "eslint-plugin-testcafe": "^0.2.1", 59 | "express": "^4.15.3", 60 | "express-urlrewrite": "^1.2.0", 61 | "npm-watch": "^0.2.0", 62 | "nyc": "^11.0.3", 63 | "rollup": "^0.41.6", 64 | "rollup-plugin-babel": "^2.7.1", 65 | "rollup-plugin-replace": "^1.1.1", 66 | "rollup-plugin-uglify": "^1.0.2", 67 | "testcafe": "^0.16.2", 68 | "vue": "^2.3.4", 69 | "vue-loader": "^12.1.1", 70 | "vue-router": "^2.5.3", 71 | "vue-template-compiler": "^2.3.4", 72 | "webpack": "^3.0.0", 73 | "webpack-dev-middleware": "^1.10.2", 74 | "whatwg-fetch": "^2.0.3" 75 | }, 76 | "ava": { 77 | "require": [ 78 | "babel-register" 79 | ] 80 | }, 81 | "watch": { 82 | "watch:test": { 83 | "patterns": "./", 84 | "ignore": [ 85 | "dist", 86 | ".nyc_output", 87 | "coverage" 88 | ], 89 | "extensions": "js,html,vue" 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /packages/vuet-route/README.md: -------------------------------------------------------------------------------- 1 | ## vuet-route 2 | [![Coverage Status](https://coveralls.io/repos/github/medatc/vuet/badge.svg?branch=dev)](https://coveralls.io/github/medatc/vuet?branch=dev) 3 | [![Build Status](https://travis-ci.org/medatc/vuet.svg?branch=dev)](https://travis-ci.org/medatc/vuet) 4 | [![npm](https://img.shields.io/npm/v/vuet-route.svg)](https://www.npmjs.com/package/vuet-route) 5 | [![npm](https://img.shields.io/npm/dm/vuet-route.svg)](https://www.npmjs.com/package/vuet-route) 6 | [![npm](https://img.shields.io/npm/dt/vuet-route.svg)](https://www.npmjs.com/package/vuet-route) 7 | 8 | 9 | ## 它是做什么的? 10 | 它能在路由变化时,自动获取数据,重置页面状态 11 | 12 | 13 | ## 安装 14 | ```bash 15 | npm install --save vuet-route 16 | ``` 17 | 18 | 19 | ## 使用 20 | ```javascript 21 | import Vuet from 'vuet' 22 | import VuetRoute from 'vuet-route' 23 | 24 | Vuet.rule('route', VuetRoute) // 注意:规则的注册必须在所有组件执行之前 25 | 26 | const vuet = new Vuet({ 27 | modules: { 28 | test: { 29 | data () { 30 | return { 31 | list: [] 32 | } 33 | }, 34 | route: { 35 | once: true, // 第一次加载成功后,是否还请求数据,true请求数据,false不请求数据,默认为true 36 | watch: ['fullPath'] // 监听路由变化,重置页面状态,默认为fullPath 37 | }, 38 | fetch () { 39 | this.app.$route // 取得路由对象,你可以在这里发起http请求 40 | setInterval(() => { 41 | this.list = [...] 42 | }, 1000) 43 | } 44 | } 45 | } 46 | }) 47 | ``` 48 | 49 | 50 | ## 上拉加载例子 51 | ```javascript 52 | import Vuet from 'vuet' 53 | import VuetRoute from 'vuet-route' 54 | 55 | Vuet.rule('route', VuetRoute) // 注意:规则的注册必须在所有组件执行之前 56 | 57 | const vuet = new Vuet({ 58 | modules: { 59 | test: { 60 | data () { 61 | return { 62 | page: 1, 63 | list: [] 64 | } 65 | }, 66 | route: { 67 | once: true, // 第一次加载成功后,是否还请求数据,true不请求数据,false请求数据,默认为false 68 | watch: ['fullPath'], // 监听路由变化,重置页面状态,默认为fullPath 69 | }, 70 | fetch () { 71 | this.app.$route // 取得路由对象,你可以在这里发起http请求 72 | setInterval(() => { 73 | this.list = [...this.list, ...[this.page]] 74 | this.page++ 75 | }, 1000) 76 | } 77 | } 78 | } 79 | }) 80 | // 在组件中,上拉加载事件触发时,调用下面的方法即可 81 | // this.$vuet.getModule('cleartest').route.fetch() 82 | ``` -------------------------------------------------------------------------------- /packages/vuet-route/dist/vuet-route.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (factory((global.VuetRoute = global.VuetRoute || {}))); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 8 | return typeof obj; 9 | } : function (obj) { 10 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 11 | }; 12 | 13 | var util = { 14 | isObject: function isObject(obj) { 15 | return !!obj && Object.prototype.toString.call(obj) === '[object Object]'; 16 | }, 17 | getArgMerge: function getArgMerge() { 18 | var opt = {}; 19 | var args = arguments; 20 | if (typeof args[0] === 'string') { 21 | opt[args[0]] = args.length > 1 ? args[1] : args[0]; 22 | } else if (args[0] && util.isObject(args[0])) { 23 | opt = args[0]; 24 | } 25 | return opt; 26 | }, 27 | isPromise: function isPromise(obj) { 28 | return ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function'; 29 | } 30 | }; 31 | 32 | var _Vue = void 0; 33 | 34 | var NAME$1 = 'vuet-route'; 35 | 36 | var debug = { 37 | error: function error(msg) { 38 | throw new Error('[' + NAME$1 + '] ' + msg); 39 | }, 40 | warn: function warn(msg) { 41 | { 42 | typeof console !== 'undefined' && console.warn('[' + NAME$1 + '] ' + msg); 43 | } 44 | }, 45 | assertModule: function assertModule(vuet, path) { 46 | if (path in vuet.modules) { 47 | return; 48 | } 49 | this.error('The \'' + path + '\' module does not exist'); 50 | }, 51 | assertVue: function assertVue() { 52 | if (!_Vue) { 53 | this.error('must call Vue.use(Vuet) before creating a store instance'); 54 | } 55 | }, 56 | assertFetch: function assertFetch(vuet, path) { 57 | this.assertModule(vuet, path); 58 | if (typeof vuet.getModule(path).fetch !== 'function') { 59 | this.error('\'' + path + '\' module \'fetch\' must be the function type'); 60 | } 61 | } 62 | }; 63 | 64 | var NAME = '__route__'; 65 | 66 | function isWatch(vuet, path, route) { 67 | var vtm = vuet.getModule(path); 68 | var watch = ['fullPath']; 69 | if (vtm.route.watch) { 70 | watch = vtm.route.watch; 71 | } 72 | watch = Array.isArray(watch) ? watch : [watch]; 73 | var oldWatch = vuet[NAME][path]; // old 74 | vuet[NAME][path] = []; // new 75 | watch.forEach(function (k) { 76 | var data = route; 77 | k.split('.').forEach(function (chlidKey) { 78 | data = data[chlidKey]; 79 | }); 80 | vuet[NAME][path].push(JSON.stringify(data)); 81 | }); 82 | return oldWatch.join() !== vuet[NAME][path].join(); 83 | } 84 | 85 | var index = { 86 | init: function init(vuet) { 87 | vuet[NAME] = {}; 88 | }, 89 | addModule: function addModule(vuet, path) { 90 | vuet[NAME][path] = []; 91 | if (!util.isObject(vuet.getModule(path).route)) { 92 | vuet.getModule(path).route = {}; 93 | } 94 | }, 95 | rule: function rule(_ref) { 96 | var path = _ref.path; 97 | 98 | return { 99 | beforeCreate: function beforeCreate() { 100 | debug.assertFetch(this.$vuet, path); 101 | if (!this.$route) { 102 | debug.error('The \'vue-router\' module is not installed'); 103 | } 104 | var vtm = this.$vuet.getModule(path); 105 | if (!util.isObject(vtm.state)) { 106 | debug.error('\'' + path + '\' module state must be the object type'); 107 | } 108 | if (isWatch(this.$vuet, path, this.$route)) { 109 | vtm.reset(); 110 | vtm.state.__routeLoaded__ = true; 111 | return vtm.fetch(vtm); 112 | } 113 | if (vtm.route.once !== true || !vtm.state.__routeLoaded__) { 114 | // default 115 | vtm.state.__routeLoaded__ = true; 116 | return vtm.fetch(vtm); 117 | } 118 | }, 119 | 120 | watch: { 121 | $route: { 122 | deep: true, 123 | handler: function handler(to, from) { 124 | var vtm = this.$vuet.getModule(path); 125 | if (isWatch(this.$vuet, path, to)) { 126 | vtm.reset(); 127 | vtm.state.__routeLoaded__ = true; 128 | vtm.fetch(vtm); 129 | } 130 | } 131 | } 132 | } 133 | }; 134 | } 135 | }; 136 | 137 | exports['default'] = index; 138 | 139 | Object.defineProperty(exports, '__esModule', { value: true }); 140 | 141 | }))); 142 | //# sourceMappingURL=vuet-route.js.map 143 | -------------------------------------------------------------------------------- /packages/vuet-route/dist/vuet-route.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vuet-route.js","sources":["../../../src/util.js","../../../src/vuet-static.js","../../../src/debug.js","../src/index.js"],"sourcesContent":["const util = {\n isObject (obj) {\n return !!obj && Object.prototype.toString.call(obj) === '[object Object]'\n },\n getArgMerge () {\n let opt = {}\n const args = arguments\n if (typeof args[0] === 'string') {\n opt[args[0]] = args.length > 1 ? args[1] : args[0]\n } else if (args[0] && util.isObject(args[0])) {\n opt = args[0]\n }\n return opt\n },\n isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function'\n }\n}\n\nexport default util\n","import debug from './debug'\nimport util from './util'\n\nexport let _Vue\n\nexport default function (Vuet) {\n Object.assign(Vuet, {\n installed: false,\n options: {\n rules: {},\n module: {\n reset () {\n this.state = this.data()\n return this\n }\n }\n },\n install (Vue) {\n if (this.installed) return this\n this.installed = true\n _Vue = Vue\n Object.defineProperty(Vue.prototype, '$vuet', {\n get () { return this.$root._vuet }\n })\n Vue.mixin({\n beforeCreate () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet = this.$options.vuet\n this._vuet._init(this)\n }\n }\n },\n destroyed () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet.destroy(this)\n }\n }\n }\n })\n return this\n },\n mapModules (opts) {\n const mixins = Object.keys(opts).map(alias => {\n const path = opts[alias]\n return {\n computed: {\n [alias]: {\n get () {\n debug.assertModule(this.$vuet, path)\n return this.$vuet.getModule(path)\n },\n set (val) {\n debug.error(`The'${path}'module is not allowed to assign`)\n }\n }\n }\n }\n })\n return {\n mixins\n }\n },\n mapRules () {\n const opts = util.getArgMerge.apply(null, arguments)\n const vueRules = []\n const addRule = (ruleName, any) => {\n const rules = Vuet.options.rules[ruleName]\n if (!util.isObject(rules)) debug.error(`The'${ruleName}'rule does not exist. Please make sure that it executes 'Vuet.rule('${ruleName}', opts)' before all components`)\n if (typeof any === 'string') {\n vueRules.push(rules.rule({ path: any }))\n } else {\n vueRules.push(rules.rule(any))\n }\n }\n Object.keys(opts).forEach(ruleName => {\n const any = opts[ruleName]\n if (Array.isArray(any)) {\n return any.forEach(item => {\n addRule(ruleName, item)\n })\n }\n addRule(ruleName, any)\n })\n return {\n mixins: vueRules\n }\n },\n rule () {\n Vuet.options.rules[arguments[0]] = arguments[1]\n if (typeof arguments[1].install === 'function') {\n arguments[1].install(Vuet, _Vue)\n }\n return this\n },\n callRuleHook (hook, ...arg) {\n Object.keys(Vuet.options.rules).forEach(k => {\n if (typeof Vuet.options.rules[k][hook] === 'function') {\n Vuet.options.rules[k][hook].apply(undefined, arg)\n }\n })\n }\n })\n}\n","import { _Vue } from './vuet-static'\n\nconst NAME = '__name__'\n\nexport default {\n error (msg) {\n throw new Error(`[${NAME}] ${msg}`)\n },\n warn (msg) {\n if (process.env.NODE_ENV !== 'production') {\n typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`)\n }\n },\n assertModule (vuet, path) {\n if (path in vuet.modules) {\n return\n }\n this.error(`The '${path}' module does not exist`)\n },\n assertVue () {\n if (!_Vue) {\n this.error('must call Vue.use(Vuet) before creating a store instance')\n }\n },\n assertFetch (vuet, path) {\n this.assertModule(vuet, path)\n if (typeof vuet.getModule(path).fetch !== 'function') {\n this.error(`'${path}' module 'fetch' must be the function type`)\n }\n }\n}\n","import debug from '../../../src/debug'\nimport util from '../../../src/util'\n\nconst NAME = '__route__'\n\nfunction isWatch (vuet, path, route) {\n const vtm = vuet.getModule(path)\n let watch = ['fullPath']\n if (vtm.route.watch) {\n watch = vtm.route.watch\n }\n watch = Array.isArray(watch) ? watch : [watch]\n const oldWatch = vuet[NAME][path] // old\n vuet[NAME][path] = [] // new\n watch.forEach(k => {\n let data = route\n k.split('.').forEach(chlidKey => {\n data = data[chlidKey]\n })\n vuet[NAME][path].push(JSON.stringify(data))\n })\n return oldWatch.join() !== vuet[NAME][path].join()\n}\n\nexport default {\n init (vuet) {\n vuet[NAME] = {}\n },\n addModule (vuet, path) {\n vuet[NAME][path] = []\n if (!util.isObject(vuet.getModule(path).route)) {\n vuet.getModule(path).route = {}\n }\n },\n rule ({ path }) {\n return {\n beforeCreate () {\n debug.assertFetch(this.$vuet, path)\n if (!this.$route) {\n debug.error(`The 'vue-router' module is not installed`)\n }\n const vtm = this.$vuet.getModule(path)\n if (!util.isObject(vtm.state)) {\n debug.error(`'${path}' module state must be the object type`)\n }\n if (isWatch(this.$vuet, path, this.$route)) {\n vtm.reset()\n vtm.state.__routeLoaded__ = true\n return vtm.fetch(vtm)\n }\n if (vtm.route.once !== true || !vtm.state.__routeLoaded__) { // default\n vtm.state.__routeLoaded__ = true\n return vtm.fetch(vtm)\n }\n },\n watch: {\n $route: {\n deep: true,\n handler (to, from) {\n const vtm = this.$vuet.getModule(path)\n if (isWatch(this.$vuet, path, to)) {\n vtm.reset()\n vtm.state.__routeLoaded__ = true\n vtm.fetch(vtm)\n }\n }\n }\n }\n }\n }\n}\n"],"names":["util","obj","Object","prototype","toString","call","opt","args","arguments","length","isObject","then","_Vue","NAME","msg","Error","process","console","warn","vuet","path","modules","error","assertModule","getModule","fetch","isWatch","route","vtm","watch","Array","isArray","oldWatch","forEach","data","split","chlidKey","push","JSON","stringify","join","assertFetch","$vuet","$route","state","reset","__routeLoaded__","once","to","from"],"mappings":"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"} -------------------------------------------------------------------------------- /packages/vuet-route/dist/vuet-route.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.VuetRoute=t.VuetRoute||{})}(this,function(t){"use strict";function e(t,e,o){var r=t.getModule(e),u=["fullPath"];r.route.watch&&(u=r.route.watch),u=Array.isArray(u)?u:[u];var i=t[n][e];return t[n][e]=[],u.forEach(function(r){var u=o;r.split(".").forEach(function(t){u=u[t]}),t[n][e].push(JSON.stringify(u))}),i.join()!==t[n][e].join()}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r={isObject:function(t){return!!t&&"[object Object]"===Object.prototype.toString.call(t)},getArgMerge:function(){var t={},e=arguments;return"string"==typeof e[0]?t[e[0]]=e.length>1?e[1]:e[0]:e[0]&&r.isObject(e[0])&&(t=e[0]),t},isPromise:function(t){return("object"===(void 0===t?"undefined":o(t))||"function"==typeof t)&&!!t&&"function"==typeof t.then}},u={error:function(t){throw new Error("[vuet-route] "+t)},warn:function(t){},assertModule:function(t,e){e in t.modules||this.error("The '"+e+"' module does not exist")},assertVue:function(){this.error("must call Vue.use(Vuet) before creating a store instance")},assertFetch:function(t,e){this.assertModule(t,e),"function"!=typeof t.getModule(e).fetch&&this.error("'"+e+"' module 'fetch' must be the function type")}},n="__route__",i={init:function(t){t[n]={}},addModule:function(t,e){t[n][e]=[],r.isObject(t.getModule(e).route)||(t.getModule(e).route={})},rule:function(t){var o=t.path;return{beforeCreate:function(){u.assertFetch(this.$vuet,o),this.$route||u.error("The 'vue-router' module is not installed");var t=this.$vuet.getModule(o);return r.isObject(t.state)||u.error("'"+o+"' module state must be the object type"),e(this.$vuet,o,this.$route)?(t.reset(),t.state.__routeLoaded__=!0,t.fetch(t)):!0===t.route.once&&t.state.__routeLoaded__?void 0:(t.state.__routeLoaded__=!0,t.fetch(t))},watch:{$route:{deep:!0,handler:function(t,r){var u=this.$vuet.getModule(o);e(this.$vuet,o,t)&&(u.reset(),u.state.__routeLoaded__=!0,u.fetch(u))}}}}}};t.default=i,Object.defineProperty(t,"__esModule",{value:!0})}); 2 | //# sourceMappingURL=vuet-route.min.js.map 3 | -------------------------------------------------------------------------------- /packages/vuet-route/dist/vuet-route.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vuet-route.min.js","sources":["../src/index.js","../../../src/util.js","../../../src/debug.js"],"sourcesContent":["import debug from '../../../src/debug'\nimport util from '../../../src/util'\n\nconst NAME = '__route__'\n\nfunction isWatch (vuet, path, route) {\n const vtm = vuet.getModule(path)\n let watch = ['fullPath']\n if (vtm.route.watch) {\n watch = vtm.route.watch\n }\n watch = Array.isArray(watch) ? watch : [watch]\n const oldWatch = vuet[NAME][path] // old\n vuet[NAME][path] = [] // new\n watch.forEach(k => {\n let data = route\n k.split('.').forEach(chlidKey => {\n data = data[chlidKey]\n })\n vuet[NAME][path].push(JSON.stringify(data))\n })\n return oldWatch.join() !== vuet[NAME][path].join()\n}\n\nexport default {\n init (vuet) {\n vuet[NAME] = {}\n },\n addModule (vuet, path) {\n vuet[NAME][path] = []\n if (!util.isObject(vuet.getModule(path).route)) {\n vuet.getModule(path).route = {}\n }\n },\n rule ({ path }) {\n return {\n beforeCreate () {\n debug.assertFetch(this.$vuet, path)\n if (!this.$route) {\n debug.error(`The 'vue-router' module is not installed`)\n }\n const vtm = this.$vuet.getModule(path)\n if (!util.isObject(vtm.state)) {\n debug.error(`'${path}' module state must be the object type`)\n }\n if (isWatch(this.$vuet, path, this.$route)) {\n vtm.reset()\n vtm.state.__routeLoaded__ = true\n return vtm.fetch(vtm)\n }\n if (vtm.route.once !== true || !vtm.state.__routeLoaded__) { // default\n vtm.state.__routeLoaded__ = true\n return vtm.fetch(vtm)\n }\n },\n watch: {\n $route: {\n deep: true,\n handler (to, from) {\n const vtm = this.$vuet.getModule(path)\n if (isWatch(this.$vuet, path, to)) {\n vtm.reset()\n vtm.state.__routeLoaded__ = true\n vtm.fetch(vtm)\n }\n }\n }\n }\n }\n }\n}\n","const util = {\n isObject (obj) {\n return !!obj && Object.prototype.toString.call(obj) === '[object Object]'\n },\n getArgMerge () {\n let opt = {}\n const args = arguments\n if (typeof args[0] === 'string') {\n opt[args[0]] = args.length > 1 ? args[1] : args[0]\n } else if (args[0] && util.isObject(args[0])) {\n opt = args[0]\n }\n return opt\n },\n isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function'\n }\n}\n\nexport default util\n","import { _Vue } from './vuet-static'\n\nconst NAME = '__name__'\n\nexport default {\n error (msg) {\n throw new Error(`[${NAME}] ${msg}`)\n },\n warn (msg) {\n if (process.env.NODE_ENV !== 'production') {\n typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`)\n }\n },\n assertModule (vuet, path) {\n if (path in vuet.modules) {\n return\n }\n this.error(`The '${path}' module does not exist`)\n },\n assertVue () {\n if (!_Vue) {\n this.error('must call Vue.use(Vuet) before creating a store instance')\n }\n },\n assertFetch (vuet, path) {\n this.assertModule(vuet, path)\n if (typeof vuet.getModule(path).fetch !== 'function') {\n this.error(`'${path}' module 'fetch' must be the function type`)\n }\n }\n}\n"],"names":["isWatch","vuet","path","route","vtm","getModule","watch","Array","isArray","oldWatch","NAME","forEach","data","split","chlidKey","push","JSON","stringify","join","util","obj","Object","prototype","toString","call","opt","args","arguments","length","isObject","then","msg","Error","modules","error","assertModule","fetch","assertFetch","this","$vuet","$route","state","reset","__routeLoaded__","once","to","from"],"mappings":"wMAKA,SAASA,GAASC,EAAMC,EAAMC,MACtBC,GAAMH,EAAKI,UAAUH,GACvBI,GAAS,WACTF,GAAID,MAAMG,UACJF,EAAID,MAAMG,SAEZC,MAAMC,QAAQF,GAASA,GAASA,MAClCG,GAAWR,EAAKS,GAAMR,YACvBQ,GAAMR,QACLS,QAAQ,eACRC,GAAOT,IACTU,MAAM,KAAKF,QAAQ,cACZC,EAAKE,OAETJ,GAAMR,GAAMa,KAAKC,KAAKC,UAAUL,MAEhCH,EAASS,SAAWjB,EAAKS,GAAMR,GAAMgB,uNCrBxCC,qBACMC,WACCA,GAA+C,oBAAxCC,OAAOC,UAAUC,SAASC,KAAKJ,8BAG3CK,MACEC,EAAOC,gBACU,gBAAZD,GAAK,KACVA,EAAK,IAAMA,EAAKE,OAAS,EAAIF,EAAK,GAAKA,EAAK,GACvCA,EAAK,IAAMP,EAAKU,SAASH,EAAK,QACjCA,EAAK,IAEND,sBAEEL,UACc,qBAARA,gBAAAA,KAAmC,kBAARA,OAAyBA,GAA2B,kBAAbA,GAAIU,yBCVhFC,QACC,IAAIC,uBAAmBD,kBAEzBA,2BAKQ9B,EAAMC,GACdA,IAAQD,GAAKgC,cAGZC,cAAchC,wDAIZgC,MAAM,kFAGFjC,EAAMC,QACZiC,aAAalC,EAAMC,GACkB,kBAA/BD,GAAKI,UAAUH,GAAMkC,YACzBF,UAAUhC,kDFxBfQ,EAAO,6BAsBLT,KACCS,0BAEIT,EAAMC,KACVQ,GAAMR,MACNiB,EAAKU,SAAS5B,EAAKI,UAAUH,GAAMC,WACjCE,UAAUH,GAAMC,+BAGjBD,KAAAA,sCAGImC,YAAYC,KAAKC,MAAOrC,GACzBoC,KAAKE,UACFN,qDAEF9B,GAAMkC,KAAKC,MAAMlC,UAAUH,SAC5BiB,GAAKU,SAASzB,EAAIqC,UACfP,UAAUhC,4CAEdF,EAAQsC,KAAKC,MAAOrC,EAAMoC,KAAKE,WAC7BE,UACAD,MAAME,iBAAkB,EACrBvC,EAAIgC,MAAMhC,KAEI,IAAnBA,EAAID,MAAMyC,MAAkBxC,EAAIqC,MAAME,0BACpCF,MAAME,iBAAkB,EACrBvC,EAAIgC,MAAMhC,0BAKX,mBACGyC,EAAIC,MACL1C,GAAMkC,KAAKC,MAAMlC,UAAUH,EAC7BF,GAAQsC,KAAKC,MAAOrC,EAAM2C,OACxBH,UACAD,MAAME,iBAAkB,IACxBP,MAAMhC"} -------------------------------------------------------------------------------- /packages/vuet-route/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuet-route", 3 | "version": "0.1.3", 4 | "description": "vuet route", 5 | "main": "dist/vuet-route.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "medatc", 10 | "license": "MIT", 11 | "files": [ 12 | "dist/", 13 | "src/" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/vuet-route/src/index.js: -------------------------------------------------------------------------------- 1 | import debug from '../../../src/debug' 2 | import util from '../../../src/util' 3 | 4 | const NAME = '__route__' 5 | 6 | function isWatch (vuet, path, route) { 7 | const vtm = vuet.getModule(path) 8 | let watch = ['fullPath'] 9 | if (vtm.route.watch) { 10 | watch = vtm.route.watch 11 | } 12 | watch = Array.isArray(watch) ? watch : [watch] 13 | const oldWatch = vuet[NAME][path] // old 14 | vuet[NAME][path] = [] // new 15 | watch.forEach(k => { 16 | let data = route 17 | k.split('.').forEach(chlidKey => { 18 | data = data[chlidKey] 19 | }) 20 | vuet[NAME][path].push(JSON.stringify(data)) 21 | }) 22 | return oldWatch.join() !== vuet[NAME][path].join() 23 | } 24 | 25 | export default { 26 | init (vuet) { 27 | vuet[NAME] = {} 28 | }, 29 | addModule (vuet, path) { 30 | vuet[NAME][path] = [] 31 | if (!util.isObject(vuet.getModule(path).route)) { 32 | vuet.getModule(path).route = {} 33 | } 34 | }, 35 | rule ({ path }) { 36 | return { 37 | beforeCreate () { 38 | debug.assertFetch(this.$vuet, path) 39 | if (!this.$route) { 40 | debug.error(`The 'vue-router' module is not installed`) 41 | } 42 | const vtm = this.$vuet.getModule(path) 43 | if (!util.isObject(vtm.state)) { 44 | debug.error(`'${path}' module state must be the object type`) 45 | } 46 | if (isWatch(this.$vuet, path, this.$route)) { 47 | vtm.reset() 48 | vtm.state.__routeLoaded__ = true 49 | return vtm.fetch(vtm) 50 | } 51 | if (vtm.route.once !== true || !vtm.state.__routeLoaded__) { // default 52 | vtm.state.__routeLoaded__ = true 53 | return vtm.fetch(vtm) 54 | } 55 | }, 56 | watch: { 57 | $route: { 58 | deep: true, 59 | handler (to, from) { 60 | const vtm = this.$vuet.getModule(path) 61 | if (isWatch(this.$vuet, path, to)) { 62 | vtm.reset() 63 | vtm.state.__routeLoaded__ = true 64 | vtm.fetch(vtm) 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /packages/vuet-scroll/README.md: -------------------------------------------------------------------------------- 1 | ## vuet-scroll 2 | [![Coverage Status](https://coveralls.io/repos/github/medatc/vuet/badge.svg?branch=dev)](https://coveralls.io/github/medatc/vuet?branch=dev) 3 | [![Build Status](https://travis-ci.org/medatc/vuet.svg?branch=dev)](https://travis-ci.org/medatc/vuet) 4 | [![npm](https://img.shields.io/npm/v/vuet-scroll.svg)](https://www.npmjs.com/package/vuet-scroll) 5 | [![npm](https://img.shields.io/npm/dm/vuet-scroll.svg)](https://www.npmjs.com/package/vuet-scroll) 6 | [![npm](https://img.shields.io/npm/dt/vuet-scroll.svg)](https://www.npmjs.com/package/vuet-scroll) 7 | 8 | 9 | ## 它是做什么的? 10 | 它可以将`window`和`元素内部`的滚动条记录在`Vuet`的模块中,如果没有传入绑定的对象,将会自动注入模块的`$scroll`对象中 11 | 12 | 13 | ## 安装 14 | ```bash 15 | npm install --save vuet-scroll 16 | ``` 17 | 18 | 19 | ## 使用 20 | ```javascript 21 | import Vue from 'vue' 22 | import Vuet from 'vuet' 23 | import VuetRoute from 'vuet-route' 24 | 25 | Vue.use(VuetScroll) 26 | 27 | const vuet = new Vuet({ 28 | // 选项 29 | }) 30 | 31 | const app = new App({ 32 | el: '#app', 33 | vuet 34 | }) 35 | 36 | ``` 37 | 安装成功后,会在Vue中注入`v-vuet-scroll`指令,注意,此指令必须配合`Vuet`使用才会有效 38 | ```html 39 | 40 |
41 | 42 |
43 | 44 |
45 | 46 |
47 | ``` -------------------------------------------------------------------------------- /packages/vuet-scroll/dist/vuet-scroll.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (factory((global.VuetScroll = global.VuetScroll || {}))); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 8 | return typeof obj; 9 | } : function (obj) { 10 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 11 | }; 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | var classCallCheck = function (instance, Constructor) { 24 | if (!(instance instanceof Constructor)) { 25 | throw new TypeError("Cannot call a class as a function"); 26 | } 27 | }; 28 | 29 | var createClass = function () { 30 | function defineProperties(target, props) { 31 | for (var i = 0; i < props.length; i++) { 32 | var descriptor = props[i]; 33 | descriptor.enumerable = descriptor.enumerable || false; 34 | descriptor.configurable = true; 35 | if ("value" in descriptor) descriptor.writable = true; 36 | Object.defineProperty(target, descriptor.key, descriptor); 37 | } 38 | } 39 | 40 | return function (Constructor, protoProps, staticProps) { 41 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 42 | if (staticProps) defineProperties(Constructor, staticProps); 43 | return Constructor; 44 | }; 45 | }(); 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | var _extends = Object.assign || function (target) { 54 | for (var i = 1; i < arguments.length; i++) { 55 | var source = arguments[i]; 56 | 57 | for (var key in source) { 58 | if (Object.prototype.hasOwnProperty.call(source, key)) { 59 | target[key] = source[key]; 60 | } 61 | } 62 | } 63 | 64 | return target; 65 | }; 66 | 67 | var util = { 68 | isObject: function isObject(obj) { 69 | return !!obj && Object.prototype.toString.call(obj) === '[object Object]'; 70 | }, 71 | getArgMerge: function getArgMerge() { 72 | var opt = {}; 73 | var args = arguments; 74 | if (typeof args[0] === 'string') { 75 | opt[args[0]] = args.length > 1 ? args[1] : args[0]; 76 | } else if (args[0] && util.isObject(args[0])) { 77 | opt = args[0]; 78 | } 79 | return opt; 80 | }, 81 | isPromise: function isPromise(obj) { 82 | return ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function'; 83 | } 84 | }; 85 | 86 | var _Vue$1 = void 0; 87 | 88 | var NAME = 'vuet-scroll'; 89 | 90 | var debug = { 91 | error: function error(msg) { 92 | throw new Error('[' + NAME + '] ' + msg); 93 | }, 94 | warn: function warn(msg) { 95 | { 96 | typeof console !== 'undefined' && console.warn('[' + NAME + '] ' + msg); 97 | } 98 | }, 99 | assertModule: function assertModule(vuet, path) { 100 | if (path in vuet.modules) { 101 | return; 102 | } 103 | this.error('The \'' + path + '\' module does not exist'); 104 | }, 105 | assertVue: function assertVue() { 106 | if (!_Vue$1) { 107 | this.error('must call Vue.use(Vuet) before creating a store instance'); 108 | } 109 | }, 110 | assertFetch: function assertFetch(vuet, path) { 111 | this.assertModule(vuet, path); 112 | if (typeof vuet.getModule(path).fetch !== 'function') { 113 | this.error('\'' + path + '\' module \'fetch\' must be the function type'); 114 | } 115 | } 116 | }; 117 | 118 | var _Vue = void 0; 119 | var _self = '__vuetScrollSelf__'; 120 | var _window = '__vuetScrollWindow__'; 121 | 122 | var VuetScroll = function () { 123 | function VuetScroll(opts) { 124 | classCallCheck(this, VuetScroll); 125 | 126 | this.timer = {}; 127 | this.setOption(opts); 128 | this.scrollTo(); 129 | this.subScroll(); 130 | } 131 | 132 | createClass(VuetScroll, [{ 133 | key: 'update', 134 | value: function update(opts) { 135 | var _this = this; 136 | 137 | this.setOption(opts); 138 | var key = 'timer-' + this.path + '-' + this.name; 139 | clearTimeout(this.timer[key]); 140 | this.timer[key] = setTimeout(function () { 141 | _this.scrollTo(); 142 | delete _this.timer[key]; 143 | }, 10); 144 | } 145 | }, { 146 | key: 'destroy', 147 | value: function destroy() { 148 | this.app.removeEventListener('scroll', this.subScrolling, false); 149 | } 150 | }, { 151 | key: 'setOption', 152 | value: function setOption(opt) { 153 | this.app = opt.app; 154 | this.path = opt.path; 155 | this.name = opt.name || ''; 156 | this.store = opt.store || { x: 0, y: 0 }; 157 | this.scrolls = opt.scrolls || createScroll(opt); 158 | function createScroll(opt) { 159 | if (!opt.store.$scroll) { 160 | _Vue.set(opt.store, '$scroll', {}); 161 | } 162 | if (!opt.store.$scroll[opt.name]) { 163 | _Vue.set(opt.store.$scroll, opt.name, { x: 0, y: 0 }); 164 | } 165 | 166 | return opt.store.$scroll[opt.name]; 167 | } 168 | } 169 | }, { 170 | key: 'scrollTo', 171 | value: function scrollTo() { 172 | var app = this.app, 173 | scrolls = this.scrolls; 174 | 175 | if ('scrollTop' in app && app !== window) { 176 | app.scrollLeft = scrolls.x; 177 | app.scrollTop = scrolls.y; 178 | } else { 179 | app.scrollTo(scrolls.x, scrolls.y); 180 | } 181 | } 182 | }, { 183 | key: 'subScroll', 184 | value: function subScroll() { 185 | var _this2 = this; 186 | 187 | var app = this.app; 188 | 189 | var newScrolls = { x: 0, y: 0 }; 190 | this.subScrolling = function (event) { 191 | if (app === window) { 192 | newScrolls.x = window.pageXOffset; 193 | newScrolls.y = window.pageYOffset; 194 | } else { 195 | var _event$target = event.target, 196 | scrollTop = _event$target.scrollTop, 197 | scrollLeft = _event$target.scrollLeft, 198 | pageXOffset = _event$target.pageXOffset, 199 | pageYOffset = _event$target.pageYOffset; 200 | 201 | newScrolls.x = scrollLeft || pageYOffset || scrollLeft; 202 | newScrolls.y = scrollTop || pageXOffset || scrollTop; 203 | } 204 | _extends(_this2.scrolls, newScrolls); 205 | }; 206 | app.addEventListener('scroll', this.subScrolling, false); 207 | } 208 | }]); 209 | return VuetScroll; 210 | }(); 211 | 212 | function isSelf(modifiers) { 213 | return !!(modifiers.window !== true || modifiers.self); 214 | } 215 | 216 | function isWindow(modifiers) { 217 | return !!modifiers.window; 218 | } 219 | 220 | var directive = { 221 | inserted: function inserted(el, _ref, vnode) { 222 | var modifiers = _ref.modifiers, 223 | value = _ref.value; 224 | 225 | if (typeof value.path !== 'string') return debug.error('path is imperative parameter and is string type'); 226 | if (value.path === 'window') return debug.error('name cannot be the window name'); 227 | var store = vnode.context.$vuet.getState(value.path); 228 | if (!util.isObject(store)) return debug.error('\'' + value.path + '\' The module is not an object'); 229 | if (isSelf(modifiers)) { 230 | if (typeof value.name !== 'string') return debug.error('name is imperative parameter and is string type'); 231 | el[_self] = new VuetScroll({ 232 | app: el, 233 | path: value.path, 234 | name: value.name, 235 | store: store, 236 | scrolls: value.self 237 | }); 238 | } 239 | if (isWindow(modifiers)) { 240 | el[_window] = new VuetScroll({ 241 | app: window, 242 | path: value.path, 243 | name: 'window', 244 | store: store, 245 | scrolls: value.window 246 | }); 247 | } 248 | }, 249 | componentUpdated: function componentUpdated(el, _ref2, vnode) { 250 | var modifiers = _ref2.modifiers, 251 | value = _ref2.value; 252 | 253 | var store = vnode.context.$vuet.getState(value.path); 254 | if (!util.isObject(store)) return debug.error('\'' + value.path + '\' The module is not an object'); 255 | if (isSelf(modifiers)) { 256 | el[_self].update({ 257 | app: el, 258 | path: value.path, 259 | name: value.name, 260 | store: store, 261 | scrolls: value.self 262 | }); 263 | } 264 | if (isWindow(modifiers)) { 265 | el[_window].update({ 266 | app: window, 267 | path: value.path, 268 | name: 'window', 269 | store: store, 270 | scrolls: value.window || null 271 | }); 272 | } 273 | }, 274 | unbind: function unbind(el, _ref3) { 275 | var modifiers = _ref3.modifiers; 276 | 277 | if (isSelf(modifiers)) { 278 | el[_self].destroy(); 279 | delete el[_self]; 280 | } 281 | if (isWindow(modifiers)) { 282 | el[_window].destroy(); 283 | delete el[_window]; 284 | } 285 | } 286 | }; 287 | 288 | var index = { 289 | install: function install(Vue) { 290 | _Vue = Vue; 291 | Vue.directive('vuet-scroll', directive); 292 | } 293 | }; 294 | 295 | exports['default'] = index; 296 | 297 | Object.defineProperty(exports, '__esModule', { value: true }); 298 | 299 | }))); 300 | //# sourceMappingURL=vuet-scroll.js.map 301 | -------------------------------------------------------------------------------- /packages/vuet-scroll/dist/vuet-scroll.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vuet-scroll.js","sources":["../../../src/util.js","../../../src/vuet-static.js","../../../src/debug.js","../src/index.js"],"sourcesContent":["const util = {\n isObject (obj) {\n return !!obj && Object.prototype.toString.call(obj) === '[object Object]'\n },\n getArgMerge () {\n let opt = {}\n const args = arguments\n if (typeof args[0] === 'string') {\n opt[args[0]] = args.length > 1 ? args[1] : args[0]\n } else if (args[0] && util.isObject(args[0])) {\n opt = args[0]\n }\n return opt\n },\n isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function'\n }\n}\n\nexport default util\n","import debug from './debug'\nimport util from './util'\n\nexport let _Vue\n\nexport default function (Vuet) {\n Object.assign(Vuet, {\n installed: false,\n options: {\n rules: {},\n module: {\n reset () {\n this.state = this.data()\n return this\n }\n }\n },\n install (Vue) {\n if (this.installed) return this\n this.installed = true\n _Vue = Vue\n Object.defineProperty(Vue.prototype, '$vuet', {\n get () { return this.$root._vuet }\n })\n Vue.mixin({\n beforeCreate () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet = this.$options.vuet\n this._vuet._init(this)\n }\n }\n },\n destroyed () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet.destroy(this)\n }\n }\n }\n })\n return this\n },\n mapModules (opts) {\n const mixins = Object.keys(opts).map(alias => {\n const path = opts[alias]\n return {\n computed: {\n [alias]: {\n get () {\n debug.assertModule(this.$vuet, path)\n return this.$vuet.getModule(path)\n },\n set (val) {\n debug.error(`The'${path}'module is not allowed to assign`)\n }\n }\n }\n }\n })\n return {\n mixins\n }\n },\n mapRules () {\n const opts = util.getArgMerge.apply(null, arguments)\n const vueRules = []\n const addRule = (ruleName, any) => {\n const rules = Vuet.options.rules[ruleName]\n if (!util.isObject(rules)) debug.error(`The'${ruleName}'rule does not exist. Please make sure that it executes 'Vuet.rule('${ruleName}', opts)' before all components`)\n if (typeof any === 'string') {\n vueRules.push(rules.rule({ path: any }))\n } else {\n vueRules.push(rules.rule(any))\n }\n }\n Object.keys(opts).forEach(ruleName => {\n const any = opts[ruleName]\n if (Array.isArray(any)) {\n return any.forEach(item => {\n addRule(ruleName, item)\n })\n }\n addRule(ruleName, any)\n })\n return {\n mixins: vueRules\n }\n },\n rule () {\n Vuet.options.rules[arguments[0]] = arguments[1]\n if (typeof arguments[1].install === 'function') {\n arguments[1].install(Vuet, _Vue)\n }\n return this\n },\n callRuleHook (hook, ...arg) {\n Object.keys(Vuet.options.rules).forEach(k => {\n if (typeof Vuet.options.rules[k][hook] === 'function') {\n Vuet.options.rules[k][hook].apply(undefined, arg)\n }\n })\n }\n })\n}\n","import { _Vue } from './vuet-static'\n\nconst NAME = '__name__'\n\nexport default {\n error (msg) {\n throw new Error(`[${NAME}] ${msg}`)\n },\n warn (msg) {\n if (process.env.NODE_ENV !== 'production') {\n typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`)\n }\n },\n assertModule (vuet, path) {\n if (path in vuet.modules) {\n return\n }\n this.error(`The '${path}' module does not exist`)\n },\n assertVue () {\n if (!_Vue) {\n this.error('must call Vue.use(Vuet) before creating a store instance')\n }\n },\n assertFetch (vuet, path) {\n this.assertModule(vuet, path)\n if (typeof vuet.getModule(path).fetch !== 'function') {\n this.error(`'${path}' module 'fetch' must be the function type`)\n }\n }\n}\n","import debug from '../../../src/debug'\nimport util from '../../../src/util'\n\nlet _Vue\nconst _self = '__vuetScrollSelf__'\nconst _window = '__vuetScrollWindow__'\n\nclass VuetScroll {\n constructor (opts) {\n this.timer = {}\n this.setOption(opts)\n this.scrollTo()\n this.subScroll()\n }\n update (opts) {\n this.setOption(opts)\n const key = `timer-${this.path}-${this.name}`\n clearTimeout(this.timer[key])\n this.timer[key] = setTimeout(() => {\n this.scrollTo()\n delete this.timer[key]\n }, 10)\n }\n destroy () {\n this.app.removeEventListener('scroll', this.subScrolling, false)\n }\n setOption (opt) {\n this.app = opt.app\n this.path = opt.path\n this.name = opt.name || ''\n this.store = opt.store || { x: 0, y: 0 }\n this.scrolls = opt.scrolls || createScroll(opt)\n function createScroll (opt) {\n if (!opt.store.$scroll) {\n _Vue.set(opt.store, '$scroll', {})\n }\n if (!opt.store.$scroll[opt.name]) {\n _Vue.set(opt.store.$scroll, opt.name, { x: 0, y: 0 })\n }\n\n return opt.store.$scroll[opt.name]\n }\n }\n scrollTo () {\n const { app, scrolls } = this\n if ('scrollTop' in app && app !== window) {\n app.scrollLeft = scrolls.x\n app.scrollTop = scrolls.y\n } else {\n app.scrollTo(scrolls.x, scrolls.y)\n }\n }\n subScroll () {\n const { app } = this\n const newScrolls = { x: 0, y: 0 }\n this.subScrolling = (event) => {\n if (app === window) {\n newScrolls.x = window.pageXOffset\n newScrolls.y = window.pageYOffset\n } else {\n const { scrollTop, scrollLeft, pageXOffset, pageYOffset } = event.target\n newScrolls.x = scrollLeft || pageYOffset || scrollLeft\n newScrolls.y = scrollTop || pageXOffset || scrollTop\n }\n Object.assign(this.scrolls, newScrolls)\n }\n app.addEventListener('scroll', this.subScrolling, false)\n }\n}\n\nfunction isSelf (modifiers) {\n return !!(modifiers.window !== true || modifiers.self)\n}\n\nfunction isWindow (modifiers) {\n return !!(modifiers.window)\n}\n\nconst directive = {\n inserted (el, { modifiers, value }, vnode) {\n if (typeof value.path !== 'string') return debug.error('path is imperative parameter and is string type')\n if (value.path === 'window') return debug.error('name cannot be the window name')\n const store = vnode.context.$vuet.getState(value.path)\n if (!util.isObject(store)) return debug.error(`'${value.path}' The module is not an object`)\n if (isSelf(modifiers)) {\n if (typeof value.name !== 'string') return debug.error('name is imperative parameter and is string type')\n el[_self] = new VuetScroll({\n app: el,\n path: value.path,\n name: value.name,\n store,\n scrolls: value.self\n })\n }\n if (isWindow(modifiers)) {\n el[_window] = new VuetScroll({\n app: window,\n path: value.path,\n name: 'window',\n store,\n scrolls: value.window\n })\n }\n },\n componentUpdated (el, { modifiers, value }, vnode) {\n const store = vnode.context.$vuet.getState(value.path)\n if (!util.isObject(store)) return debug.error(`'${value.path}' The module is not an object`)\n if (isSelf(modifiers)) {\n el[_self].update({\n app: el,\n path: value.path,\n name: value.name,\n store,\n scrolls: value.self\n })\n }\n if (isWindow(modifiers)) {\n el[_window].update({\n app: window,\n path: value.path,\n name: 'window',\n store,\n scrolls: value.window || null\n })\n }\n },\n unbind (el, { modifiers }) {\n if (isSelf(modifiers)) {\n el[_self].destroy()\n delete el[_self]\n }\n if (isWindow(modifiers)) {\n el[_window].destroy()\n delete el[_window]\n }\n }\n}\n\nexport default {\n install (Vue) {\n _Vue = Vue\n Vue.directive('vuet-scroll', directive)\n }\n}\n"],"names":["util","obj","Object","prototype","toString","call","opt","args","arguments","length","isObject","then","_Vue","NAME","msg","Error","process","console","warn","vuet","path","modules","error","assertModule","getModule","fetch","_self","_window","VuetScroll","opts","timer","setOption","scrollTo","subScroll","key","name","setTimeout","app","removeEventListener","subScrolling","store","x","y","scrolls","createScroll","$scroll","set","window","scrollLeft","scrollTop","newScrolls","event","pageXOffset","pageYOffset","target","addEventListener","isSelf","modifiers","self","isWindow","directive","el","vnode","value","debug","context","$vuet","getState","update","destroy","Vue"],"mappings":"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"} -------------------------------------------------------------------------------- /packages/vuet-scroll/dist/vuet-scroll.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.VuetScroll=e.VuetScroll||{})}(this,function(e){"use strict";function t(e){return!(!0===e.window&&!e.self)}function o(e){return!!e.window}var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},i=function(){function e(e,t){for(var o=0;o1?t[1]:t[0]:t[0]&&l.isObject(t[0])&&(e=t[0]),e},isPromise:function(e){return("object"===(void 0===e?"undefined":n(e))||"function"==typeof e)&&!!e&&"function"==typeof e.then}},a={error:function(e){throw new Error("[vuet-scroll] "+e)},warn:function(e){},assertModule:function(e,t){t in e.modules||this.error("The '"+t+"' module does not exist")},assertVue:function(){this.error("must call Vue.use(Vuet) before creating a store instance")},assertFetch:function(e,t){this.assertModule(e,t),"function"!=typeof e.getModule(t).fetch&&this.error("'"+t+"' module 'fetch' must be the function type")}},c=void 0,u="__vuetScrollSelf__",f="__vuetScrollWindow__",p=function(){function e(t){r(this,e),this.timer={},this.setOption(t),this.scrollTo(),this.subScroll()}return i(e,[{key:"update",value:function(e){var t=this;this.setOption(e);var o="timer-"+this.path+"-"+this.name;clearTimeout(this.timer[o]),this.timer[o]=setTimeout(function(){t.scrollTo(),delete t.timer[o]},10)}},{key:"destroy",value:function(){this.app.removeEventListener("scroll",this.subScrolling,!1)}},{key:"setOption",value:function(e){this.app=e.app,this.path=e.path,this.name=e.name||"",this.store=e.store||{x:0,y:0},this.scrolls=e.scrolls||function(e){return e.store.$scroll||c.set(e.store,"$scroll",{}),e.store.$scroll[e.name]||c.set(e.store.$scroll,e.name,{x:0,y:0}),e.store.$scroll[e.name]}(e)}},{key:"scrollTo",value:function(){var e=this.app,t=this.scrolls;"scrollTop"in e&&e!==window?(e.scrollLeft=t.x,e.scrollTop=t.y):e.scrollTo(t.x,t.y)}},{key:"subScroll",value:function(){var e=this,t=this.app,o={x:0,y:0};this.subScrolling=function(n){if(t===window)o.x=window.pageXOffset,o.y=window.pageYOffset;else{var r=n.target,i=r.scrollTop,l=r.scrollLeft,a=r.pageXOffset,c=r.pageYOffset;o.x=l||c||l,o.y=i||a||i}s(e.scrolls,o)},t.addEventListener("scroll",this.subScrolling,!1)}}]),e}(),h={inserted:function(e,n,r){var i=n.modifiers,s=n.value;if("string"!=typeof s.path)return a.error("path is imperative parameter and is string type");if("window"===s.path)return a.error("name cannot be the window name");var c=r.context.$vuet.getState(s.path);if(!l.isObject(c))return a.error("'"+s.path+"' The module is not an object");if(t(i)){if("string"!=typeof s.name)return a.error("name is imperative parameter and is string type");e[u]=new p({app:e,path:s.path,name:s.name,store:c,scrolls:s.self})}o(i)&&(e[f]=new p({app:window,path:s.path,name:"window",store:c,scrolls:s.window}))},componentUpdated:function(e,n,r){var i=n.modifiers,s=n.value,c=r.context.$vuet.getState(s.path);if(!l.isObject(c))return a.error("'"+s.path+"' The module is not an object");t(i)&&e[u].update({app:e,path:s.path,name:s.name,store:c,scrolls:s.self}),o(i)&&e[f].update({app:window,path:s.path,name:"window",store:c,scrolls:s.window||null})},unbind:function(e,n){var r=n.modifiers;t(r)&&(e[u].destroy(),delete e[u]),o(r)&&(e[f].destroy(),delete e[f])}},d={install:function(e){c=e,e.directive("vuet-scroll",h)}};e.default=d,Object.defineProperty(e,"__esModule",{value:!0})}); 2 | //# sourceMappingURL=vuet-scroll.min.js.map 3 | -------------------------------------------------------------------------------- /packages/vuet-scroll/dist/vuet-scroll.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vuet-scroll.min.js","sources":["../src/index.js","../../../src/util.js","../../../src/debug.js"],"sourcesContent":["import debug from '../../../src/debug'\nimport util from '../../../src/util'\n\nlet _Vue\nconst _self = '__vuetScrollSelf__'\nconst _window = '__vuetScrollWindow__'\n\nclass VuetScroll {\n constructor (opts) {\n this.timer = {}\n this.setOption(opts)\n this.scrollTo()\n this.subScroll()\n }\n update (opts) {\n this.setOption(opts)\n const key = `timer-${this.path}-${this.name}`\n clearTimeout(this.timer[key])\n this.timer[key] = setTimeout(() => {\n this.scrollTo()\n delete this.timer[key]\n }, 10)\n }\n destroy () {\n this.app.removeEventListener('scroll', this.subScrolling, false)\n }\n setOption (opt) {\n this.app = opt.app\n this.path = opt.path\n this.name = opt.name || ''\n this.store = opt.store || { x: 0, y: 0 }\n this.scrolls = opt.scrolls || createScroll(opt)\n function createScroll (opt) {\n if (!opt.store.$scroll) {\n _Vue.set(opt.store, '$scroll', {})\n }\n if (!opt.store.$scroll[opt.name]) {\n _Vue.set(opt.store.$scroll, opt.name, { x: 0, y: 0 })\n }\n\n return opt.store.$scroll[opt.name]\n }\n }\n scrollTo () {\n const { app, scrolls } = this\n if ('scrollTop' in app && app !== window) {\n app.scrollLeft = scrolls.x\n app.scrollTop = scrolls.y\n } else {\n app.scrollTo(scrolls.x, scrolls.y)\n }\n }\n subScroll () {\n const { app } = this\n const newScrolls = { x: 0, y: 0 }\n this.subScrolling = (event) => {\n if (app === window) {\n newScrolls.x = window.pageXOffset\n newScrolls.y = window.pageYOffset\n } else {\n const { scrollTop, scrollLeft, pageXOffset, pageYOffset } = event.target\n newScrolls.x = scrollLeft || pageYOffset || scrollLeft\n newScrolls.y = scrollTop || pageXOffset || scrollTop\n }\n Object.assign(this.scrolls, newScrolls)\n }\n app.addEventListener('scroll', this.subScrolling, false)\n }\n}\n\nfunction isSelf (modifiers) {\n return !!(modifiers.window !== true || modifiers.self)\n}\n\nfunction isWindow (modifiers) {\n return !!(modifiers.window)\n}\n\nconst directive = {\n inserted (el, { modifiers, value }, vnode) {\n if (typeof value.path !== 'string') return debug.error('path is imperative parameter and is string type')\n if (value.path === 'window') return debug.error('name cannot be the window name')\n const store = vnode.context.$vuet.getState(value.path)\n if (!util.isObject(store)) return debug.error(`'${value.path}' The module is not an object`)\n if (isSelf(modifiers)) {\n if (typeof value.name !== 'string') return debug.error('name is imperative parameter and is string type')\n el[_self] = new VuetScroll({\n app: el,\n path: value.path,\n name: value.name,\n store,\n scrolls: value.self\n })\n }\n if (isWindow(modifiers)) {\n el[_window] = new VuetScroll({\n app: window,\n path: value.path,\n name: 'window',\n store,\n scrolls: value.window\n })\n }\n },\n componentUpdated (el, { modifiers, value }, vnode) {\n const store = vnode.context.$vuet.getState(value.path)\n if (!util.isObject(store)) return debug.error(`'${value.path}' The module is not an object`)\n if (isSelf(modifiers)) {\n el[_self].update({\n app: el,\n path: value.path,\n name: value.name,\n store,\n scrolls: value.self\n })\n }\n if (isWindow(modifiers)) {\n el[_window].update({\n app: window,\n path: value.path,\n name: 'window',\n store,\n scrolls: value.window || null\n })\n }\n },\n unbind (el, { modifiers }) {\n if (isSelf(modifiers)) {\n el[_self].destroy()\n delete el[_self]\n }\n if (isWindow(modifiers)) {\n el[_window].destroy()\n delete el[_window]\n }\n }\n}\n\nexport default {\n install (Vue) {\n _Vue = Vue\n Vue.directive('vuet-scroll', directive)\n }\n}\n","const util = {\n isObject (obj) {\n return !!obj && Object.prototype.toString.call(obj) === '[object Object]'\n },\n getArgMerge () {\n let opt = {}\n const args = arguments\n if (typeof args[0] === 'string') {\n opt[args[0]] = args.length > 1 ? args[1] : args[0]\n } else if (args[0] && util.isObject(args[0])) {\n opt = args[0]\n }\n return opt\n },\n isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function'\n }\n}\n\nexport default util\n","import { _Vue } from './vuet-static'\n\nconst NAME = '__name__'\n\nexport default {\n error (msg) {\n throw new Error(`[${NAME}] ${msg}`)\n },\n warn (msg) {\n if (process.env.NODE_ENV !== 'production') {\n typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`)\n }\n },\n assertModule (vuet, path) {\n if (path in vuet.modules) {\n return\n }\n this.error(`The '${path}' module does not exist`)\n },\n assertVue () {\n if (!_Vue) {\n this.error('must call Vue.use(Vuet) before creating a store instance')\n }\n },\n assertFetch (vuet, path) {\n this.assertModule(vuet, path)\n if (typeof vuet.getModule(path).fetch !== 'function') {\n this.error(`'${path}' module 'fetch' must be the function type`)\n }\n }\n}\n"],"names":["isSelf","modifiers","window","self","isWindow","util","obj","Object","prototype","toString","call","opt","args","arguments","length","isObject","then","msg","Error","vuet","path","modules","error","assertModule","getModule","fetch","_Vue","_self","_window","VuetScroll","opts","timer","setOption","scrollTo","subScroll","key","this","name","setTimeout","_this","app","removeEventListener","subScrolling","store","x","y","scrolls","$scroll","set","scrollLeft","scrollTop","newScrolls","event","pageXOffset","pageYOffset","target","_this2","addEventListener","directive","el","vnode","value","debug","context","$vuet","getState","update","destroy","Vue"],"mappings":"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"} -------------------------------------------------------------------------------- /packages/vuet-scroll/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuet-scroll", 3 | "version": "0.0.7", 4 | "description": "vuet scroll", 5 | "main": "dist/vuet-scroll.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "medatc", 10 | "license": "MIT", 11 | "files": [ 12 | "dist/", 13 | "src/" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/vuet-scroll/src/index.js: -------------------------------------------------------------------------------- 1 | import debug from '../../../src/debug' 2 | import util from '../../../src/util' 3 | 4 | let _Vue 5 | const _self = '__vuetScrollSelf__' 6 | const _window = '__vuetScrollWindow__' 7 | 8 | class VuetScroll { 9 | constructor (opts) { 10 | this.timer = {} 11 | this.setOption(opts) 12 | this.scrollTo() 13 | this.subScroll() 14 | } 15 | update (opts) { 16 | this.setOption(opts) 17 | const key = `timer-${this.path}-${this.name}` 18 | clearTimeout(this.timer[key]) 19 | this.timer[key] = setTimeout(() => { 20 | this.scrollTo() 21 | delete this.timer[key] 22 | }, 10) 23 | } 24 | destroy () { 25 | this.app.removeEventListener('scroll', this.subScrolling, false) 26 | } 27 | setOption (opt) { 28 | this.app = opt.app 29 | this.path = opt.path 30 | this.name = opt.name || '' 31 | this.store = opt.store || { x: 0, y: 0 } 32 | this.scrolls = opt.scrolls || createScroll(opt) 33 | function createScroll (opt) { 34 | if (!opt.store.$scroll) { 35 | _Vue.set(opt.store, '$scroll', {}) 36 | } 37 | if (!opt.store.$scroll[opt.name]) { 38 | _Vue.set(opt.store.$scroll, opt.name, { x: 0, y: 0 }) 39 | } 40 | 41 | return opt.store.$scroll[opt.name] 42 | } 43 | } 44 | scrollTo () { 45 | const { app, scrolls } = this 46 | if ('scrollTop' in app && app !== window) { 47 | app.scrollLeft = scrolls.x 48 | app.scrollTop = scrolls.y 49 | } else { 50 | app.scrollTo(scrolls.x, scrolls.y) 51 | } 52 | } 53 | subScroll () { 54 | const { app } = this 55 | const newScrolls = { x: 0, y: 0 } 56 | this.subScrolling = (event) => { 57 | if (app === window) { 58 | newScrolls.x = window.pageXOffset 59 | newScrolls.y = window.pageYOffset 60 | } else { 61 | const { scrollTop, scrollLeft, pageXOffset, pageYOffset } = event.target 62 | newScrolls.x = scrollLeft || pageYOffset || scrollLeft 63 | newScrolls.y = scrollTop || pageXOffset || scrollTop 64 | } 65 | Object.assign(this.scrolls, newScrolls) 66 | } 67 | app.addEventListener('scroll', this.subScrolling, false) 68 | } 69 | } 70 | 71 | function isSelf (modifiers) { 72 | return !!(modifiers.window !== true || modifiers.self) 73 | } 74 | 75 | function isWindow (modifiers) { 76 | return !!(modifiers.window) 77 | } 78 | 79 | const directive = { 80 | inserted (el, { modifiers, value }, vnode) { 81 | if (typeof value.path !== 'string') return debug.error('path is imperative parameter and is string type') 82 | if (value.path === 'window') return debug.error('name cannot be the window name') 83 | const store = vnode.context.$vuet.getState(value.path) 84 | if (!util.isObject(store)) return debug.error(`'${value.path}' The module is not an object`) 85 | if (isSelf(modifiers)) { 86 | if (typeof value.name !== 'string') return debug.error('name is imperative parameter and is string type') 87 | el[_self] = new VuetScroll({ 88 | app: el, 89 | path: value.path, 90 | name: value.name, 91 | store, 92 | scrolls: value.self 93 | }) 94 | } 95 | if (isWindow(modifiers)) { 96 | el[_window] = new VuetScroll({ 97 | app: window, 98 | path: value.path, 99 | name: 'window', 100 | store, 101 | scrolls: value.window 102 | }) 103 | } 104 | }, 105 | componentUpdated (el, { modifiers, value }, vnode) { 106 | const store = vnode.context.$vuet.getState(value.path) 107 | if (!util.isObject(store)) return debug.error(`'${value.path}' The module is not an object`) 108 | if (isSelf(modifiers)) { 109 | el[_self].update({ 110 | app: el, 111 | path: value.path, 112 | name: value.name, 113 | store, 114 | scrolls: value.self 115 | }) 116 | } 117 | if (isWindow(modifiers)) { 118 | el[_window].update({ 119 | app: window, 120 | path: value.path, 121 | name: 'window', 122 | store, 123 | scrolls: value.window || null 124 | }) 125 | } 126 | }, 127 | unbind (el, { modifiers }) { 128 | if (isSelf(modifiers)) { 129 | el[_self].destroy() 130 | delete el[_self] 131 | } 132 | if (isWindow(modifiers)) { 133 | el[_window].destroy() 134 | delete el[_window] 135 | } 136 | } 137 | } 138 | 139 | export default { 140 | install (Vue) { 141 | _Vue = Vue 142 | Vue.directive('vuet-scroll', directive) 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /packages/vuet-store/README.md: -------------------------------------------------------------------------------- 1 | ## vuet-store 2 | [![Coverage Status](https://coveralls.io/repos/github/medatc/vuet/badge.svg?branch=dev)](https://coveralls.io/github/medatc/vuet?branch=dev) 3 | [![Build Status](https://travis-ci.org/medatc/vuet.svg?branch=dev)](https://travis-ci.org/medatc/vuet) 4 | [![npm](https://img.shields.io/npm/v/vuet-store.svg)](https://www.npmjs.com/package/vuet-store) 5 | [![npm](https://img.shields.io/npm/dm/vuet-store.svg)](https://www.npmjs.com/package/vuet-store) 6 | [![npm](https://img.shields.io/npm/dt/vuet-store.svg)](https://www.npmjs.com/package/vuet-store) 7 | 8 | 9 | ## 它是做什么的? 10 | 它能够监模块变化,使用`localStorage`存储模块状态,等下次用户访问时,再从`localStorage`中取出状态,适合存储用户登录状态等。 11 | 12 | 13 | ## 安装 14 | ```bash 15 | npm install --save vuet-store 16 | ``` 17 | 18 | 19 | ## 使用 20 | ```javascript 21 | import Vue from 'vue' 22 | import Vuet, { mapModules, mapRules } from 'vuet' 23 | import VuetStore from 'vuet-store' 24 | 25 | Vue.use(Vuet) 26 | Vuet.rule('store', VuetStore) 27 | 28 | const vuet = new Vuet() 29 | vuet.addModules('test', { 30 | data () { 31 | return { 32 | count: 0 33 | } 34 | }, 35 | fetch () { 36 | this.count = 1000 37 | }, 38 | plus () { 39 | this.count++ 40 | }, 41 | reduce () { 42 | this.count-- 43 | } 44 | }) 45 | 46 | const App = { 47 | mixins: [ 48 | mapModules({ 49 | test: 'test' // { 别名: '模块路径' } 50 | }), 51 | mapRules({ 52 | store: [{ path: 'test' }] // { 规则: ['模块路径'] } 53 | }) 54 | ], 55 | template: ` 56 |
57 |
{{ test.count }}
58 | 59 | 60 | 61 | 62 |
63 | ` 64 | } 65 | 66 | export default new Vue({ 67 | el: '#app', 68 | vuet, 69 | render (h) { 70 | return h(App) 71 | } 72 | }) 73 | 74 | ``` 75 | -------------------------------------------------------------------------------- /packages/vuet-store/dist/vuet-store.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (factory((global.VuetStore = global.VuetStore || {}))); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | var _Vue = void 0; 8 | 9 | var NAME = 'vuet-store'; 10 | 11 | var debug = { 12 | error: function error(msg) { 13 | throw new Error('[' + NAME + '] ' + msg); 14 | }, 15 | warn: function warn(msg) { 16 | { 17 | typeof console !== 'undefined' && console.warn('[' + NAME + '] ' + msg); 18 | } 19 | }, 20 | assertModule: function assertModule(vuet, path) { 21 | if (path in vuet.modules) { 22 | return; 23 | } 24 | this.error('The \'' + path + '\' module does not exist'); 25 | }, 26 | assertVue: function assertVue() { 27 | if (!_Vue) { 28 | this.error('must call Vue.use(Vuet) before creating a store instance'); 29 | } 30 | }, 31 | assertFetch: function assertFetch(vuet, path) { 32 | this.assertModule(vuet, path); 33 | if (typeof vuet.getModule(path).fetch !== 'function') { 34 | this.error('\'' + path + '\' module \'fetch\' must be the function type'); 35 | } 36 | } 37 | }; 38 | 39 | var getName = function getName(path) { 40 | return '__vuet_store_' + path + '__'; 41 | }; 42 | 43 | var setItem = function setItem(path, data) { 44 | setTimeout(function () { 45 | localStorage.setItem(getName(path), JSON.stringify(data)); 46 | }, 0); 47 | }; 48 | 49 | var index = { 50 | addModule: function addModule(vuet, path) { 51 | var store = JSON.parse(localStorage.getItem(getName(path))); 52 | if (store) { 53 | vuet.getModule(path).state = store; 54 | } 55 | }, 56 | rule: function rule(_ref) { 57 | var path = _ref.path; 58 | 59 | return { 60 | created: function created() { 61 | debug.assertModule(this.$vuet, path); 62 | setItem(path, this.$vuet.getModule(path).state); 63 | this[getName(path)] = this.$vuet.app.$watch(function () { 64 | return this.$vuet.getModule(path).state; 65 | }, function (newVal) { 66 | setItem(path, newVal); 67 | }, { 68 | deep: true 69 | }); 70 | }, 71 | destroyed: function destroyed() { 72 | this[getName(path)](); 73 | delete this[getName(path)]; 74 | } 75 | }; 76 | } 77 | }; 78 | 79 | exports['default'] = index; 80 | 81 | Object.defineProperty(exports, '__esModule', { value: true }); 82 | 83 | }))); 84 | //# sourceMappingURL=vuet-store.js.map 85 | -------------------------------------------------------------------------------- /packages/vuet-store/dist/vuet-store.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vuet-store.js","sources":["../../../src/vuet-static.js","../../../src/debug.js","../src/index.js"],"sourcesContent":["import debug from './debug'\nimport util from './util'\n\nexport let _Vue\n\nexport default function (Vuet) {\n Object.assign(Vuet, {\n installed: false,\n options: {\n rules: {},\n module: {\n reset () {\n this.state = this.data()\n return this\n }\n }\n },\n install (Vue) {\n if (this.installed) return this\n this.installed = true\n _Vue = Vue\n Object.defineProperty(Vue.prototype, '$vuet', {\n get () { return this.$root._vuet }\n })\n Vue.mixin({\n beforeCreate () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet = this.$options.vuet\n this._vuet._init(this)\n }\n }\n },\n destroyed () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet.destroy(this)\n }\n }\n }\n })\n return this\n },\n mapModules (opts) {\n const mixins = Object.keys(opts).map(alias => {\n const path = opts[alias]\n return {\n computed: {\n [alias]: {\n get () {\n debug.assertModule(this.$vuet, path)\n return this.$vuet.getModule(path)\n },\n set (val) {\n debug.error(`The'${path}'module is not allowed to assign`)\n }\n }\n }\n }\n })\n return {\n mixins\n }\n },\n mapRules () {\n const opts = util.getArgMerge.apply(null, arguments)\n const vueRules = []\n const addRule = (ruleName, any) => {\n const rules = Vuet.options.rules[ruleName]\n if (!util.isObject(rules)) debug.error(`The'${ruleName}'rule does not exist. Please make sure that it executes 'Vuet.rule('${ruleName}', opts)' before all components`)\n if (typeof any === 'string') {\n vueRules.push(rules.rule({ path: any }))\n } else {\n vueRules.push(rules.rule(any))\n }\n }\n Object.keys(opts).forEach(ruleName => {\n const any = opts[ruleName]\n if (Array.isArray(any)) {\n return any.forEach(item => {\n addRule(ruleName, item)\n })\n }\n addRule(ruleName, any)\n })\n return {\n mixins: vueRules\n }\n },\n rule () {\n Vuet.options.rules[arguments[0]] = arguments[1]\n if (typeof arguments[1].install === 'function') {\n arguments[1].install(Vuet, _Vue)\n }\n return this\n },\n callRuleHook (hook, ...arg) {\n Object.keys(Vuet.options.rules).forEach(k => {\n if (typeof Vuet.options.rules[k][hook] === 'function') {\n Vuet.options.rules[k][hook].apply(undefined, arg)\n }\n })\n }\n })\n}\n","import { _Vue } from './vuet-static'\n\nconst NAME = '__name__'\n\nexport default {\n error (msg) {\n throw new Error(`[${NAME}] ${msg}`)\n },\n warn (msg) {\n if (process.env.NODE_ENV !== 'production') {\n typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`)\n }\n },\n assertModule (vuet, path) {\n if (path in vuet.modules) {\n return\n }\n this.error(`The '${path}' module does not exist`)\n },\n assertVue () {\n if (!_Vue) {\n this.error('must call Vue.use(Vuet) before creating a store instance')\n }\n },\n assertFetch (vuet, path) {\n this.assertModule(vuet, path)\n if (typeof vuet.getModule(path).fetch !== 'function') {\n this.error(`'${path}' module 'fetch' must be the function type`)\n }\n }\n}\n","import debug from '../../../src/debug'\n\nconst getName = (path) => {\n return `__vuet_store_${path}__`\n}\n\nconst setItem = (path, data) => {\n setTimeout(() => {\n localStorage.setItem(getName(path), JSON.stringify(data))\n }, 0)\n}\n\nexport default {\n addModule (vuet, path) {\n const store = JSON.parse(localStorage.getItem(getName(path)))\n if (store) {\n vuet.getModule(path).state = store\n }\n },\n rule ({ path }) {\n return {\n created () {\n debug.assertModule(this.$vuet, path)\n setItem(path, this.$vuet.getModule(path).state)\n this[getName(path)] = this.$vuet.app.$watch(function () {\n return this.$vuet.getModule(path).state\n }, (newVal) => {\n setItem(path, newVal)\n }, {\n deep: true\n })\n },\n destroyed () {\n this[getName(path)]()\n delete this[getName(path)]\n }\n }\n }\n}\n"],"names":["_Vue","NAME","msg","Error","process","console","warn","vuet","path","modules","error","assertModule","getModule","fetch","getName","setItem","data","JSON","stringify","store","parse","localStorage","getItem","state","$vuet","app","$watch","newVal"],"mappings":";;;;;;AAGO,IAAIA,aAAJ,CAEP;;ACHA,IAAMC,OAAO,YAAb;;AAEA,YAAe;OAAA,iBACNC,GADM,EACD;UACJ,IAAIC,KAAJ,OAAcF,IAAd,UAAuBC,GAAvB,CAAN;GAFW;MAAA,gBAIPA,GAJO,EAIF;IACLE,AAAJ,AAA2C;aAClCC,OAAP,KAAmB,WAAnB,IAAkCA,QAAQC,IAAR,OAAiBL,IAAjB,UAA0BC,GAA1B,CAAlC;;GANS;cAAA,wBASCK,IATD,EASOC,IATP,EASa;QACpBA,QAAQD,KAAKE,OAAjB,EAA0B;;;SAGrBC,KAAL,YAAmBF,IAAnB;GAbW;WAAA,uBAeA;QACP,CAACR,IAAL,EAAW;WACJU,KAAL,CAAW,0DAAX;;GAjBS;aAAA,uBAoBAH,IApBA,EAoBMC,IApBN,EAoBY;SAClBG,YAAL,CAAkBJ,IAAlB,EAAwBC,IAAxB;QACI,OAAOD,KAAKK,SAAL,CAAeJ,IAAf,EAAqBK,KAA5B,KAAsC,UAA1C,EAAsD;WAC/CH,KAAL,QAAeF,IAAf;;;CAvBN;;ACFA,IAAMM,UAAU,SAAVA,OAAU,CAACN,IAAD,EAAU;2BACDA,IAAvB;CADF;;AAIA,IAAMO,UAAU,SAAVA,OAAU,CAACP,IAAD,EAAOQ,IAAP,EAAgB;aACnB,YAAM;iBACFD,OAAb,CAAqBD,QAAQN,IAAR,CAArB,EAAoCS,KAAKC,SAAL,CAAeF,IAAf,CAApC;GADF,EAEG,CAFH;CADF;;AAMA,YAAe;WAAA,qBACFT,IADE,EACIC,IADJ,EACU;QACfW,QAAQF,KAAKG,KAAL,CAAWC,aAAaC,OAAb,CAAqBR,QAAQN,IAAR,CAArB,CAAX,CAAd;QACIW,KAAJ,EAAW;WACJP,SAAL,CAAeJ,IAAf,EAAqBe,KAArB,GAA6BJ,KAA7B;;GAJS;MAAA,sBAOG;QAARX,IAAQ,QAARA,IAAQ;;WACP;aAAA,qBACM;cACHG,YAAN,CAAmB,KAAKa,KAAxB,EAA+BhB,IAA/B;gBACQA,IAAR,EAAc,KAAKgB,KAAL,CAAWZ,SAAX,CAAqBJ,IAArB,EAA2Be,KAAzC;aACKT,QAAQN,IAAR,CAAL,IAAsB,KAAKgB,KAAL,CAAWC,GAAX,CAAeC,MAAf,CAAsB,YAAY;iBAC/C,KAAKF,KAAL,CAAWZ,SAAX,CAAqBJ,IAArB,EAA2Be,KAAlC;SADoB,EAEnB,UAACI,MAAD,EAAY;kBACLnB,IAAR,EAAcmB,MAAd;SAHoB,EAInB;gBACK;SALc,CAAtB;OAJG;eAAA,uBAYQ;aACNb,QAAQN,IAAR,CAAL;eACO,KAAKM,QAAQN,IAAR,CAAL,CAAP;;KAdJ;;CARJ;;;;;;"} -------------------------------------------------------------------------------- /packages/vuet-store/dist/vuet-store.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.VuetStore=e.VuetStore||{})}(this,function(e){"use strict";var t={error:function(e){throw new Error("[vuet-store] "+e)},warn:function(e){},assertModule:function(e,t){t in e.modules||this.error("The '"+t+"' module does not exist")},assertVue:function(){this.error("must call Vue.use(Vuet) before creating a store instance")},assertFetch:function(e,t){this.assertModule(e,t),"function"!=typeof e.getModule(t).fetch&&this.error("'"+t+"' module 'fetch' must be the function type")}},o=function(e){return"__vuet_store_"+e+"__"},n=function(e,t){setTimeout(function(){localStorage.setItem(o(e),JSON.stringify(t))},0)},u={addModule:function(e,t){var n=JSON.parse(localStorage.getItem(o(t)));n&&(e.getModule(t).state=n)},rule:function(e){var u=e.path;return{created:function(){t.assertModule(this.$vuet,u),n(u,this.$vuet.getModule(u).state),this[o(u)]=this.$vuet.app.$watch(function(){return this.$vuet.getModule(u).state},function(e){n(u,e)},{deep:!0})},destroyed:function(){this[o(u)](),delete this[o(u)]}}}};e.default=u,Object.defineProperty(e,"__esModule",{value:!0})}); 2 | //# sourceMappingURL=vuet-store.min.js.map 3 | -------------------------------------------------------------------------------- /packages/vuet-store/dist/vuet-store.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"vuet-store.min.js","sources":["../../../src/vuet-static.js","../../../src/debug.js","../src/index.js"],"sourcesContent":["import debug from './debug'\nimport util from './util'\n\nexport let _Vue\n\nexport default function (Vuet) {\n Object.assign(Vuet, {\n installed: false,\n options: {\n rules: {},\n module: {\n reset () {\n this.state = this.data()\n return this\n }\n }\n },\n install (Vue) {\n if (this.installed) return this\n this.installed = true\n _Vue = Vue\n Object.defineProperty(Vue.prototype, '$vuet', {\n get () { return this.$root._vuet }\n })\n Vue.mixin({\n beforeCreate () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet = this.$options.vuet\n this._vuet._init(this)\n }\n }\n },\n destroyed () {\n if (typeof this.$options.vuet !== 'undefined') {\n if (this.$options.vuet instanceof Vuet) {\n this._vuet.destroy(this)\n }\n }\n }\n })\n return this\n },\n mapModules (opts) {\n const mixins = Object.keys(opts).map(alias => {\n const path = opts[alias]\n return {\n computed: {\n [alias]: {\n get () {\n debug.assertModule(this.$vuet, path)\n return this.$vuet.getModule(path)\n },\n set (val) {\n debug.error(`The'${path}'module is not allowed to assign`)\n }\n }\n }\n }\n })\n return {\n mixins\n }\n },\n mapRules () {\n const opts = util.getArgMerge.apply(null, arguments)\n const vueRules = []\n const addRule = (ruleName, any) => {\n const rules = Vuet.options.rules[ruleName]\n if (!util.isObject(rules)) debug.error(`The'${ruleName}'rule does not exist. Please make sure that it executes 'Vuet.rule('${ruleName}', opts)' before all components`)\n if (typeof any === 'string') {\n vueRules.push(rules.rule({ path: any }))\n } else {\n vueRules.push(rules.rule(any))\n }\n }\n Object.keys(opts).forEach(ruleName => {\n const any = opts[ruleName]\n if (Array.isArray(any)) {\n return any.forEach(item => {\n addRule(ruleName, item)\n })\n }\n addRule(ruleName, any)\n })\n return {\n mixins: vueRules\n }\n },\n rule () {\n Vuet.options.rules[arguments[0]] = arguments[1]\n if (typeof arguments[1].install === 'function') {\n arguments[1].install(Vuet, _Vue)\n }\n return this\n },\n callRuleHook (hook, ...arg) {\n Object.keys(Vuet.options.rules).forEach(k => {\n if (typeof Vuet.options.rules[k][hook] === 'function') {\n Vuet.options.rules[k][hook].apply(undefined, arg)\n }\n })\n }\n })\n}\n","import { _Vue } from './vuet-static'\n\nconst NAME = '__name__'\n\nexport default {\n error (msg) {\n throw new Error(`[${NAME}] ${msg}`)\n },\n warn (msg) {\n if (process.env.NODE_ENV !== 'production') {\n typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`)\n }\n },\n assertModule (vuet, path) {\n if (path in vuet.modules) {\n return\n }\n this.error(`The '${path}' module does not exist`)\n },\n assertVue () {\n if (!_Vue) {\n this.error('must call Vue.use(Vuet) before creating a store instance')\n }\n },\n assertFetch (vuet, path) {\n this.assertModule(vuet, path)\n if (typeof vuet.getModule(path).fetch !== 'function') {\n this.error(`'${path}' module 'fetch' must be the function type`)\n }\n }\n}\n","import debug from '../../../src/debug'\n\nconst getName = (path) => {\n return `__vuet_store_${path}__`\n}\n\nconst setItem = (path, data) => {\n setTimeout(() => {\n localStorage.setItem(getName(path), JSON.stringify(data))\n }, 0)\n}\n\nexport default {\n addModule (vuet, path) {\n const store = JSON.parse(localStorage.getItem(getName(path)))\n if (store) {\n vuet.getModule(path).state = store\n }\n },\n rule ({ path }) {\n return {\n created () {\n debug.assertModule(this.$vuet, path)\n setItem(path, this.$vuet.getModule(path).state)\n this[getName(path)] = this.$vuet.app.$watch(function () {\n return this.$vuet.getModule(path).state\n }, (newVal) => {\n setItem(path, newVal)\n }, {\n deep: true\n })\n },\n destroyed () {\n this[getName(path)]()\n delete this[getName(path)]\n }\n }\n }\n}\n"],"names":["msg","Error","vuet","path","modules","error","assertModule","getModule","fetch","getName","setItem","data","JSON","stringify","store","parse","localStorage","getItem","state","this","$vuet","app","$watch","newVal"],"mappings":"wMAGO,uBCEEA,QACC,IAAIC,uBAAmBD,kBAEzBA,2BAKQE,EAAMC,GACdA,IAAQD,GAAKE,cAGZC,cAAcF,wDAIZE,MAAM,kFAGFH,EAAMC,QACZG,aAAaJ,EAAMC,GACkB,kBAA/BD,GAAKK,UAAUJ,GAAMK,YACzBH,UAAUF,kDCzBfM,EAAU,SAACN,yBACQA,QAGnBO,EAAU,SAACP,EAAMQ,cACV,wBACID,QAAQD,EAAQN,GAAOS,KAAKC,UAAUF,KAClD,0BAIQT,EAAMC,MACTW,GAAQF,KAAKG,MAAMC,aAAaC,QAAQR,EAAQN,IAClDW,OACGP,UAAUJ,GAAMe,MAAQJ,wBAGzBX,KAAAA,iCAGIG,aAAaa,KAAKC,MAAOjB,KACvBA,EAAMgB,KAAKC,MAAMb,UAAUJ,GAAMe,YACpCT,EAAQN,IAASgB,KAAKC,MAAMC,IAAIC,OAAO,iBACnCH,MAAKC,MAAMb,UAAUJ,GAAMe,OACjC,SAACK,KACMpB,EAAMoB,WAER,+BAIHd,EAAQN,YACNgB,MAAKV,EAAQN"} -------------------------------------------------------------------------------- /packages/vuet-store/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuet-store", 3 | "version": "0.0.2", 4 | "description": "vuet store", 5 | "main": "dist/vuet-store.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "medatc", 10 | "license": "MIT", 11 | "files": [ 12 | "dist/", 13 | "src/" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/vuet-store/src/index.js: -------------------------------------------------------------------------------- 1 | import debug from '../../../src/debug' 2 | 3 | const getName = (path) => { 4 | return `__vuet_store_${path}__` 5 | } 6 | 7 | const setItem = (path, data) => { 8 | setTimeout(() => { 9 | localStorage.setItem(getName(path), JSON.stringify(data)) 10 | }, 0) 11 | } 12 | 13 | export default { 14 | addModule (vuet, path) { 15 | const store = JSON.parse(localStorage.getItem(getName(path))) 16 | if (store) { 17 | vuet.getModule(path).state = store 18 | } 19 | }, 20 | rule ({ path }) { 21 | return { 22 | created () { 23 | debug.assertModule(this.$vuet, path) 24 | setItem(path, this.$vuet.getModule(path).state) 25 | this[getName(path)] = this.$vuet.app.$watch(function () { 26 | return this.$vuet.getModule(path).state 27 | }, (newVal) => { 28 | setItem(path, newVal) 29 | }, { 30 | deep: true 31 | }) 32 | }, 33 | destroyed () { 34 | this[getName(path)]() 35 | delete this[getName(path)] 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/debug.js: -------------------------------------------------------------------------------- 1 | import { _Vue } from './vuet-static' 2 | 3 | const NAME = '__name__' 4 | 5 | export default { 6 | error (msg) { 7 | throw new Error(`[${NAME}] ${msg}`) 8 | }, 9 | warn (msg) { 10 | if (process.env.NODE_ENV !== 'production') { 11 | typeof console !== 'undefined' && console.warn(`[${NAME}] ${msg}`) 12 | } 13 | }, 14 | assertModule (vuet, path) { 15 | if (path in vuet.modules) { 16 | return 17 | } 18 | this.error(`The '${path}' module does not exist`) 19 | }, 20 | assertVue () { 21 | if (!_Vue) { 22 | this.error('must call Vue.use(Vuet) before creating a store instance') 23 | } 24 | }, 25 | assertFetch (vuet, path) { 26 | this.assertModule(vuet, path) 27 | if (typeof vuet.getModule(path).fetch !== 'function') { 28 | this.error(`'${path}' module 'fetch' must be the function type`) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import rules from './rules/index' 2 | import VuetStatic from './vuet-static' 3 | import Vuet from './vuet' 4 | 5 | VuetStatic(Vuet) 6 | rules(Vuet) 7 | export const mapRules = Vuet.mapRules.bind(Vuet) 8 | export const mapModules = Vuet.mapModules.bind(Vuet) 9 | 10 | export default Vuet 11 | -------------------------------------------------------------------------------- /src/rules/index.js: -------------------------------------------------------------------------------- 1 | import need from './need' 2 | import once from './once' 3 | import reset from './reset' 4 | import temp from './temp' 5 | 6 | export default function install (Vuet) { 7 | Vuet 8 | .rule('need', need) 9 | .rule('once', once) 10 | .rule('temp', temp) 11 | .rule('reset', reset) 12 | } 13 | -------------------------------------------------------------------------------- /src/rules/need.js: -------------------------------------------------------------------------------- 1 | import debug from '../debug' 2 | 3 | export default { 4 | rule ({ path }) { 5 | return { 6 | beforeCreate () { 7 | debug.assertFetch(this.$vuet, path) 8 | this.$vuet.getModule(path).fetch() 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/rules/once.js: -------------------------------------------------------------------------------- 1 | import debug from '../debug' 2 | import util from '../util' 3 | 4 | const NAME = '__once__' 5 | 6 | export default { 7 | init (vuet) { 8 | vuet[NAME] = [] 9 | }, 10 | rule ({ path }) { 11 | return { 12 | beforeCreate () { 13 | debug.assertFetch(this.$vuet, path) 14 | const vuet = this.$vuet 15 | if (vuet[NAME].indexOf(path) > -1) return 16 | const back = this.$vuet.getModule(path).fetch() 17 | if (util.isPromise(back)) { 18 | return back.then(res => { 19 | vuet[NAME].push(path) 20 | }) 21 | } 22 | vuet[NAME].push(path) 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/rules/reset.js: -------------------------------------------------------------------------------- 1 | import debug from '../debug' 2 | 3 | export default { 4 | rule ({ path }) { 5 | return { 6 | beforeCreate () { 7 | debug.assertModule(this.$vuet, path) 8 | }, 9 | destroyed () { 10 | this.$vuet.getModule(path).reset() 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/rules/temp.js: -------------------------------------------------------------------------------- 1 | import debug from '../debug' 2 | 3 | export default { 4 | rule ({ path }) { 5 | return { 6 | beforeCreate () { 7 | debug.assertFetch(this.$vuet, path) 8 | this.$vuet.getModule(path).fetch() 9 | }, 10 | destroyed () { 11 | this.$vuet.getModule(path).reset() 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | const util = { 2 | isObject (obj) { 3 | return !!obj && Object.prototype.toString.call(obj) === '[object Object]' 4 | }, 5 | getArgMerge () { 6 | let opt = {} 7 | const args = arguments 8 | if (typeof args[0] === 'string') { 9 | opt[args[0]] = args.length > 1 ? args[1] : args[0] 10 | } else if (args[0] && util.isObject(args[0])) { 11 | opt = args[0] 12 | } 13 | return opt 14 | }, 15 | isPromise (obj) { 16 | return (typeof obj === 'object' || typeof obj === 'function') && !!obj && typeof obj.then === 'function' 17 | } 18 | } 19 | 20 | export default util 21 | -------------------------------------------------------------------------------- /src/vuet-static.js: -------------------------------------------------------------------------------- 1 | import debug from './debug' 2 | import util from './util' 3 | 4 | export let _Vue 5 | 6 | export default function (Vuet) { 7 | Object.assign(Vuet, { 8 | installed: false, 9 | options: { 10 | rules: {}, 11 | module: { 12 | reset () { 13 | this.state = this.data() 14 | return this 15 | } 16 | } 17 | }, 18 | install (Vue) { 19 | if (this.installed) return this 20 | this.installed = true 21 | _Vue = Vue 22 | Object.defineProperty(Vue.prototype, '$vuet', { 23 | get () { return this.$root._vuet } 24 | }) 25 | Vue.mixin({ 26 | beforeCreate () { 27 | if (typeof this.$options.vuet !== 'undefined') { 28 | if (this.$options.vuet instanceof Vuet) { 29 | this._vuet = this.$options.vuet 30 | this._vuet._init(this) 31 | } 32 | } 33 | }, 34 | destroyed () { 35 | if (typeof this.$options.vuet !== 'undefined') { 36 | if (this.$options.vuet instanceof Vuet) { 37 | this._vuet.destroy(this) 38 | } 39 | } 40 | } 41 | }) 42 | return this 43 | }, 44 | mapModules (opts) { 45 | const mixins = Object.keys(opts).map(alias => { 46 | const path = opts[alias] 47 | return { 48 | computed: { 49 | [alias]: { 50 | get () { 51 | debug.assertModule(this.$vuet, path) 52 | return this.$vuet.getModule(path) 53 | }, 54 | set (val) { 55 | debug.error(`The'${path}'module is not allowed to assign`) 56 | } 57 | } 58 | } 59 | } 60 | }) 61 | return { 62 | mixins 63 | } 64 | }, 65 | mapRules () { 66 | const opts = util.getArgMerge.apply(null, arguments) 67 | const vueRules = [] 68 | const addRule = (ruleName, any) => { 69 | const rules = Vuet.options.rules[ruleName] 70 | if (!util.isObject(rules)) debug.error(`The'${ruleName}'rule does not exist. Please make sure that it executes 'Vuet.rule('${ruleName}', opts)' before all components`) 71 | if (typeof any === 'string') { 72 | vueRules.push(rules.rule({ path: any })) 73 | } else { 74 | vueRules.push(rules.rule(any)) 75 | } 76 | } 77 | Object.keys(opts).forEach(ruleName => { 78 | const any = opts[ruleName] 79 | if (Array.isArray(any)) { 80 | return any.forEach(item => { 81 | addRule(ruleName, item) 82 | }) 83 | } 84 | addRule(ruleName, any) 85 | }) 86 | return { 87 | mixins: vueRules 88 | } 89 | }, 90 | rule () { 91 | Vuet.options.rules[arguments[0]] = arguments[1] 92 | if (typeof arguments[1].install === 'function') { 93 | arguments[1].install(Vuet, _Vue) 94 | } 95 | return this 96 | }, 97 | callRuleHook (hook, ...arg) { 98 | Object.keys(Vuet.options.rules).forEach(k => { 99 | if (typeof Vuet.options.rules[k][hook] === 'function') { 100 | Vuet.options.rules[k][hook].apply(undefined, arg) 101 | } 102 | }) 103 | } 104 | }) 105 | } 106 | -------------------------------------------------------------------------------- /src/vuet.js: -------------------------------------------------------------------------------- 1 | import debug from './debug' 2 | import util from './util' 3 | import { _Vue } from './vuet-static' 4 | export default class Vuet { 5 | constructor (opts) { 6 | debug.assertVue() 7 | // debug.assertPromise() 8 | this.version = '__version__' 9 | this.modules = {} 10 | this.store = {} 11 | this.options = { 12 | pathJoin: '/', 13 | modules: {} 14 | } 15 | this.app = null 16 | this.vm = new _Vue({ 17 | data: { 18 | modules: this.store 19 | } 20 | }) 21 | Object.assign(this.options, opts) 22 | Vuet.callRuleHook('init', this) 23 | Object.keys(this.options.modules).forEach(k => { 24 | this.addModules(k, this.options.modules[k]) 25 | }) 26 | } 27 | _init (app) { 28 | this.app = app 29 | } 30 | addModules (path, modules) { 31 | if (util.isObject(modules.modules)) { 32 | Object.keys(modules.modules).forEach(k => { 33 | this.addModules(`${path}${this.options.pathJoin}${k}`, modules.modules[k]) 34 | }) 35 | } 36 | if (typeof modules.data !== 'function') return this 37 | const vuet = this 38 | const opts = { ...Vuet.options.module, ...modules } 39 | _Vue.set(vuet.store, path, opts.data()) 40 | vuet.modules[path] = opts 41 | Object.defineProperty(opts, 'vuet', { 42 | get: () => (vuet) 43 | }) 44 | Object.defineProperty(opts, 'app', { 45 | get: () => (vuet.app) 46 | }) 47 | Object.defineProperty(opts, 'state', { 48 | get () { 49 | return vuet.store[path] 50 | }, 51 | set (val) { 52 | vuet.store[path] = val 53 | } 54 | }) 55 | Object.keys(opts).forEach(k => { 56 | if (typeof opts[k] === 'function') { 57 | const native = opts[k] 58 | opts[k] = function proxy () { 59 | return native.apply(vuet.modules[path], arguments) 60 | } 61 | } 62 | }) 63 | if (util.isObject(opts.state)) { 64 | Object.keys(opts.state).forEach(k => { 65 | if (k in opts) { 66 | return debug.warn(`'${path}' the '${k}' already exists on the object`) 67 | } 68 | Object.defineProperty(opts, k, { 69 | get () { 70 | return vuet.store[path][k] 71 | }, 72 | set (val) { 73 | vuet.store[path][k] = val 74 | } 75 | }) 76 | }) 77 | } 78 | Vuet.callRuleHook('addModule', this, path) 79 | return this.getModule(path) 80 | } 81 | getModule (path) { 82 | debug.assertModule(this, path) 83 | return this.modules[path] 84 | } 85 | getState (path) { 86 | debug.assertModule(this, path) 87 | return this.modules[path].state 88 | } 89 | replaceStore (store) { 90 | this.store = this.vm.$data.modules = store 91 | return this 92 | } 93 | destroy () { 94 | this.vm.$destroy() 95 | Vuet.callRuleHook('destroy', this) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /test/e2e/base.test.js: -------------------------------------------------------------------------------- 1 | import { Selector } from 'testcafe' 2 | 3 | fixture`base` 4 | .page`http://localhost:3000/base/index.html` 5 | 6 | test('base', async t => { 7 | await t 8 | .expect(Selector('.count').textContent).eql('1000') 9 | // plus 10 | .click('button:nth-of-type(1)') 11 | .expect(Selector('.count').textContent).eql('1001') 12 | // reduce 13 | .click('button:nth-of-type(2)') 14 | .expect(Selector('.count').textContent).eql('1000') 15 | // reset 16 | .click('button:nth-of-type(3)') 17 | .expect(Selector('.count').textContent).eql('0') 18 | // fetch 19 | .click('button:nth-of-type(4)') 20 | .expect(Selector('.count').textContent).eql('1000') 21 | }) 22 | -------------------------------------------------------------------------------- /test/e2e/need.test.js: -------------------------------------------------------------------------------- 1 | import { Selector } from 'testcafe' 2 | 3 | fixture`need` 4 | .page`http://localhost:3000/need/index.html` 5 | 6 | test('base', async t => { 7 | await t 8 | .expect(Selector('.count').textContent).eql('0') 9 | .expect(Selector('.fetch-count').textContent).eql('0') 10 | 11 | .click('button') 12 | .wait(100) 13 | .expect(Selector('.count').textContent).eql('1') 14 | .expect(Selector('.fetch-count').textContent).eql('1') 15 | 16 | .click('button') 17 | .wait(100) 18 | .expect(Selector('.count').textContent).eql('1') 19 | .expect(Selector('.fetch-count').textContent).eql('1') 20 | 21 | .click('button') 22 | .wait(100) 23 | .expect(Selector('.count').textContent).eql('2') 24 | .expect(Selector('.fetch-count').textContent).eql('2') 25 | 26 | .click('button') 27 | .wait(100) 28 | .expect(Selector('.count').textContent).eql('2') 29 | .expect(Selector('.fetch-count').textContent).eql('2') 30 | }) 31 | -------------------------------------------------------------------------------- /test/e2e/once.test.js: -------------------------------------------------------------------------------- 1 | import { Selector } from 'testcafe' 2 | 3 | fixture`once` 4 | .page`http://localhost:3000/once/index.html` 5 | 6 | test('base', async t => { 7 | await t 8 | .expect(Selector('.count').textContent).eql('0') 9 | .expect(Selector('.fetch-count').textContent).eql('0') 10 | 11 | .click('button') 12 | .expect(Selector('.count').textContent).eql('1') 13 | .expect(Selector('.fetch-count').textContent).eql('1') 14 | 15 | .click('button') 16 | .expect(Selector('.count').textContent).eql('1') 17 | .expect(Selector('.fetch-count').textContent).eql('1') 18 | 19 | .click('button') 20 | .expect(Selector('.count').textContent).eql('1') 21 | .expect(Selector('.fetch-count').textContent).eql('1') 22 | 23 | .click('button') 24 | .expect(Selector('.count').textContent).eql('1') 25 | .expect(Selector('.fetch-count').textContent).eql('1') 26 | }) 27 | -------------------------------------------------------------------------------- /test/e2e/scroll-cnode.test.js: -------------------------------------------------------------------------------- 1 | import os from 'os' 2 | import { Selector, ClientFunction } from 'testcafe' 3 | 4 | fixture`scroll-cnode` 5 | .page`http://localhost:3000/scroll-cnode/index.html` 6 | 7 | test('base', async t => { 8 | const type = os.type().toLowerCase() 9 | 10 | if (type === 'linux' || type === 'ubuntu') return 11 | await Selector('.list li', { visibilityCheck: true, timeout: 60000 })() 12 | await ClientFunction(() => { 13 | window.scrollTo(0, 300) 14 | return { 15 | x: window.pageXOffset, 16 | y: window.pageYOffset 17 | } 18 | })() 19 | await t 20 | .click('.list li:nth-child(20) a') 21 | .click('.detail-back') 22 | .expect(await ClientFunction(() => { 23 | return { 24 | x: window.pageXOffset, 25 | y: window.pageYOffset 26 | } 27 | })()).eql({ x: 0, y: 300 }) 28 | .click('header ul li:nth-child(2) a') 29 | .expect(await ClientFunction(() => { 30 | return { 31 | x: window.pageXOffset, 32 | y: window.pageYOffset 33 | } 34 | })()).eql({ x: 0, y: 0 }) 35 | 36 | await Selector('.list li', { visibilityCheck: true, timeout: 60000 })() 37 | await ClientFunction(() => { 38 | window.scrollTo(0, 400) 39 | return { 40 | x: window.pageXOffset, 41 | y: window.pageYOffset 42 | } 43 | })() 44 | await t 45 | .click('.list li:nth-child(25) a') 46 | .click('.detail-back') 47 | .expect(await ClientFunction(() => { 48 | return { 49 | x: window.pageXOffset, 50 | y: window.pageYOffset 51 | } 52 | })()).eql({ x: 0, y: 400 }) 53 | 54 | await ClientFunction(() => { 55 | window.scrollTo(0, 450) 56 | return { 57 | x: window.pageXOffset, 58 | y: window.pageYOffset 59 | } 60 | })() 61 | await t 62 | .click('.list li:nth-child(30) a') 63 | .click('.detail-back') 64 | .expect(await ClientFunction(() => { 65 | return { 66 | x: window.pageXOffset, 67 | y: window.pageYOffset 68 | } 69 | })()).eql({ x: 0, y: 450 }) 70 | }) 71 | -------------------------------------------------------------------------------- /test/e2e/scroll-route.test.js: -------------------------------------------------------------------------------- 1 | import { Selector, ClientFunction } from 'testcafe' 2 | 3 | fixture`scroll-route` 4 | .page`http://localhost:3000/scroll-route/index.html` 5 | 6 | test('area scroll forward and back', async t => { 7 | await t 8 | // list page 9 | .expect(Selector('.list-view').scrollTop).eql(0) 10 | .expect(Selector('.list-view').scrollLeft).eql(0) 11 | .click(Selector('.list-set-area-scroll')) 12 | .expect(Selector('.list-view').scrollTop).eql(500) 13 | .expect(Selector('.list-view').scrollLeft).eql(500) 14 | .click(Selector('.list-to-detail-1')) 15 | 16 | // detail page 17 | .expect(Selector('.detail-view').scrollTop).eql(0) 18 | .expect(Selector('.detail-view').scrollLeft).eql(0) 19 | .click(Selector('.detail-set-area-scroll')) 20 | .expect(Selector('.detail-view').scrollTop).eql(500) 21 | .expect(Selector('.detail-view').scrollLeft).eql(500) 22 | .click(Selector('.detail-to-list-1')) 23 | 24 | // list page 25 | .expect(Selector('.list-view').scrollTop).eql(500) 26 | .expect(Selector('.list-view').scrollLeft).eql(500) 27 | .click(Selector('.list-to-detail-1')) 28 | 29 | // detail page 30 | .expect(Selector('.detail-view').scrollTop).eql(500) 31 | .expect(Selector('.detail-view').scrollLeft).eql(500) 32 | .click(Selector('.detail-to-list-2')) 33 | 34 | // list page 35 | .expect(Selector('.list-view').scrollTop).eql(0) 36 | .expect(Selector('.list-view').scrollLeft).eql(0) 37 | .click(Selector('.list-to-detail-2')) 38 | 39 | // detail page 40 | .expect(Selector('.detail-view').scrollTop).eql(0) 41 | .expect(Selector('.detail-view').scrollLeft).eql(0) 42 | }) 43 | 44 | test('window scroll forward and back', async t => { 45 | const getWindowScrolls = ClientFunction(() => { 46 | return { 47 | x: window.pageXOffset, 48 | y: window.pageYOffset 49 | } 50 | }) 51 | await t 52 | // list page 53 | .expect(Selector('.list-view').scrollTop).eql(0) 54 | .expect(Selector('.list-view').scrollLeft).eql(0) 55 | .click(Selector('.list-set-window-scroll')) 56 | .expect(getWindowScrolls()).eql({ x: 30, y: 100 }) 57 | .click(Selector('.list-to-detail-1')) 58 | 59 | // detail page 60 | .expect(Selector('.detail-view').scrollTop).eql(0) 61 | .expect(Selector('.detail-view').scrollLeft).eql(0) 62 | .click(Selector('.detail-set-window-scroll')) 63 | .expect(getWindowScrolls()).eql({ x: 30, y: 100 }) 64 | .click(Selector('.detail-to-list-1')) 65 | 66 | // list page 67 | .expect(getWindowScrolls()).eql({ x: 30, y: 100 }) 68 | .click(Selector('.list-to-detail-1')) 69 | 70 | // detail page 71 | .expect(getWindowScrolls()).eql({ x: 30, y: 100 }) 72 | .click(Selector('.detail-to-list-2')) 73 | 74 | // list page 75 | .expect(getWindowScrolls()).eql({ x: 0, y: 0 }) 76 | .click(Selector('.list-to-detail-2')) 77 | 78 | // detail page 79 | .expect(getWindowScrolls()).eql({ x: 0, y: 0 }) 80 | }) 81 | -------------------------------------------------------------------------------- /test/e2e/scroll-self.test.js: -------------------------------------------------------------------------------- 1 | import { Selector, ClientFunction } from 'testcafe' 2 | 3 | fixture`scroll-self` 4 | .page`http://localhost:3000/scroll-self/index.html` 5 | 6 | const scrollTo = ClientFunction((el, scrolls) => { 7 | scrollTo(document.querySelector(el), scrolls) 8 | function scrollTo (el, scrolls) { 9 | if ('scrollTop' in el && el !== window) { 10 | el.scrollLeft = scrolls.x 11 | el.scrollTop = scrolls.y 12 | } else { 13 | el.scrollTo(scrolls.x, scrolls.y) 14 | } 15 | } 16 | return {} 17 | }) 18 | 19 | test('base', async t => { 20 | await Selector('.view .inner', { visibilityCheck: true, timeout: 60000 })() 21 | await t 22 | .expect(Selector('.x').textContent).eql('50') 23 | .expect(Selector('.y').textContent).eql('60') 24 | .expect(Selector('.view').scrollLeft).eql(50) 25 | .expect(Selector('.view').scrollTop).eql(60) 26 | .expect(scrollTo('.view', { x: 70, y: 80 })).eql({}) 27 | 28 | .click('button.view-2') 29 | .expect(Selector('.x').textContent).eql('280') 30 | .expect(Selector('.y').textContent).eql('300') 31 | .expect(Selector('.view').scrollLeft).eql(280) 32 | .expect(Selector('.view').scrollTop).eql(300) 33 | .expect(scrollTo('.view', { x: 290, y: 310 })).eql({}) 34 | 35 | .click('button.view-3') 36 | .expect(Selector('.x').textContent).eql('0') 37 | .expect(Selector('.y').textContent).eql('0') 38 | .expect(Selector('.view').scrollLeft).eql(0) 39 | .expect(Selector('.view').scrollTop).eql(0) 40 | .expect(scrollTo('.view', { x: 10, y: 20 })).eql({}) 41 | 42 | .click('button.view-1') 43 | .expect(Selector('.x').textContent).eql('70') 44 | .expect(Selector('.y').textContent).eql('80') 45 | .expect(Selector('.view').scrollLeft).eql(70) 46 | .expect(Selector('.view').scrollTop).eql(80) 47 | 48 | .click('button.view-2') 49 | .expect(Selector('.x').textContent).eql('290') 50 | .expect(Selector('.y').textContent).eql('310') 51 | .expect(Selector('.view').scrollLeft).eql(290) 52 | .expect(Selector('.view').scrollTop).eql(310) 53 | 54 | .click('button.view-3') 55 | .expect(Selector('.x').textContent).eql('10') 56 | .expect(Selector('.y').textContent).eql('20') 57 | .expect(Selector('.view').scrollLeft).eql(10) 58 | .expect(Selector('.view').scrollTop).eql(20) 59 | }) 60 | -------------------------------------------------------------------------------- /test/e2e/scroll-sync.test.js: -------------------------------------------------------------------------------- 1 | import { Selector, ClientFunction } from 'testcafe' 2 | 3 | fixture`scroll-sync` 4 | .page`http://localhost:3000/scroll-sync/index.html` 5 | 6 | test('window scroll', async t => { 7 | const getWindowScrolls = ClientFunction(() => ({ 8 | x: window.pageXOffset, 9 | y: window.pageYOffset 10 | })) 11 | await Selector('.inner', { visibilityCheck: true })() 12 | await t 13 | .expect(Selector('header .window .x').textContent).eql('200') 14 | .expect(Selector('header .window .y').textContent).eql('300') 15 | .expect((await getWindowScrolls())).eql({ x: 200, y: 300 }) 16 | .click(Selector('header .window button')) 17 | await t 18 | .expect(Selector('header .window .x').textContent).eql('100') 19 | .expect(Selector('header .window .y').textContent).eql('200') 20 | .expect((await getWindowScrolls())).eql({ x: 100, y: 200 }) 21 | }) 22 | 23 | test('area scroll', async t => { 24 | await Selector('ul', { visibilityCheck: true })() 25 | await t 26 | .expect(Selector('header .area .x').textContent).eql('100') 27 | .expect(Selector('header .area .y').textContent).eql('500') 28 | .click('.inner') 29 | .expect(Selector('ul:nth-child(1)').scrollLeft).eql(100) 30 | .expect(Selector('ul:nth-child(1)').scrollTop).eql(500) 31 | .expect(Selector('ul:nth-child(2)').scrollLeft).eql(100) 32 | .expect(Selector('ul:nth-child(2)').scrollTop).eql(500) 33 | .click('header .area button') 34 | .expect(Selector('ul:nth-child(1)').scrollLeft).eql(200) 35 | .expect(Selector('ul:nth-child(1)').scrollTop).eql(800) 36 | .expect(Selector('ul:nth-child(2)').scrollLeft).eql(200) 37 | .expect(Selector('ul:nth-child(2)').scrollTop).eql(800) 38 | .expect(Selector('header .area .x').textContent).eql('200') 39 | .expect(Selector('header .area .y').textContent).eql('800') 40 | }) 41 | -------------------------------------------------------------------------------- /test/e2e/store.test.js: -------------------------------------------------------------------------------- 1 | import { Selector, ClientFunction } from 'testcafe' 2 | 3 | fixture`store` 4 | .page`http://localhost:3000/store/index.html` 5 | 6 | test('store', async t => { 7 | const localStorage = ClientFunction(() => { 8 | return JSON.parse(localStorage.getItem('__vuet_store_test__')) 9 | }) 10 | await t 11 | .expect(Selector('.count').textContent).eql('1000') 12 | .expect(localStorage()).eql({ count: 1000 }) 13 | // plus 14 | .click('button:nth-of-type(1)') 15 | .expect(Selector('.count').textContent).eql('1001') 16 | .expect(localStorage()).eql({ count: 1001 }) 17 | // reduce 18 | .click('button:nth-of-type(2)') 19 | .expect(Selector('.count').textContent).eql('1000') 20 | .expect(localStorage()).eql({ count: 1000 }) 21 | // reset 22 | .click('button:nth-of-type(3)') 23 | .expect(Selector('.count').textContent).eql('0') 24 | .expect(localStorage()).eql({ count: 0 }) 25 | // fetch 26 | .click('button:nth-of-type(4)') 27 | .expect(Selector('.count').textContent).eql('1000') 28 | .expect(localStorage()).eql({ count: 1000 }) 29 | }) 30 | -------------------------------------------------------------------------------- /test/e2e/temp.test.js: -------------------------------------------------------------------------------- 1 | import { Selector } from 'testcafe' 2 | 3 | fixture`temp` 4 | .page`http://localhost:3000/temp/index.html` 5 | 6 | test('base', async t => { 7 | await t 8 | .expect(Selector('.count').textContent).eql('0') 9 | .expect(Selector('.fetch-count').textContent).eql('0') 10 | 11 | .click('button') 12 | .expect(Selector('.count').textContent).eql('1') 13 | .expect(Selector('.fetch-count').textContent).eql('1') 14 | 15 | .click('button') 16 | .expect(Selector('.count').textContent).eql('0') 17 | .expect(Selector('.fetch-count').textContent).eql('0') 18 | 19 | .click('button') 20 | .expect(Selector('.count').textContent).eql('1') 21 | .expect(Selector('.fetch-count').textContent).eql('2') 22 | 23 | .click('button') 24 | .expect(Selector('.count').textContent).eql('0') 25 | .expect(Selector('.fetch-count').textContent).eql('0') 26 | }) 27 | -------------------------------------------------------------------------------- /test/e2e/v-model.js: -------------------------------------------------------------------------------- 1 | import { Selector } from 'testcafe' 2 | 3 | fixture`v-model` 4 | .page`http://localhost:3000/v-model/index.html` 5 | 6 | test('base', async t => { 7 | await t 8 | .expect(Selector('.root-content').textContent).eql('') 9 | .expect(Selector('.input-content').textContent).eql('') 10 | .expect(Selector('.output-content').textContent).eql('') 11 | .typeText(Selector('.input'), 'ok') 12 | .expect(Selector('.root-content').textContent).eql('ok') 13 | .expect(Selector('.input-content').textContent).eql('ok') 14 | .expect(Selector('.output-content').textContent).eql('ok') 15 | .click('button') 16 | .expect(Selector('.root-content').textContent).eql('ok') 17 | .expect(Selector('.input-content').textContent).eql('ok') 18 | .click('button') 19 | .typeText(Selector('.input'), 'go') 20 | .expect(Selector('.root-content').textContent).eql('okgo') 21 | .expect(Selector('.input-content').textContent).eql('okgo') 22 | .expect(Selector('.output-content').textContent).eql('okgo') 23 | }) 24 | -------------------------------------------------------------------------------- /test/unit/debug.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import Vue from 'vue' 3 | import Vuet from '../../src/index' 4 | import debug from '../../src/debug' 5 | 6 | test.serial('error', t => { 7 | try { 8 | debug.error('ok') 9 | } catch (e) { 10 | t.is(e.toString(), 'Error: [__name__] ok') 11 | } 12 | }) 13 | 14 | test.serial('warn', t => { 15 | const warn = console.warn 16 | let warnCount = 0 17 | console.warn = (msg) => { 18 | warnCount++ 19 | warn.call(console, msg) 20 | } 21 | debug.warn('ok') 22 | t.is(warnCount, 1) 23 | console.warn = warn 24 | const env = process.env.NODE_ENV 25 | process.env.NODE_ENV = 'production' 26 | debug.warn('warn ok') 27 | process.env.NODE_ENV = env 28 | t.pass() 29 | }) 30 | 31 | test.serial('assertVue', t => { 32 | try { 33 | debug.assertVue() 34 | } catch (e) { 35 | t.is(e.toString(), 'Error: [__name__] must call Vue.use(Vuet) before creating a store instance') 36 | } 37 | Vue.use(Vuet) 38 | debug.assertVue() 39 | }) 40 | 41 | test.serial('assertModule', t => { 42 | const vuet = new Vuet() 43 | vuet.addModules('test', { 44 | data () { 45 | return true 46 | } 47 | }) 48 | t.true(vuet.getModule('test').state) 49 | debug.assertModule(vuet, 'test') 50 | try { 51 | debug.assertModule(vuet, 'ok') 52 | } catch (e) { 53 | t.is(e.toString(), 'Error: [__name__] The \'ok\' module does not exist') 54 | } 55 | }) 56 | 57 | test('assertFetch', t => { 58 | const vuet = new Vuet({ 59 | modules: { 60 | test: { 61 | data () { 62 | return {} 63 | } 64 | } 65 | } 66 | }) 67 | let errMsg = '' 68 | let vm = null 69 | try { 70 | vm = new Vue({ 71 | mixins: [ 72 | Vuet.mapRules({ 73 | need: 'test' 74 | }) 75 | ], 76 | vuet 77 | }) 78 | } catch (e) { 79 | errMsg = e.toString() 80 | } 81 | t.is(vm, null) 82 | t.is(errMsg, 'Error: [__name__] \'test\' module \'fetch\' must be the function type') 83 | }) 84 | -------------------------------------------------------------------------------- /test/unit/util.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import util from '../../src/util' 3 | 4 | test('getArgMerge', t => { 5 | t.deepEqual(util.getArgMerge('name'), { name: 'name' }) 6 | t.deepEqual(util.getArgMerge('name', 'vuet'), { name: 'vuet' }) 7 | t.deepEqual(util.getArgMerge({ name: 'vuet' }), { name: 'vuet' }) 8 | t.deepEqual(util.getArgMerge(), {}) 9 | t.deepEqual(util.getArgMerge({}), {}) 10 | }) 11 | 12 | test('is object', t => { 13 | t.true(util.isObject({})) 14 | t.false(util.isObject(null)) 15 | }) 16 | 17 | test('is promise', t => { 18 | t.false(util.isPromise(null)) 19 | t.false(util.isPromise(true)) 20 | t.false(util.isPromise(false)) 21 | t.false(util.isPromise(0)) 22 | t.false(util.isPromise([])) 23 | 24 | // object 25 | t.false(util.isPromise({})) 26 | t.false(util.isPromise({ 27 | then: {} 28 | })) 29 | t.true(util.isPromise({ 30 | then () {} 31 | })) 32 | 33 | // function 34 | t.false(util.isPromise(function () {})) 35 | const myPromise = function () {} 36 | myPromise.then = function () {} 37 | t.true(util.isPromise(myPromise)) 38 | myPromise.then = [] 39 | t.false(util.isPromise(myPromise)) 40 | 41 | // promise 42 | t.true(util.isPromise(new Promise(function () {}))) 43 | t.true(util.isPromise(Promise.resolve({}))) 44 | }) 45 | -------------------------------------------------------------------------------- /test/unit/vue-route.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import Vue from 'vue' 3 | import Vuet, { mapRules } from '../../src/index' 4 | import VuetRoute from '../../packages/vuet-route/src/index' 5 | 6 | Vue.use(Vuet) 7 | 8 | Vuet.rule('route', VuetRoute) 9 | 10 | test.serial('add rule', t => { 11 | t.is(Vuet.options.rules.route, VuetRoute) 12 | }) 13 | 14 | test.serial('all error msg', t => { 15 | const vuet = new Vuet() 16 | vuet.addModules('test', { 17 | data () { 18 | return 0 19 | }, 20 | fetch () {} 21 | }) 22 | let errMsg = '' 23 | let vm = null 24 | try { 25 | vm = new Vue({ 26 | vuet, 27 | mixins: [ 28 | mapRules({ 29 | route: 'test' 30 | }) 31 | ] 32 | }) 33 | } catch (e) { 34 | errMsg = e.toString() 35 | } 36 | t.is(errMsg, 'Error: [__name__] The \'vue-router\' module is not installed') 37 | // Analog routing 38 | Vue.prototype.$route = new Vue({ 39 | data () { 40 | return { 41 | fullPath: '/', 42 | query: {}, 43 | params: {} 44 | } 45 | }, 46 | fetch () {} 47 | }).$data 48 | try { 49 | vm = new Vue({ 50 | vuet, 51 | mixins: [ 52 | mapRules({ 53 | route: 'test' 54 | }) 55 | ] 56 | }) 57 | } catch (e) { 58 | errMsg = e.toString() 59 | } 60 | t.is(errMsg, 'Error: [__name__] \'test\' module state must be the object type') 61 | 62 | vuet.addModules('testFetch', { 63 | data () { 64 | return { 65 | list: [] 66 | } 67 | } 68 | }) 69 | try { 70 | vm = new Vue({ 71 | vuet, 72 | mixins: [ 73 | mapRules({ 74 | route: 'testFetch' 75 | }) 76 | ] 77 | }) 78 | } catch (e) { 79 | errMsg = e.toString() 80 | } 81 | t.is(vm, null) 82 | t.is(errMsg, 'Error: [__name__] \'testFetch\' module \'fetch\' must be the function type') 83 | }) 84 | 85 | test.serial('default init', async t => { 86 | const vuet = new Vuet() 87 | vuet.addModules('test', { 88 | data () { 89 | return { 90 | list: [] 91 | } 92 | }, 93 | count: 0, 94 | fetch () { 95 | this.count++ 96 | this.list.push(this.list.length) 97 | } 98 | }) 99 | t.deepEqual(vuet.__route__, { test: [] }) 100 | t.deepEqual(vuet.getModule('test').state, { list: [] }) 101 | const vm = new Vue({ 102 | vuet, 103 | mixins: [ 104 | mapRules({ 105 | route: 'test' 106 | }) 107 | ] 108 | }) 109 | t.is(vuet.getModule('test').count, 1) 110 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 111 | t.deepEqual(vuet.__route__, { test: [ '"/"' ] }) 112 | 113 | Vue.prototype.$route.fullPath = '/test' 114 | await vm.$nextTick() 115 | t.is(vuet.getModule('test').count, 2) 116 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 117 | t.deepEqual(vuet.__route__, { test: [ '"/test"' ] }) 118 | Vue.prototype.$route.fullPath = '/' 119 | }) 120 | 121 | test.serial('setting watch', async t => { 122 | const vuet = new Vuet() 123 | vuet.addModules('test', { 124 | data () { 125 | return { 126 | list: [] 127 | } 128 | }, 129 | count: 0, 130 | route: { 131 | watch: 'query' 132 | }, 133 | fetch () { 134 | this.count++ 135 | this.list.push(this.list.length) 136 | } 137 | }) 138 | t.deepEqual(vuet.__route__, { test: [] }) 139 | t.deepEqual(vuet.getModule('test').state, { list: [] }) 140 | 141 | let vm = new Vue({ 142 | vuet, 143 | mixins: [ 144 | mapRules({ 145 | route: 'test' 146 | }) 147 | ] 148 | }) 149 | t.is(vuet.getModule('test').count, 1) 150 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 151 | t.deepEqual(vuet.__route__, { test: [ '{}' ] }) 152 | 153 | Vue.prototype.$route.query = { tab: 'all' } 154 | await vm.$nextTick() 155 | t.is(vuet.getModule('test').count, 2) 156 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 157 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"all"}' ] }) 158 | 159 | Vue.prototype.$route.query = { tab: 'all' } 160 | await vm.$nextTick() 161 | t.is(vuet.getModule('test').count, 2) 162 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 163 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"all"}' ] }) 164 | 165 | Vue.prototype.$route.query = { tab: 'end' } 166 | await vm.$nextTick() 167 | t.is(vuet.getModule('test').count, 3) 168 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 169 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"end"}' ] }) 170 | 171 | vm.$destroy() 172 | vm = new Vue({ 173 | vuet, 174 | mixins: [ 175 | mapRules({ 176 | route: 'test' 177 | }) 178 | ] 179 | }) 180 | 181 | t.is(vuet.getModule('test').count, 4) 182 | t.deepEqual(vuet.getModule('test').state, { list: [0, 1], __routeLoaded__: true }) 183 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"end"}' ] }) 184 | 185 | Vue.prototype.$route.query = {} 186 | await vm.$nextTick() 187 | }) 188 | 189 | test.serial('setting once=true', async t => { 190 | const vuet = new Vuet() 191 | vuet.addModules('test', { 192 | data () { 193 | return { 194 | list: [] 195 | } 196 | }, 197 | count: 0, 198 | route: { 199 | watch: 'query', 200 | once: true 201 | }, 202 | fetch () { 203 | this.count++ 204 | this.list.push(this.list.length) 205 | } 206 | }) 207 | t.deepEqual(vuet.__route__, { test: [] }) 208 | t.deepEqual(vuet.getModule('test').state, { list: [] }) 209 | 210 | let vm = new Vue({ 211 | vuet, 212 | mixins: [ 213 | mapRules({ 214 | route: 'test' 215 | }) 216 | ] 217 | }) 218 | t.is(vuet.getModule('test').count, 1) 219 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 220 | t.deepEqual(vuet.__route__, { test: [ '{}' ] }) 221 | 222 | Vue.prototype.$route.query = { tab: 'all' } 223 | await vm.$nextTick() 224 | t.is(vuet.getModule('test').count, 2) 225 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 226 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"all"}' ] }) 227 | 228 | Vue.prototype.$route.query = { tab: 'all' } 229 | await vm.$nextTick() 230 | t.is(vuet.getModule('test').count, 2) 231 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 232 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"all"}' ] }) 233 | 234 | Vue.prototype.$route.query = { tab: 'end' } 235 | await vm.$nextTick() 236 | t.is(vuet.getModule('test').count, 3) 237 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 238 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"end"}' ] }) 239 | 240 | vm.$destroy() 241 | vm = new Vue({ 242 | vuet, 243 | mixins: [ 244 | mapRules({ 245 | route: 'test' 246 | }) 247 | ] 248 | }) 249 | 250 | t.is(vuet.getModule('test').count, 3) 251 | t.deepEqual(vuet.getModule('test').state, { list: [0], __routeLoaded__: true }) 252 | t.deepEqual(vuet.__route__, { test: [ '{"tab":"end"}' ] }) 253 | 254 | Vue.prototype.$route.query = {} 255 | }) 256 | -------------------------------------------------------------------------------- /test/unit/vuet-store.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import Vue from 'vue' 3 | import Vuet, { mapRules, mapModules } from '../../src/index' 4 | import VuetStore from '../../packages/vuet-store/src/index' 5 | 6 | Vue.use(Vuet) 7 | 8 | Vuet.rule('store', VuetStore) 9 | 10 | global.localStorage = { 11 | store: {}, 12 | getItem (key) { 13 | return this.store[key] || null 14 | }, 15 | setItem (key, data) { 16 | this.store[key] = data 17 | } 18 | } 19 | 20 | const delay = (time) => { 21 | return new Promise((resolve) => { 22 | setTimeout(() => { 23 | resolve() 24 | }, time) 25 | }) 26 | } 27 | 28 | test.serial('one', async t => { 29 | const vuet = new Vuet() 30 | vuet.addModules('test', { 31 | data () { 32 | return { 33 | count: 0 34 | } 35 | }, 36 | fetch () { 37 | this.count = 1000 38 | }, 39 | plus () { 40 | this.count++ 41 | }, 42 | reduce () { 43 | this.count-- 44 | } 45 | }) 46 | const vm = new Vue({ 47 | vuet, 48 | mixins: [ 49 | mapModules({ 50 | test: 'test' // { 别名: '模块路径' } 51 | }), 52 | mapRules({ 53 | store: [{ path: 'test' }], // { 规则: ['模块路径'] } 54 | once: [{ path: 'test' }] 55 | }) 56 | ] 57 | }) 58 | 59 | const vtm = vuet.getModule('test') 60 | 61 | t.is(vtm.count, 1000) 62 | t.is(vm.test.count, 1000) 63 | await delay(20) 64 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1000}') 65 | 66 | vtm.plus() 67 | t.is(vtm.count, 1001) 68 | t.is(vm.test.count, 1001) 69 | await delay(20) 70 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1001}') 71 | 72 | vtm.reduce() 73 | t.is(vtm.count, 1000) 74 | t.is(vm.test.count, 1000) 75 | await delay(20) 76 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1000}') 77 | 78 | vtm.reset() 79 | t.is(vtm.count, 0) 80 | t.is(vm.test.count, 0) 81 | await delay(20) 82 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":0}') 83 | 84 | vtm.fetch() 85 | t.is(vtm.count, 1000) 86 | t.is(vm.test.count, 1000) 87 | await delay(20) 88 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1000}') 89 | 90 | vtm.count = 6666 91 | t.is(vtm.count, 6666) 92 | t.is(vm.test.count, 6666) 93 | await delay(20) 94 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":6666}') 95 | }) 96 | 97 | test.serial('two', async t => { 98 | const vuet = new Vuet() 99 | vuet.addModules('test', { 100 | data () { 101 | return { 102 | count: 0 103 | } 104 | }, 105 | fetch () { 106 | this.count = 1000 107 | }, 108 | plus () { 109 | this.count++ 110 | }, 111 | reduce () { 112 | this.count-- 113 | } 114 | }) 115 | 116 | const vtm = vuet.getModule('test') 117 | 118 | t.is(vtm.count, 6666) 119 | await delay(20) 120 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":6666}') 121 | 122 | const vm = new Vue({ 123 | vuet, 124 | mixins: [ 125 | mapModules({ 126 | test: 'test' // { 别名: '模块路径' } 127 | }), 128 | mapRules({ 129 | store: [{ path: 'test' }], // { 规则: ['模块路径'] } 130 | once: [{ path: 'test' }] 131 | }) 132 | ] 133 | }) 134 | 135 | t.is(vtm.count, 1000) 136 | t.is(vm.test.count, 1000) 137 | await delay(20) 138 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1000}') 139 | 140 | vtm.plus() 141 | t.is(vtm.count, 1001) 142 | t.is(vm.test.count, 1001) 143 | await delay(20) 144 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1001}') 145 | 146 | vtm.reduce() 147 | t.is(vtm.count, 1000) 148 | t.is(vm.test.count, 1000) 149 | await delay(20) 150 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1000}') 151 | 152 | vtm.reset() 153 | t.is(vtm.count, 0) 154 | t.is(vm.test.count, 0) 155 | await delay(20) 156 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":0}') 157 | 158 | vtm.fetch() 159 | t.is(vtm.count, 1000) 160 | t.is(vm.test.count, 1000) 161 | await delay(20) 162 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1000}') 163 | 164 | vm.$destroy() 165 | vtm.reset() 166 | t.is(vtm.count, 0) 167 | t.is(vm.test.count, 0) 168 | await delay(20) 169 | t.is(localStorage.getItem('__vuet_store_test__'), '{"count":1000}') 170 | t.is(vm['__vuet_store_test__'], undefined) 171 | }) 172 | -------------------------------------------------------------------------------- /test/unit/vuet.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import Vue from 'vue' 3 | import Vuet, { mapRules, mapModules } from '../../src/index' 4 | 5 | test.before(() => { 6 | Vue.use(Vuet) 7 | }) 8 | 9 | test('is installed', t => { 10 | t.true(Vuet.installed) 11 | Vue.use(Vuet) 12 | t.true(Vuet.installed) 13 | Vuet.install(Vue) 14 | t.true(Vuet.installed) 15 | }) 16 | 17 | function baseExample (t, pathJoin = '/') { 18 | const opts = { 19 | modules: { 20 | test: { 21 | data () { 22 | return { 23 | count: 0 24 | } 25 | }, 26 | plus () { 27 | this.count++ 28 | }, 29 | modules: { 30 | chlid: { 31 | data () { 32 | return { 33 | count: 0 34 | } 35 | }, 36 | plus () { 37 | this.count++ 38 | } 39 | } 40 | } 41 | } 42 | } 43 | } 44 | if (pathJoin !== '/') { 45 | opts.pathJoin = pathJoin 46 | } 47 | const vuet = new Vuet(opts) 48 | vuet.addModules('myTest', { 49 | data () { 50 | return { 51 | count: 0 52 | } 53 | }, 54 | plus () { 55 | this.count++ 56 | } 57 | }) 58 | t.is(vuet.app, null) 59 | const vm = new Vue({ 60 | mixins: [ 61 | mapModules({ 62 | test: 'test', 63 | chlid: `test${pathJoin}chlid`, 64 | myTest: 'myTest' 65 | }) 66 | ], 67 | vuet 68 | }) 69 | t.is(vuet, vm.$vuet) 70 | t.is(vuet.app, vm) 71 | t.true(vuet.vm instanceof Vue) 72 | t.deepEqual(Object.keys(vuet.modules), [`test${pathJoin}chlid`, 'test', 'myTest']) 73 | 74 | // test => vuet 75 | const test = vuet.getModule('test') 76 | test.plus() 77 | t.is(test.count, 1) 78 | t.is(test.state.count, 1) 79 | t.is(vm.test.count, 1) 80 | t.is(vm.test.state.count, 1) 81 | test.reset() 82 | t.is(test.count, 0) 83 | t.is(test.state.count, 0) 84 | t.is(vm.test.count, 0) 85 | t.is(vm.test.state.count, 0) 86 | // test => vm 87 | vm.test.plus() 88 | t.is(test.count, 1) 89 | t.is(test.state.count, 1) 90 | t.is(vm.test.count, 1) 91 | t.is(vm.test.state.count, 1) 92 | vm.test.reset() 93 | t.is(test.count, 0) 94 | t.is(test.state.count, 0) 95 | t.is(vm.test.count, 0) 96 | t.is(vm.test.state.count, 0) 97 | 98 | // test => vuet 99 | const chlid = vuet.getModule(`test${pathJoin}chlid`) 100 | chlid.plus() 101 | t.is(chlid.count, 1) 102 | t.is(chlid.state.count, 1) 103 | t.is(vm.chlid.count, 1) 104 | t.is(vm.chlid.state.count, 1) 105 | chlid.reset() 106 | t.is(chlid.count, 0) 107 | t.is(chlid.state.count, 0) 108 | t.is(vm.chlid.count, 0) 109 | t.is(vm.chlid.state.count, 0) 110 | // chlid => vm 111 | vm.chlid.plus() 112 | t.is(chlid.count, 1) 113 | t.is(chlid.state.count, 1) 114 | t.is(vm.chlid.count, 1) 115 | t.is(vm.chlid.state.count, 1) 116 | vm.chlid.reset() 117 | t.is(chlid.count, 0) 118 | t.is(chlid.state.count, 0) 119 | t.is(vm.chlid.count, 0) 120 | t.is(vm.chlid.state.count, 0) 121 | 122 | // myTest => vuet 123 | const myTest = vuet.getModule('myTest') 124 | myTest.plus() 125 | t.is(myTest.count, 1) 126 | t.is(myTest.state.count, 1) 127 | t.is(vm.myTest.count, 1) 128 | t.is(vm.myTest.state.count, 1) 129 | myTest.reset() 130 | t.is(myTest.count, 0) 131 | t.is(myTest.state.count, 0) 132 | t.is(vm.myTest.count, 0) 133 | t.is(vm.myTest.state.count, 0) 134 | // myTest => vm 135 | vm.myTest.plus() 136 | t.is(myTest.count, 1) 137 | t.is(myTest.state.count, 1) 138 | t.is(vm.myTest.count, 1) 139 | t.is(vm.myTest.state.count, 1) 140 | vm.myTest.reset() 141 | t.is(myTest.count, 0) 142 | t.is(myTest.state.count, 0) 143 | t.is(vm.myTest.count, 0) 144 | t.is(vm.myTest.state.count, 0) 145 | 146 | // set state 147 | vm.test.count = 1001 148 | vm.chlid.count = 1002 149 | vm.myTest.count = 1003 150 | t.is(test.count, 1001) 151 | t.is(chlid.count, 1002) 152 | t.is(myTest.count, 1003) 153 | 154 | // addModules error 155 | let errMsg = '' 156 | try { 157 | vuet.addModules('notData', {}) 158 | } catch (e) { 159 | errMsg = e.toString() 160 | } 161 | t.is(errMsg, '') 162 | 163 | // set module value error 164 | try { 165 | vm.test = 'ok' 166 | } catch (e) { 167 | errMsg = e.toString() 168 | } 169 | t.is(errMsg, 'Error: [__name__] The\'test\'module is not allowed to assign') 170 | } 171 | 172 | test('base', t => { 173 | const vuet = new Vuet({ 174 | modules: false 175 | }) 176 | t.deepEqual(vuet.__once__, []) 177 | baseExample(t, '/') 178 | }) 179 | 180 | test('set path join', t => { 181 | baseExample(t, '-') 182 | }) 183 | 184 | test('static attrs', t => { 185 | t.deepEqual(Object.keys(Vuet.options), ['rules', 'module']) 186 | t.deepEqual(Object.keys(Vuet.options.rules), ['need', 'once', 'temp', 'reset']) 187 | Vuet 188 | .rule('myRule1', { 189 | rule ({ path }) { 190 | return {} 191 | } 192 | }) 193 | .rule('myRule2', { 194 | rule ({ path }) { 195 | return {} 196 | } 197 | }) 198 | t.deepEqual(Object.keys(Vuet.options.rules), ['need', 'once', 'temp', 'reset', 'myRule1', 'myRule2']) 199 | }) 200 | 201 | test('mapModules', t => { 202 | const mixin = Vuet.mapModules({ 203 | list: 'list', 204 | detail: 'detail' 205 | }) 206 | const rules = Vuet.mapRules({ 207 | temp: 'list', 208 | need: ['detail', { path: 'myPath' }], 209 | once: { path: 'myPath' } 210 | }) 211 | t.is(JSON.stringify(mixin), '{"mixins":[{"computed":{"list":{}}},{"computed":{"detail":{}}}]}') 212 | t.is(JSON.stringify(rules), '{"mixins":[{},{},{},{}]}') 213 | }) 214 | 215 | test('callRuleHook', t => { 216 | let installed = false 217 | let initBtn = false 218 | let destroyed = false 219 | let myCallBtn = false 220 | const myRule = { 221 | install () { 222 | t.is(arguments[0], Vuet) 223 | installed = !installed 224 | }, 225 | init () { 226 | t.true(arguments[0] instanceof Vuet) 227 | initBtn = !initBtn 228 | }, 229 | destroy () { 230 | t.true(arguments[0] instanceof Vuet) 231 | destroyed = !destroyed 232 | }, 233 | myCall () { 234 | t.true(arguments[0] instanceof Vuet) 235 | myCallBtn = !myCallBtn 236 | } 237 | } 238 | Vuet.rule('myRule', myRule) 239 | 240 | t.true(installed) 241 | t.false(initBtn) 242 | t.false(destroyed) 243 | t.false(myCallBtn) 244 | 245 | const vuet = new Vuet() 246 | t.true(installed) 247 | t.true(initBtn) 248 | t.false(destroyed) 249 | t.false(myCallBtn) 250 | 251 | new Vue({ vuet }).$destroy() 252 | t.true(installed) 253 | t.true(initBtn) 254 | t.true(destroyed) 255 | t.false(myCallBtn) 256 | 257 | Vuet.callRuleHook('myCall', vuet) 258 | t.true(installed) 259 | t.true(initBtn) 260 | t.true(destroyed) 261 | t.true(myCallBtn) 262 | 263 | t.is(Vuet.options.rules.myRule, myRule) 264 | }) 265 | 266 | test.cb('rules', t => { 267 | const vuet = new Vuet() 268 | const opts = { 269 | data () { 270 | return 0 271 | }, 272 | fetch () { 273 | this.state++ 274 | } 275 | } 276 | vuet.addModules('need', opts) 277 | vuet.addModules('once', opts) 278 | vuet.addModules('temp', opts) 279 | vuet.addModules('reset', opts) 280 | vuet.addModules('oncePromise', { 281 | data () { 282 | return 0 283 | }, 284 | async fetch () { 285 | return new Promise((resolve) => { 286 | setTimeout(() => { 287 | this.state++ 288 | resolve() 289 | }, 30) 290 | }) 291 | } 292 | }) 293 | let vm = new Vue({ 294 | vuet, 295 | mixins: [ 296 | mapRules({ 297 | need: 'need', 298 | once: ['once', 'oncePromise'], 299 | temp: 'temp', 300 | reset: 'reset' 301 | }) 302 | ], 303 | beforeCreate () { 304 | this.$vuet.getModule('reset').fetch() 305 | } 306 | }) 307 | 308 | t.is(vuet.getState('need'), 1) 309 | t.is(vm.$vuet.getState('need'), 1) 310 | t.is(vuet.getState('once'), 1) 311 | t.is(vm.$vuet.getState('once'), 1) 312 | t.is(vuet.getState('oncePromise'), 0) 313 | t.is(vm.$vuet.getState('oncePromise'), 0) 314 | t.is(vuet.getState('temp'), 1) 315 | t.is(vm.$vuet.getState('temp'), 1) 316 | t.is(vuet.getState('reset'), 1) 317 | t.is(vm.$vuet.getState('reset'), 1) 318 | 319 | vm.$destroy() 320 | t.is(vuet.getState('need'), 1) 321 | t.is(vm.$vuet.getState('need'), 1) 322 | t.is(vuet.getState('once'), 1) 323 | t.is(vm.$vuet.getState('once'), 1) 324 | t.is(vuet.getState('oncePromise'), 0) 325 | t.is(vm.$vuet.getState('oncePromise'), 0) 326 | t.is(vuet.getState('temp'), 0) 327 | t.is(vm.$vuet.getState('temp'), 0) 328 | t.is(vuet.getState('reset'), 0) 329 | t.is(vm.$vuet.getState('reset'), 0) 330 | 331 | vm = new Vue({ 332 | mixins: [ 333 | mapRules({ 334 | need: 'need', 335 | once: 'once', 336 | temp: 'temp', 337 | reset: 'reset' 338 | }) 339 | ], 340 | vuet 341 | }) 342 | 343 | vm.$vuet.getModule('reset').fetch() 344 | 345 | t.is(vuet.getState('need'), 2) 346 | t.is(vm.$vuet.getState('need'), 2) 347 | t.is(vuet.getState('once'), 1) 348 | t.is(vm.$vuet.getState('once'), 1) 349 | t.is(vuet.getState('oncePromise'), 0) 350 | t.is(vm.$vuet.getState('oncePromise'), 0) 351 | t.is(vuet.getState('temp'), 1) 352 | t.is(vm.$vuet.getState('temp'), 1) 353 | t.is(vuet.getState('reset'), 1) 354 | t.is(vm.$vuet.getState('reset'), 1) 355 | 356 | setTimeout(() => { 357 | t.is(vuet.getState('need'), 2) 358 | t.is(vm.$vuet.getState('need'), 2) 359 | t.is(vuet.getState('once'), 1) 360 | t.is(vm.$vuet.getState('once'), 1) 361 | t.is(vuet.getState('oncePromise'), 1) 362 | t.is(vm.$vuet.getState('oncePromise'), 1) 363 | t.is(vuet.getState('temp'), 1) 364 | t.is(vm.$vuet.getState('temp'), 1) 365 | t.is(vuet.getState('reset'), 1) 366 | t.is(vm.$vuet.getState('reset'), 1) 367 | 368 | vm.$destroy() 369 | t.is(vuet.getState('need'), 2) 370 | t.is(vm.$vuet.getState('need'), 2) 371 | t.is(vuet.getState('once'), 1) 372 | t.is(vm.$vuet.getState('once'), 1) 373 | t.is(vuet.getState('oncePromise'), 1) 374 | t.is(vm.$vuet.getState('oncePromise'), 1) 375 | t.is(vuet.getState('temp'), 0) 376 | t.is(vm.$vuet.getState('temp'), 0) 377 | t.is(vuet.getState('reset'), 0) 378 | t.is(vm.$vuet.getState('reset'), 0) 379 | t.end() 380 | }, 100) 381 | }) 382 | 383 | test('attr', t => { 384 | const vuet = new Vuet() 385 | t.is(vuet.app, null) 386 | const vm = new Vue({ vuet }) 387 | t.is(vuet.app, vm) 388 | t.true(vuet.vm instanceof Vue) 389 | 390 | vuet.addModules('test', { 391 | data () { 392 | return { 393 | count: 0 394 | } 395 | } 396 | }) 397 | t.deepEqual(vuet.store.test, { count: 0 }) 398 | t.deepEqual(vuet.getState('test'), { count: 0 }) 399 | t.is(vuet.store.test, vuet.getState('test')) 400 | t.is(vuet.getModule('test').app, vm) 401 | t.is(vuet.getModule('test').app, vuet.app) 402 | t.is(vuet.getModule('test').vuet, vuet) 403 | }) 404 | 405 | test('already exists on the object', t => { 406 | const warn = console.warn 407 | let warnMsg = 0 408 | console.warn = (msg) => { 409 | warnMsg = msg 410 | warn.call(console, msg) 411 | } 412 | const vuet = new Vuet({ 413 | modules: { 414 | test: { 415 | data () { 416 | return { 417 | data: [] 418 | } 419 | } 420 | } 421 | } 422 | }) 423 | t.is(warnMsg, '[__name__] \'test\' the \'data\' already exists on the object') 424 | console.warn = warn 425 | 426 | t.true(typeof vuet.getModule('test').data === 'function') 427 | t.true(Array.isArray(vuet.getModule('test').state.data)) 428 | }) 429 | 430 | test('root vue app', t => { 431 | const vuet = new Vuet() 432 | const vm = new Vue({ 433 | vuet 434 | }) 435 | t.is(vm._vuet, vm.$vuet) 436 | vm.$destroy() 437 | t.is(vm._vuet, vm.$vuet) 438 | 439 | const vm2 = new Vue({ 440 | vuet: Vuet 441 | }) 442 | t.is(vm2._vuet, undefined) 443 | t.is(vm2.$vuet, undefined) 444 | vm2.$destroy() 445 | t.is(vm2._vuet, undefined) 446 | t.is(vm2.$vuet, undefined) 447 | }) 448 | 449 | test('The rule does not exist', t => { 450 | let errMsg = '' 451 | try { 452 | mapRules({ 453 | notRule: 'test' 454 | }) 455 | } catch (e) { 456 | errMsg = e.toString() 457 | } 458 | t.is(errMsg, 'Error: [__name__] The\'notRule\'rule does not exist. Please make sure that it executes \'Vuet.rule(\'notRule\', opts)\' before all components') 459 | }) 460 | 461 | test('add module public function', t => { 462 | Vuet.options.module.plus = function () { 463 | this.count++ 464 | } 465 | 466 | const vuet = new Vuet({ 467 | modules: { 468 | test: { 469 | data () { 470 | return { 471 | count: 0 472 | } 473 | } 474 | } 475 | } 476 | }) 477 | const vtm = vuet.getModule('test') 478 | t.is(vtm.count, 0) 479 | vtm.plus() 480 | t.is(vtm.count, 1) 481 | vtm.reset() 482 | t.is(vtm.count, 0) 483 | }) 484 | 485 | test('replaceStore', t => { 486 | const vuet = new Vuet() 487 | const vm = new Vue({ 488 | vuet 489 | }) 490 | const test = vuet.addModules('test', { 491 | data () { 492 | return { 493 | count: 0 494 | } 495 | } 496 | }) 497 | t.is(test.count, 0) 498 | vuet.replaceStore({ 499 | test: { 500 | count: 100 501 | } 502 | }) 503 | console.log(JSON.stringify(vuet.store)) 504 | t.is(test.count, 100) 505 | t.is(vm.$vuet, vuet) 506 | }) 507 | --------------------------------------------------------------------------------