The component Context API provides a mechanism for components to ‘talk’ to each other without passing data and functions as properties, or sending lots of events. Similar to vue provide and inject
There are two API functions related to Context, setContext and getContext
If a component calls setContext(key, context), then any of its children can retrieve the context by const Context = getContext(key).
SetContext and getContext are similar to lifecycle functions and can only be called during component initialization.
The parent component App. Svelte
<script>
import { setContext } from 'svelte'
import Child1 from './Child1.svelte'
import Child2 from './Child2.svelte'
// The value of Context can be any data type
setContext('child1', {
msg: 'child1 message'
})
setContext('child2', {
msg: 'child2 message'
})
</script>
<Child1 />
<Child2 />
Copy the code
Child components
<! -- Child1.svelte -->
<h2>{ctx.msg}</h2>
<script>
import { getContext } from 'svelte'
let ctx
// If the child component's parent set a context named child1, the child component can be obtained using the getContext method
// If the parent component does not set the context or the child component is used alone, the child component may not get a valid context
// Therefore, it is necessary to use the corresponding logical judgment
if (getContext('child1')) {
ctx = getContext('child1')}</script>
<! -------------------------------------->
<! -- Child2.svelte -->
<h2>{ctx.msg}</h2>
<script>
import { getContext } from 'svelte'
let ctx
if (getContext('child2')) {
ctx = getContext('child2')}</script>
Copy the code
When setting a context, you can use any data type as the key of the context in principle, but it is recommended to use the reference data type as the key of the context
For example: setContext({},…) This avoids key conflicts (because {}! == {} “x” === “x”)
<! -- parent app.svelte -->
<script>
import { setContext } from 'svelte'
import Middle from './Middle.svelte'
setContext('child', {
msg: 'App message'
})
</script>
<Middle />
<! Middle. Svelte -->
<Child />
<script>
import { setContext } from 'svelte'
import Child from './Child.svelte'
setContext('child', {
msg: 'Middle message'
})
</script>
<! -- Child component child. svelte -->
<h2>{ctx.msg}</h2> <! -- output Middle message -->
<script>
import { getContext } from 'svelte'
let ctx
if (getContext('child')) {
ctx = getContext('child')}</script>
Copy the code
Contexts vs Props vs Stores
category | describe |
---|---|
Contexts | To pass from father to father or all descendants (including children that are generations away or passed in slot mode) The data is not responsive |
Props | The father the son Data is responsive |
Stores | Any component and between components (does not need to be parent and child) Data is responsive |
Context is not reactive by default. If you want values in Context to support reactivity,
You should store the value in the Store first and then place the Store in the context.
Module context
Typically, a script contains code that needs to be executed each time a component is instantiated
If I want some code to be executed the first time a component is instantiated, and then not executed again, I can use the module context
The main purpose of a module context is to provide a way for all instances of a component to share the same context
If you want to share values across multiple components, it is recommended to use store
The module context is written in the top-level script tag
Values declared in a module context can be accessed from a regular
Note: Variables defined in the Module script are not responsive. So assignment does not trigger it to be rerendered, even though the variable itself is updated.
<! -- Child.svelte -->
<script context="module">
// After setting context="module" on the script, the code in the scipt block will only be executed on the first instantiation
// Subsequent instantiations of the component will not be executed
const elements = new Set(a);// Any content exported from the context="module" block will become an export of the module itself
// Currently, the export can only be a normal export. You cannot use the default export because the component itself uses the default export
export function stopAll() {
elements.forEach(element= > element.pause() });
}
</script>
<! -- App.svelte -->
<script>
import Child, { stopAll } from './Child.svelte';
</script>
Copy the code