Summary 1.

The development experience of wechat applets is similar to vue and React, but there is no global state management mechanism, so state sharing can only be realized through attribute transfer. This approach can meet the development efficiency in small-scale applications, but in complex applications, the nesting level of components is very deep, and the path of attribute transmission is too long.

So I want to use the small program Page data object to build a global store, this store meets the following requirements:

  • The store can be accessed by any component on the current page, and is accessed directly rather than through attribute passing.
  • A global store is corresponding to a component, meaning that a change in the store can cause the component to be redrawn.
  • Both pages and components can change the state of the Store without breaking the original responsiveness.
  • Provide a Vuex like development experience to reduce learning costs.

First, attach the source code github address

2. Use

Let’s skip the principle and see how it works.

2.1 installation

Put store. js in the wechat applet project folder, such as /lib/store.js.

2.2 Creating a Page Object

Let’s create from wxappStore. CreatePage here. Compare store.js with the original creation method

// The original creation method
Page({
  data: {
    message: ' '
  },
  onLoad: function () {
    this.setData({
        message: 'hello world'})}})Copy the code
// After adding global state management
import wxappStore from ".. /.. /lib/Store.js";

Page(wxappStore.createPage({
    // The first argument is the same as the option passed to the Page method. Data is used as a global shared object.
    data: {
        message: ' '
    },
    onLoad: function () {
        // Perform an asynchronous operation with the dispatch method.
        this.store.dispatch({ 
            name: 'testAction'.payload: 'hello world'
        });
        // Use the commit method to change the global status.
        this.store.commit({ 
            name: 'testMutation'.payload: 'hello world'}); }},The second argument is an object that contains mutations and actions
{
    mutations: {
        testMutation: function({ setData, payload, data }) {
            setData({
                message: payload }); }},actions: {
        testAction: function ({ commit, payload, data }) {
            setTimeout((a)= > {
                commit({
                    name: 'testMutation'.payload: payload }); }); }}}))Copy the code

The wxappStore. CreatePage method takes two parameters.

The first argument is no different from the option passed to the Page method. Data is used as a global shared object.

The second parameter is an object that contains mutations and actions

2.3 the use of mutation

Mutation is similar to mutation in Vuex in that it changes the state in a synchronous manner. This can be called by commit.

2.3.1 defined mutation

Mutations is defined in the second parameter of wxappStore. CreatePage, which is used to modify global state. Mutation is usually synchronized. The parameter to the mutation method is an object containing three properties:

  • setData function: used to modify the global status. Directly modifying the status in the wechat mini program will not trigger page reaggregation.
  • payload object: The modified state, which can be an object or an underlying data type such as String
  • data object: Current status
mutations: {
    testMutation: function({ setData, payload, data }) {
        setData({
            message: payload }); }},Copy the code

2.3.2 call mutation

The commit method calls mutation, which takes an object containing two properties:

  • name String: mutation name
  • payload Object: Indicates the status to be changed. It is similar to the payload of Vuex.
this.store.commit({ 
    name: 'testMutation'.payload: 'hello world'
});
Copy the code

2.4 use the action

Action is similar to action in Vuex. It usually contains an asynchronous operation. After the asynchronous operation is complete, the commit operation is performed.

Action against 2.4.1 definition

The action method takes a single parameter containing three properties:

  • commit function: Performs the commit operation
  • payload Object: data object, and Vuex type
  • data Object: Current status
actions: {
    testAction: function ({ commit, payload, data }) {
        setTimeout((a)= > {
            commit({
                name: 'testMutation'.payload: payload }); }); }}Copy the code

2.4.2 calls to action

The Action is called through the Dispatch method and takes an object with two properties:

  • name String: Specifies the action name
  • payload Object: Indicates the status to be changed. It is similar to the payload of Vuex.
this.store.dispatch({ 
    name: 'testAction'.payload: 'hello world'
});
Copy the code

2.5 create a Component

There are two things we need to do in Component

First, bind the global state to the data property of the current component, and bind the component’s data property to the page element.

The second component needs to use commit or Dispatch to change the global state.

Here, Store.j creates the Component through wxappStore. CreateComp, which implements global state management for the Component through a proxy.

import wxappStore from ".. /lib/Store.js";

Component(wxappStore.createComp({
  data: {
    localtimeData: ' '
  },
  ready: function () {
    // Bind global state
    this.getGlobalData({ globalDataKey: 'localtime'.localDataKey: 'localtimeData' });

    // Change the global state
    this.store.commit({
        name: 'testMutation'.payload: (new Date()).toLocaleTimeString()
    })
  }
}))

Copy the code
<view>{{localtimeData}}</view>
Copy the code

2.5.1 Global status Binding

Global state binding is implemented through the getGlobalData instance method, which is inserted into the Component instance during store.js execution and is not in the applet’s runtime environment.

GetGlobalData cannot be called in the Created callback because the component instance method setData cannot be called in the Created callback.

The argument to getGlobalData is an object containing two properties:

  • globalDataKey StringThis property represents the name of the property that requires the global state to be bound to the component’s local state.
  • localDataKey String: This property represents the property name of the local state that will be bound to the global state.
// Bind global state
this.getGlobalData({ globalDataKey: 'localtime'.localDataKey: 'localtimeData' });
Copy the code

2.5.2 Changing the Global Status

You can use store.mit or store.dispatch. Store is not built into the applet environment, but is inserted into each component instance via store.js. It is used in a similar way to Page.

3. The deficiencies of this framework

  • Store.js borrows the data attribute of the Page object to complete global state management, so the responsibility of the data attribute is not single. The data attribute combines the functionality of the page ViewModel with the functionality of the global state. But the data attribute in Page also has global meaning, so there is not much conflict between the two.

  • The data property in Component has more responsibilities than one. It combines the ability of local properties with the ability to bind global state. And modifying data in component directly with setData does not trigger a global state change because data is scoped only to the current component and must be triggered by store.mit or store.dispatch.

  • If you find other problems, welcome to leave a message, we make progress together!

4. Write complete tired, principle and so on next update it…