Actions expose a component's public methods. They're like buttons on your component that other components or code can trigger. Just as a TV remote has buttons for changing channels or volume, your component can have actions for functionality like "increment", "reset", and "submit".
Written By Joel
Last updated About 1 month ago
Declaring Actions
Actions are declared in the components options:
defineComponent("counter", {
store: {
count: 0
},
actions: {
reset(ctx) {
ctx.store.count = 0;
},
increment(ctx) {
ctx.store.count++;
},
}
});
Action Context
Each action receives a context object that provides access to the component's state and functionality:
defineComponent('rq-counter', {
props: {
max: 10,
},
store: {
count: 0,
},
actions: {
// Action with no arguments
increment(ctx) {
ctx.actions.add(1);
},
// Action with arguments
add(ctx, amount) {
const max = ctx.props.max
const newCount = ctx.store.count + amount;
if (newCount <= max) {
ctx.store.count = newCount;
}
},
},
setup(component, props, store, actions) {
// Bind count value
component.query('count').text(() => store.count);
// Call increment action
component.query('button').on('click', (evt) => {
actions.increment();
});
},
});
Properties
props
Access the component's props:
add(ctx, amount) {
const max = ctx.props.max
...
},
store
Access and modify the component's state:
add(ctx) {
const max = ctx.props.max
const newCount = ctx.store.count + amount;
if (newCount <= max) {
ctx.store.count = newCount;
}
},
actions
Call other actions from within an action:
increment(ctx) {
ctx.actions.add(1)
},
Using Actions
There are several ways to access a component's actions:
From Setup Function
Access your own component's actions:
HTML
<rq-counter>
<button rq="increment">+</button>
<span rq="count">0</span>
</rq-counter>
JavaScript
defineComponent("rq-counter", {
store: {
count: 0
},
actions: {
increment(ctx) {
ctx.store.count++;
}
},
setup(component, props, store, actions) {
// Display count
component.query("count").text(() => store.count);
// Handle internal button
component.query("increment").on("click", (evt) => {
actions.increment();
});
}
});
From Parent Component
Access a child components actions:
HTML
<rq-parent prop:key="parent">
<rq-counter prop:key="counter1">
<button rq="increment">Internal +</button>
<span rq="count">0</span>
</rq-counter>
<button rq="button">External +</button>
</rq-parent>
JavaScript
defineComponent("rq-parent", {
setup(component, props, store) {
component.query('button').on('click', (evt) => {
const counter = component.components.get('counter1');
counter?.actions.increment();
});
}
});
Via Query Component
Access any component's actions globally:
// Get component instance
const counter = queryComponent("rq-counter", "counter1");
// Call its increment action
counter?.actions.increment();
Typescript
You can type your actions for better TypeScript support:
interface Props {
max: number;
}
interface Store {
count: number;
}
interface Actions extends RqActions<Props, Store> {
increment: (ctx: RqActionContext<Props, Store>) => void;
add: (ctx: RqActionContext<Props, Store>, amount: number) => void;
}
defineComponent('rq-parent', {
setup(component, _props, _store) {
// Call counter's actions
component.query('button').on('click', (evt) => {
const counter = component.components.get('counter1');
counter?.actions.increment();
});
},
});
defineComponent<Props, Store, Actions>('rq-counter', {
props: {
max: 10,
},
store: {
count: 0,
},
actions: {
// Action with no arguments
reset(ctx) {
ctx.store.count = 0;
},
// Action with arguments
add(ctx, amount) {
const newCount = ctx.store.count + amount;
if (newCount <= ctx.props.max) {
ctx.store.count = newCount;
}
},
// Action referencing actions
increment(ctx) {
ctx.actions.add(1);
},
},
setup(component, _props, store, actions) {
// Bind count value
component.query('count').text(() => store.count);
// Call action with no arguments
component.query('increment').on('click', (evt) => {
actions.increment();
});
// Call action with arguments
component.query('increment2').on('click', (evt) => {
actions.add(2);
});
},
});
Could not load article.
Could not load article.