您现在的位置是:主页 > news > 网站广告如何做/买卖链接网

网站广告如何做/买卖链接网

admin2025/5/12 23:23:38news

简介网站广告如何做,买卖链接网,wordpress调用最近更新文章,网页搜索框下记录删不掉小程序全局状态管理 缘由 使用vue的朋友可能用过vuex,使用react的朋友可能用redux,好处自然不用多说,用过的都说好。 微信小程序,我去年就曾接触过,那时候小程序连组件的概念都没有,现在小程序似乎更火了&a…

网站广告如何做,买卖链接网,wordpress调用最近更新文章,网页搜索框下记录删不掉小程序全局状态管理 缘由 使用vue的朋友可能用过vuex,使用react的朋友可能用redux,好处自然不用多说,用过的都说好。 微信小程序,我去年就曾接触过,那时候小程序连组件的概念都没有,现在小程序似乎更火了&a…

小程序全局状态管理

缘由

使用vue的朋友可能用过vuex,使用react的朋友可能用redux,好处自然不用多说,用过的都说好。
微信小程序,我去年就曾接触过,那时候小程序连组件的概念都没有,现在小程序似乎更火了,也增加了很多新概念,包括自定义组件。
小程序的入口文件app.js里会调用App()方法创建一个应用程序实例,有一些公共的、全局的数据可以保存在app.globalData属性里,但是globalData并不具备响应式功能,数据变化时,不会自动更新视图。多个页面或者组件共享同一状态时,处理起来也是相当麻烦的。
所以,我花了一点时间,简单实现了一个适用于小程序的状态管理。

demo

app.js

//app.js
import store from './store/index';// 创建app
App(store.createApp({globalData: {userInfo: {},todos: [{name: '刷牙',done: true}, {name: '吃饭',done: false}]}// ...其他
}))
复制代码

pages/index/index.wxml

<view class="container"><view>{{title}}</view><view class="info"><view>姓名:{{userInfo.name}}</view><view>年龄:{{userInfo.age}}</view></view><button type="button" bindtap="addTodo">增加todo</button><!-- todos组件 --><todos />
</view>
复制代码

pages/index/index.js

//index.js
import store from '../../store/index';// 创建页面
Page(store.createPage({data: {title: '用户信息页'},// 依赖的全局状态属性 这些状态会被绑定到data上globalData: ['userInfo', 'todos'],// 这里可以定义需要监听的状态,做一些额外的操作,this指向了当前页面实例watch: {userInfo(val) {console.log('userInfo更新了', val, this);}},onLoad() {this.getUserInfo().then(userInfo => {// 通过dispatch更新globalData数据store.dispatch('userInfo', userInfo);})},// 模拟从服务端获取用户信息getUserInfo() {return new Promise((resolve, reject) => {setTimeout(() => {resolve({name: '小明',age: 20})}, 100)})},// 增加todoaddTodo() {// 注意:这里从this.data上获取todos而不是globalDataconst todos = [...this.data.todos, {name: '学习',donw: false}];store.dispatch('todos', todos);}// 其他...
}))
复制代码

components/todos/index.wxml

<view class="container"><view class="todos"><view wx:for="{{todos}}" wx:key="{{index}}"><view>{{item.name}}</view><view>{{item.done?'已完成':'未完成'}}</view></view></view>
</view>
复制代码

components/todos/index.js

import store from '../../store/index';// 创建组件
Component(store.createComponent({// 依赖的全局状态属性globalData: ['todos'],// 这里可以定义需要监听的状态,做一些额外的操作,this指向了当前组件实例watch: {todos(val) {console.log('todos更新了', val, this);// 做其他事。。。}}// 其他...
}))
复制代码

点击"增加todo"之前

点击"增加todo"之后

实现原理

是不是很神奇,全是代码中那个store的功劳。
原理其实非常简单,实现起来也就100+行代码。
主要就是使用观察者模式(或者说是订阅/分发模式),通过dispatch方法更新数据时,执行回调,内部调用this.setData方法更新视图。 不多说,直接贴一下源码。

