Vue
Persistent State for Composition API
<script setup>
import { reactive } from 'vue'
const reactiveData = reactive({})
Agent
.state('my-count-state')
.then(state => {
// Initialize state if it hasn't been initialized yet.
if (isNaN(state.count)) state.count = 0
// Add the persistent state to reactiveData so that
// it can be accessed and modified in the template.
reactiveData.persistentState = state
})
</script>
<template>
<h1>Hello Vue 3</h1>
<button
v-if="reactiveData.persistentState"
@click="reactiveData.persistentState.count++"
>
The current count is: {{ reactiveData.persistentState.count }}
</button>
<div v-else>Loading the current count</div>
</template>
View State At a Scope
<template>
<!--
simple example that will just render the text value of
whatever data is at that scope
-->
<vueScopeComponent :id="scopeId" />
<!-- simple example rendering the metadata at that scope -->
<vueScopeComponent :id="scopeId" metadata/>
<!--
more advanced example rendering data inside that scope
-->
<vueScopeComponent
:id="scopeId"
:path="['field_name', 'deeper_field']"/>
<!--
Even more advanced example rendering data with a custom
viewer for the data in the scope
-->
<vueScopeComponent
:id="scopeId"
v-slot="{ loading, value }"
>
My Custom Way To View The data at that Scope
<span v-if="loading">Please hold...</span>
<span v-else>Here you go!: {{value}}</span>
</vueScopeComponent>
</template>
<script setup>
import { vueScopeComponent } from '@knowlearning/agents/vue.js'
const scopeId = 'some-id-for-a-scope'
</script>
Persistent State for Options API Components
Application Root Components
You can create a vue application who's root component's state is automatically bound to a scope you specify:
import { vuePersistentComponent } from '@knowlearning/agents/vue.js'
import myComponent from './my-component-file.vue'
const id = 'uuid-or-name-of-scope-to-bind-to-component-data'
const root = vuePersistentComponent(myComponent, id)
const app = createApp(root)
app.mount()
Now all state updates to that component will be persisted, and the most recent state will be re-attached to on every reload.
Child Components
A persistent component does not have to be used as the application root. You are free to make any component in your app a persistent component:
<template>
<div>
<h1>Cool persistent component!</h1>
<anyNameForMyPersistentComponent :importantProp="42">
</div>
</template>
<script>
import { vuePeristentComponent } from '@knowlearning/agents'
import myComponent from './my-component-file.vue'
const id = 'uuid-or-name-of-scope-to-bind-to-component-data'
export default {
components: {
anyNameForMyPersistentComponent: vuePeristentComponent(myComponent, id)
}
}
</script>
Persistent State for a Vuex Store
You can set up an app with a persistent store.
import App from './app.vue'
import store from './store.js'
const store = createStore(await vuePersistentStore(store, 'name-for-store-state'))
const app = createApp(App)
app.use(store)
app.mount('#app')
Any time a user loads an app configured like this, their store will reconnect to their persistent state.
Embedded Content Component
You can embed other sites that use @knowlearning/agents like so:
<template>
<div>
<vueEmbedComponent
:id="id"
@state="handleState"
@mutate="handleMutate"
/>
</div>
</template>
<script>
import { vueEmbedComponent } from '@knowlearning/agents/vue.js'
export default {
components: {
vueEmbedComponent
},
data() {
return {
id: "some-uuid-reference or url"
}
},
methods: {
handleState(event) {
// event will contain the id that the embedded content
// called Agent.state(id) on
},
handleMutate(event) {
// event will contain the id for a state that the
// embedded content has updated
}
}
}
</script>
How Embedded Content's Iframe URL is Resolved
The id passed into an embedded content component will be handled in the following way when deciding how to resolve the url to load into the embedded iframe:
-
If
id
is a UUID, then the url for the iframe will be:https://DOMAIN_THAT_CREATED_UUID/UUID
.For example: if
dd3d48cf-82d7-43ab-8f5c-d2b7ab06a2ff
is set asid
, then the vueEmbedComponent will look at the metadata for that UUID to find the domain where it was created. If, for instance, the domain that created that UUID is app.knowlearning.org, then the URL that vueEmbedComponent will load in its iframe is:https://app.knowlearning.org/dd3d48cf-82d7-43ab-8f5c-d2b7ab06a2ff
-
If
id
is already a valid URL with a domain included (likeapp.knowlearning.org
orapp.knowlearning.org/any-other-path
or evenapp.knowlearning.org/cc3e48de-82d8-42bc-8f5c-d2b7ab06a2fa
), then vueEmbedComponent will simply load that url in its iframe.
Tip
It is completely up to every domain owner to decide how to deal with URL paths, but we recommend all app creators check for a UUID passed as the path so that they can do something expected when an embedding app uses a UUID that belongs to their domain for the id
of a vueEmbedComponent. Please see the "Recommended Scaffolding" to see an app structure we really recommend.