/vuet

允许你定义飙车过程的集中式状态管理模式

Primary LanguageJavaScriptMIT LicenseMIT

Vuet

Coverage Status Build Status npm npm npm

索引

Vuet.js是什么?

vuex中更新状态的唯一途径,就是通过提交mutation,这个过程是琐碎的,而在Vuet中是允许在何时何地进行直接赋值更新的,这个过程它是愉快的。Vuet是一种集中式状态管理模式,提供了模块系统和规则系统,它存在的意义是为了将状态管理变得简单

0.x版本和1.x版本的区别

0.x版本中,我们内置了太多的功能,导致大幅度提升了入门的门槛,1.x版本则是化繁为简,只保留了几个核心的API。
:route规则已经从Vuet中删除,后续会以插件的形式进行发布,敬请期待!0.x版本地址

安装

npm install vuet@latest

快速入门

import Vue from 'vue'
import Vuet, { mapModules, mapRules } from 'vuet'

Vue.use(Vuet)

const vuet = new Vuet({
  // 实例的选项,详情往下看
})
vuet.addModules('test', {
  data () {
    return {
      count: 0
    }
  },
  fetch () {
    this.count = 1000
  },
  plus () {
    this.count++
  },
  reduce () {
    this.count--
  },
  modules: {
    // 可以添加子模块,会自动继承父模块的名称:路径 = 父模块名称/子模块名称
  }
})

const App = {
  mixins: [
    mapModules({
      test: 'test' // { 别名: '模块路径' }
    }),
    mapRules({
      once: [{ path: 'test' }] // { 规则: ['模块路径'] } 内置的规则和简写方式可以在下面看
    })
  ],
  template: `
    <div>
      <div class="count">{{ test.count }}</div>
      <button @click="test.plus">plus</button> 
      <button @click="test.reduce">reduce</button> 
      <button @click="test.reset">reset</button> 
      <button @click="test.fetch">fetch</button> 
    </div>
  `
}

export default new Vue({
  el: '#app',
  vuet,
  render (h) {
    return h(App)
  }
})

API

实例的选项

options.pathJoin

  • 描述:子模块继承父模块时分割符
  • 默认值:/

options.modules

  • 描述:要初始化的模块
  • 默认值:{}

实例的属性

vuet.version

  • 描述:当前的版本号

vuet.app

  • 描述:new Vuet({ vuet })时的Vue实例
  • 默认值:null

vuet.modules

  • 描述:添加的模块,全部都在这里
  • 默认值:{}

vuet.options

  • 描述:new Vuet(options)实例化时传入的参数
  • 默认值:{ pathJoin: '/', modules: {} }

vuet.store

  • 描述:每个模块存储的状态
  • 默认值:{}

vuet.vm

  • 描述:vuet内部的Vue实例

实例的方法

vuet.addModules(path: string, modules: Object)

  • 描述:注册模块

vuet.getModule(path: string)

  • 描述:返回该模块的状态和方法

vuet.getState(path: string)

  • 描述:只返回模块的状态,不会返回方法

vuet.destroy()

  • 描述:销毁程序,释放内存。vue实例销毁时,也会跟着自动销毁

静态属性

Vuet.options.rules

  • 描述:存储了Vuet内置的规则,以及Vuet.rule添加的规则

Vuet.options.module

  • 描述:存储了Vuet模块公共的方法

静态方法

Vuet.mapModules(opts: { 别名: '模块路径' })

  • 描述:在Vue组件中连接模块,这样就可以在组件中使用模块的方法和状态

