Now.js provides several methods for components to communicate with each other
The most basic form of component communication is passing props from parent to child
Now.getManager('component').define('user-list', {
template: `
<div class="user-list">
<user-card
data-prop-user="{{user}}"
data-prop-show-details="true"
data-json-prop-actions="{{actions}}">
</user-card>
</div>
`,
state: {
user: {
name: 'John Doe',
email: 'john@example.com'
},
actions: {
edit: () => console.log('edit'),
delete: () => console.log('delete')
}
}
});
Now.getManager('component').define('user-card', {
template: `
<div class="user-card">
<h3>{{props.user.name}}</h3>
{{#if props.showDetails}}
<p>{{props.user.email}}</p>
{{/if}}
<div class="actions">
<button onclick="{{props.actions.edit}}">Edit</button>
<button onclick="{{props.actions.delete}}">Delete</button>
</div>
</div>
`,
props: {
user: null,
showDetails: false,
actions: {}
}
});
Children can communicate with parents by emitting events
Now.getManager('component').define('user-card', {
methods: {
handleEdit() {
// Emit event to parent
this.emit('user:edit', {
userId: this.props.user.id
});
}
},
template: `
<div class="user-card">
<button onclick="methods.handleEdit">Edit</button>
</div>
`
});
Now.getManager('component').define('user-list', {
mounted() {
// Listen for child events
this.on('user:edit', (event) => {
console.log('Edit user:', event.detail.userId);
});
}
});
Components can communicate globally using the EventManager
// Component A
Now.getManager('component').define('component-a', {
methods: {
broadcastMessage() {
Now.getManager('event').emit('global:message', {
text: 'Hello from Component A'
});
}
}
});
// Component B
Now.getManager('component').define('component-b', {
mounted() {
Now.getManager('event').on('global:message', (event) => {
console.log('Received:', event.data.text);
});
}
});
Share and sync state between components
// Define shared state
const stateManager = Now.getManager('state');
stateManager.registerModule('users', {
state: {
currentUser: null,
userList: []
},
mutations: {
setCurrentUser(state, user) {
state.currentUser = user;
}
}
});
// Component A - Updates state
Now.getManager('component').define('user-selector', {
methods: {
selectUser(user) {
stateManager.commit('users/setCurrentUser', user);
}
}
});
// Component B - Reacts to state changes
Now.getManager('component').define('user-profile', {
mounted() {
stateManager.watch('users/currentUser', (user) => {
this.state.displayedUser = user;
});
}
});
Access child components directly using refs
Now.getManager('component').define('form-container', {
template: `
<form>
<input-field data-ref="emailInput"></input-field>
<button onclick="methods.submit">Submit</button>
</form>
`,
methods: {
submit() {
// Access child component directly
const email = this.refs.emailInput.getValue();
console.log('Email:', email);
}
}
});
// Create a mediator component
Now.getManager('component').define('chat-mediator', {
mounted() {
// Handle messages between components
this.on('message:send', (event) => {
this.state.messages.push(event.detail);
this.emit('message:received', event.detail);
});
}
});
// Create observable state
const userStore = {
observers: new Set(),
user: null,
setUser(user) {
this.user = user;
this.notifyObservers();
},
addObserver(component) {
this.observers.add(component);
},
notifyObservers() {
this.observers.forEach(component => {
component.onUserChange(this.user);
});
}
};