code

store/observer.js

const events = Symbol('events');
class Observer {constructor() {this[events] = {};}on(eventName, callback) {this[events][eventName] = this[events][eventName] || [];this[events][eventName].push(callback);}emit(eventName, param) {if (this[events][eventName]) {this[events][eventName].forEach((value, index) => {value(param);})}}clear(eventName) {this[events][eventName] = [];}off(eventName, callback) {this[events][eventName] = this[events][eventName] || [];this[events][eventName].forEach((item, index) => {if (item === callback) {this[events][eventName].splice(index, 1);}})}one(eventName, callback) {this[events][eventName] = [callback];}
}const observer = new Observer();export {Observer,observer
}
复制代码

store/index.js

import {Observer
} from './observer'const bindWatcher = Symbol('bindWatcher');
const unbindWatcher = Symbol('unbindWatcher');class Store extends Observer {constructor() {super();this.app = null;}// 创建appcreateApp(options) {const {onLaunch} = options;const store = this;options.onLaunch = function (...params) {store.app = this;if (typeof onLaunch === 'function') {onLaunch.apply(this, params);}}return options;}// 创建页面createPage(options) {const {globalData = [],watch = {},onLoad,onUnload} = options;const store = this;// 保存globalData更新回调的引用const globalDataWatcher = {};// 保存watch监听回调的引用const watcher = {};// 劫持onLoadoptions.onLoad = function (...params) {store[bindWatcher](globalData, watch, globalDataWatcher, watcher, this);if (typeof onLoad === 'function') {onLoad.apply(this, params);}}// 劫持onUnloadoptions.onUnload = function () {store[unbindWatcher](watcher, globalDataWatcher);if (typeof onUnload === 'function') {onUnload.apply(this);}}delete options.globalData;delete options.watch;return options;}// 创建组件createComponent(options) {const {globalData = [],watch = {},attached,detached} = options;const store = this;// 保存globalData更新回调的引用const globalDataWatcher = {};// 保存watch监听回调的引用const watcher = {};// 劫持attachedoptions.attached = function (...params) {store[bindWatcher](globalData, watch, globalDataWatcher, watcher, this);if (typeof attached === 'function') {attached.apply(this, params);}}// 劫持detachedoptions.detached = function () {store[unbindWatcher](watcher, globalDataWatcher);if (typeof detached === 'function') {detached.apply(this);}}delete options.globalData;delete options.watch;return options;}// 派发一个action更新状态dispatch(action, payload) {this.app.globalData[action] = payload;this.emit(action, payload);}/*** 1. 初始化页面关联的globalData并且监听更新* 2. 绑定watcher* @param {Array} globalData* @param {Object} watch* @param {Object} globalDataWatcher* @param {Object} watcher* @param {Object} instance 页面实例*/[bindWatcher](globalData, watch, globalDataWatcher, watcher, instance) {const instanceData = {};for (let prop of globalData) {instanceData[prop] = this.app.globalData[prop];globalDataWatcher[prop] = payload => {instance.setData({[prop]: payload})}this.on(prop, globalDataWatcher[prop]);}for (let prop in watch) {watcher[prop] = payload => {watch[prop].call(instance, payload);}this.on(prop, watcher[prop])}instance.setData(instanceData);}/*** 解绑watcher与globalDataWatcher* @param {Object} watcher* @param {Object} globalDataWatcher */[unbindWatcher](watcher, globalDataWatcher) {// 页面卸载前 解绑对应的回调 释放内存for (let prop in watcher) {this.off(prop, watcher[prop]);}for (let prop in globalDataWatcher) {this.off(prop, globalDataWatcher[prop])}}
}export default new Store()
复制代码

具体的代码就不解释了,源码里也有基本的注释。
目前实现的功能不算多,基本上能用了,如果业务上需求更高了,再进行拓展。
以上,
希望能给一些朋友一点点启发,顺便点个赞哦,嘻嘻!