npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dl-store

v1.0.2

Published

一个为 js 应用程序开发的状态管理模式

Downloads

6

Readme

dl-store

dl-store 是一个为 js 应用程序开发的状态管理模式,兼容web浏览器和node.js。它采用集中式存储管理应用的所有数据的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 dl-store 的设计思路是参考的 vuex,使用体验上也极为相似。同时结合了 vue.js 的底层原理实现数据的响应式监听。

安装

通过 NPM 安装

npm i dl-store -S

CDN

目前可以通过 unpkg.com/dl-store 获取到最新版本的资源,在页面上引入 js 文件即可开始使用。

<script src="https://unpkg.com/[email protected]/lib/dl-store.iife.min.js"></script>

核心概念

State

State 是模块下的所有数据的状态集合。State 可以直接使用或者从计算属性中返回某个状态:

const store = new DlStore({
  state: {
    apples: 6,
    oranges: 4,
    bananas: 2
  },
  getters: {
    // 计算水果总数
    fruitsCount({ state }) {
      return state.apples + state.oranges + state.bananas
    }
  }
})
store.state.apples // -> 6
store.getters.fruitsCount // -> 12

Getters

Gettersstore 的计算属性。getter 的返回值会根据它的依赖被缓存起来,当 getter 所依赖的 state 数据发生变化时,getter 才会重新计算。 getter 接受四个参数:

  • state:当前模块下的状态集合。
  • getters:当前模块下的计算属性集合。
  • rootState:root下的状态集合。
  • rootGetters:root下的计算属性集合。
const store = new DlStore({
  state: {
    apples: 6,
    oranges: 4,
    bananas: 2
  },
  getters: {
    // 计算苹果 + 橘子总数
    applesAndOranges({state}) {
      const res = state.apples + state.oranges
      return res
    },
    // 计算水果总数
    fruitsCount({ state, getters }) {
      const res = getters.applesAndOranges + state.bananas
      return res
    }
  }
})

Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:

store.getters.fruitsCount // -> 12

Watch

watchstore 中可以自定义的侦听器对象。通过监听及时响应数据的变化,当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。 watch 是一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。 Store 实例将会在实例化时遍历 watch 对象的每一个 property

const store = new DlStore({
  state: {
    name: '张三',
    age: 28,
    occupation: {
      name: '打工人',
      companyName: 'XXX有限公司',
      companyAddress: '繁华大道999号'
    }
  },
  watch: {
    age(val) {
      const message = `张三:我今年${val}岁了`
      console.log(message)
    },
    'occupation.companyName'(val) {
      const message = `张三:我跳槽到${val}上班了`
      console.log(message)
    }
  }
})

除了 watch 选项之外,您还可以使用命令式的 store.addWatch()/store.removeWatch() 动态的创建/移除侦听器。

// 添加监听
store.addWatch('occupation.name', {
  handler(val) {
    const message = `张三:我是一名光荣的${val}`
    console.log(message)
  },
  immediate: true
})
// 移除监听
store.removeWatch('occupation.name')

Actions

更改 store 中数据的唯一方法是通过提交 action。每个 action 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 context 对象作为第一个参数,且 action 内允许异步操作 你不能直接调用一个 action 处理函数。要唤醒一个 action 处理函数,你需要以相应的 type 调用 store.dispatch 方法。

const store = new DlStore({
  state: {
    name: '张三',
    age: 28,
    favouriteFruits: [
      '苹果',
      '橘子',
      '香蕉',
      '草莓'
    ]
  },
  actions: {
    updateage({ state }, age) {
      state.age = age
    },
    addFruits({ state }, fruit) {
      state.favouriteFruits.push(fruit)
    },
    removeFruits({ state }, index) {
      return new Promise(r => {
        setTimeout(() => {
          state.favouriteFruits.splice(index, 1)
          r()
        }, 1000)
      })
    }
  }
})

store.dispatch('addFruits', '葡萄') // -> ['苹果', '橘子', '香蕉', '草莓', '葡萄']

如果您想要调用指定模块下的 action ,需要为 type/ 拼接上模块的名称:

// 水果模块
const fruitsModule = {
  state: {
    favouriteFruits: [
      '苹果',
      '橘子'
    ]
  },
  actions: {
    addFruits({ state }, fruit) {
      state.favouriteFruits.push(fruit)
    }
  }
}
const store = new DlStore({
  modules: {
    fruits: fruitsModule
  }
})

store.dispatch('fruits/addFruits', '葡萄') // -> ['苹果', '橘子', '葡萄']

context 的属性如下:

  • state:当前模块下的状态集合。
  • getters:当前模块下的计算属性集合。
  • rootState:root下的状态集合。
  • rootGetters:root下的计算属性集合。
  • addWatch:当前模块下动态添加监听的方法。
  • removeWatch:当前模块下动态移除监听的方法。
  • dispatch:当前模块下调用 action 的方法。
  • __history__:root下的时间线实例对象。

Modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,dl-store 允许我们将 store 分割成模块(module)。每个模块拥有自己的 stateactionsgetterswatch

const moduleA = {
  state: () => ({ ... }),
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  actions: { ... }
}

const store = createStore({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.modules.a.state // -> moduleA 的状态
store.modules.b.state // -> moduleB 的状态

通过 store.modules[moduleName]state 可以查找到子模块的状态,但是这样获取状态的链路较长。 store 将模块的状态以如下规则映射到 store 身上:

  • store.__[moduleName]_state__:子模块的状态树。
  • store.__[moduleName]_getters__:子模块的计算集合。
  • store.__[moduleName]_dispatch__:子模块的 dispatch 方法。
  • store.__[moduleName]_addWatch__:子模块的 addWatch 方法。
  • store.__[moduleName]_removeWatch__:子模块的 removeWatch 方法。

在 store 创建之后,你可以使用 store.registerModule 方法动态的注册模块:

store.registerModule('fruits', fruitsModule)

History

__history__ 是记录 store 中操作 state 的时间线数据队列,最多缓存100次操作。 通过 __history__ 对象的 prevTime()/nextTime() 方法,可以轻松实现 state 数据的撤销/回退功能。