Slim.js — это легковесный фреймворк для создания веб-компонентов с реактивным подходом. Одним из ключевых аспектов разработки на Slim.js является управление общим состоянием между компонентами. Понимание этой концепции позволяет создавать масштабируемые интерфейсы, где отдельные компоненты могут обмениваться данными без прямого связывания.
Общее состояние используется для хранения информации, к которой должны иметь доступ несколько компонентов. Оно решает три основные задачи:
В Slim.js общий стейт обычно реализуется через внешний объект состояния или синглтон. Простейший пример:
export const store = {
state: {
user: null,
notifications: []
},
subscribers: [],
subscribe(callback) {
this.subscribers.push(callback);
},
setState(newState) {
this.state = { ...this.state, ...newState };
this.subscribers.forEach(cb => cb(this.state));
}
};
state — объект, содержащий актуальные данные.subscribers — массив функций, которые вызываются при
изменении состояния.subscribe(callback) — метод для регистрации
подписчиков.setState(newState) — метод для обновления состояния и
уведомления всех подписанных компонентов.Компоненты Slim.js могут подписываться на изменения состояния через
subscribe. Пример:
import { Slim } from 'slim-js';
import { store } from './store.js';
class UserProfile extends Slim {
constructor() {
super();
this.user = null;
}
onBeforeCreated() {
store.subscribe(state => {
this.user = state.user;
this.update();
});
}
get template() {
return `
User Profile
${this.user ? this.user.name : 'Гость'}
`;
}
}
Slim.tag('user-profile', UserProfile);
Ключевые моменты:
onBeforeCreated, что гарантирует
доступность данных до рендеринга.update() перерисовывает компонент при изменении
данных.Компоненты могут не только читать, но и изменять общее состояние:
class LoginForm extends Slim {
constructor() {
super();
this.username = '';
}
onLogin() {
store.setState({ user: { name: this.username } });
}
get template() {
return `
`;
}
}
Slim.tag('login-form', LoginForm);
Slim.js использует легковесную реактивную систему, поэтому важно учитывать следующие моменты:
state без нужды может вызвать лишние
перерисовки.export const userStore = {
state: { user: null },
subscribers: [],
setUser(user) {
this.state.user = user;
this.subscribers.forEach(cb => cb(this.state));
},
subscribe(cb) {
this.subscribers.push(cb);
}
};
export const notificationStore = {
state: { notifications: [] },
subscribers: [],
addNotification(msg) {
this.state.notifications.push(msg);
this.subscribers.forEach(cb => cb(this.state));
},
subscribe(cb) {
this.subscribers.push(cb);
}
};
Разделение состояния по модулям снижает вероятность ненужных обновлений компонентов, не связанных с изменившимися данными.
Slim.js поддерживает двустороннюю привязку с помощью реактивных свойств. В связке с общим состоянием это выглядит так:
this.userName — локальное свойство компонента.setState.Для больших приложений рекомендуется:
update().