Vuet.mapRules(opts: { 规则: [{ path: '模块路径 }] })

  • 描述:使用对应的规则,来更新模块。支持简写:{ 规则: '模块路径' }{ 规则: ['模块路径'] }

Vuet.rule(name: string, opts: Object)

模块

什么是模块?

模块好比就是一个人的基本骨架,模块的属性就好比人的手、脚、眼睛等等,而模块的方法就好比大脑,操纵着人的行为,比如用手撸代码,用脚走路,看到漂亮的美女眨眨眼睛

注册模块

const vuet = new Vuet()

// 注册了一个叫test的模块
vuet.addModules('test', {
  data () {
    return {
      count: 0 // 定义了一个count属性
    }
  },
  plus () { // 定义了一个plus方法
    this.count++
  },
  modules: { // 定义子模块
    chlid: { // 子模块路径 = 父模块/子模块 = test/chlid
      data () {
        return {
          count: 0 // 定义了一个count属性
        }
      },
      plus () { // 定义了一个plus方法
        this.count++
      }
    }
  }
})

使用计算属性连接模块

{
  computed: {
    test () { // 虽然可以通过mapModules方法向组件注入模块,但是也可以通过计算属性的方法获取模块
      return this.$vuet.getModule('模块路径')
    }
  },
  beforeCreate () {
    // this.test 取得模块,就可以调用模块的方法和属性了
    // this.$vuet 取得vuet实例,然后就可以愉快的玩耍了
  }
}

在模块中获取路由对象

const vuet = new Vuet()
vuet.addModules('test', {
  data () {
    return {}
  },
  plus () {
    this.vuet // 取得vuet实例
    this.app // 取得vue根实例
    this.app.$router // 获取路由的方法
    this.app.$route  // 获取路由的状态
  }
})

重置模块状态

const vuet = new Vuet()
vuet.addModules('test', {
  data () {
    return {
      count: 0
    }
  },
  plus () {
    this.count = 100 // 等同于 this.state.count
    setTimeout(() => {
      this.reset() // 这是vuet内置的一个reset的方法 等同于 this.state = this.data()
    }, 2000)
  }
})

添加模块公共方法或属性

有时候,在Vuet模块中,我们期望能添加一些公共的方法或属性,以便在模块中能够使用this.xxxx的形式访问,来减少很多代码量

import Vuet from 'vuet'

Vuet.options.module.isFunction = (any) => (typeof any === 'function')

const vuet = new Vuet({
  modules: {
    test: {
      data () {
        return {
          count: 0
        }
      },
      plus () {
        // 这样就可以访问到我们公共的方法了
        this.isFunction()
      }
    }
  }
})

规则

什么是规则?

Vuet中,规则Vuet中是一种特殊的存在,它允许你将类似的更新一个模块状态的过程抽象出来,你可以使用规则来更新任何一个模块。你可以把Vuet模块当成一辆车,而规则就是定义这辆车应该怎么行走,到底是直走,还是转弯,还是直走一会,然后转弯,这些都是通过来规则来定义它

内置的规则

need

  • 描述:组件每次初始化时,在beforeCreate钩子中调用一次fetch方法

once

  • 描述:仅第一次在组件的beforeCreate钩子中调用一次fetch方法,之后在任何组件都不会再进行更新

temp

  • 描述:组件初始化时,在beforeCreate钩子中调用一次fetch方法,组件销毁时,在destroyed钩子中重置模块状态

reset

  • 描述:组件销毁时,在destroyed钩子中重置模块状态,这个能有效的减少对内存的占用

自定义规则

主要的原理就是获取传入的模块路径return一个mixin注入到组件中
我们现在就开始尝试定义一个飙车的过程,就是在组件每次执行beforeCreate钩子时,调用一次模块的fetch方法,那我们现在尝试定义一个myRule规则

Vuet.rule('myRule', { // 注意:规则的注册必须在所有组件执行之前
  install (Vuet, Vue) {
    // 传入一个Vuet和Vue构造函数。只会调用一次
  },
  init (vuet) {
    // new Vuet() 实例化后,传入实例,你可以在这里添加一些模块、方法之类的。每new一个Vuet实例,都会执行一次钩子
  },
  addModule (vuet, path) {
    // new Vuet().addModules 每注册一个模块,都会执行一次钩子,此时模块已经创建完成
  }
  rule ({ path }) {
    // 传入当前模块的路径,返回一个mixin来注入到组件中。执行Vuet的mapRules方法时会调用
    return {
      beforeCreate () {
        // 用路径,取得当前的模块
        const vtm = this.$vuet.getModule(path)
        // 然后调用一次模块的fetch方法
        vtm.fetch()
      }
    }
  },
  destroy (vuet) {
    // 传入当前要销毁的vuet实例,你可以做一些自己使用销毁的东西
  }
})

向组件中注入更新模块的规则

  {
    mixins: [
      mapRules({
        'myRule': '更新的模块路径'
      })
    ]
    // ...options
  }

第三方插件

第三方项目

许可证

MIT