• Stars
    star
    422
  • Rank 102,753 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated about 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

Vuet

Coverage Status Build Status npm npm npm

此项目除了正常的bug修复,不再进行功能更新

如果对状态管理感兴趣,可以看下 Tms,文档更齐全

索引

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)

  • 描述:注册模块,并返回添加的模块(1.0.3及以上版本支持)

vuet.replaceStore(store: Object)

  • 描述:替换整个vuet的store,服务器端渲染时会用到(1.0.3及以上版本支持)

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