vue_app() writes a Vue 3 component in R and places it on the page: the
arguments are Vue's own options, under Vue's own names, and the browser
creates and mounts it with Vue.createApp(). Three things are added, as
Shiny needs them: id, where it goes and what the server calls it;
input, the field that is input$<id>; and dependencies. use is
Vue's app.use().
Usage
vue_app(
id,
template,
data = list(),
methods = NULL,
computed = NULL,
watch = NULL,
emits = NULL,
setup = NULL,
components = NULL,
...,
input = NULL,
outputs = NULL,
use = NULL,
dependencies = NULL
)Arguments
- id
The component's id:
input$<id>, and whatupdate_vue()andcall_vue()name. Inside a module,ns("id").- template
The template: htmltools tags, or a string.
- data
Named list: the initial state. A data.frame in it is rows. A vector of one element travels as a single value, as in Shiny; wrap it in
I()to keep it an array:tags = I("red").- methods, computed, watch
Named lists of
JS()functions.- emits
Names of the events the component sends with
$emit().- setup
A
JS()function: Vue's Composition API.- components
Named list of
vue_component()s, for the template.- ...
Any other option of Vue's, by Vue's name or its snake_case:
mounted = JS(...),before_unmount = JS(...),provide = JS(...).- input
The field whose value is
input$<id>, or several, for one value made of them.NULL: the component reports no value.- outputs
Ids of outputs the component's
datafollows, rendered withrender_vue_data(): each render sets the fields it names, which must be indata(orsetup()'s state). Inside a module,ns("stats"). While Shiny recalculates one,$recalculating.<id>istruein templates.- use
Vue plugins to install, by the global name each is loaded under:
"MyPlugin", or with options,list(MyPlugin = list(...)).- dependencies
htmltools::htmlDependency()s the component needs: the plugins' scripts and stylesheets.
What goes where
| Vue | Here |
createApp(options).mount('#app') | vue_app(id, ...) |
data(), methods, computed, watch, setup(), emits, hooks | the same names; functions as JS() |
beforeUnmount, inheritAttrs, ... | Vue's name, or snake_case: before_unmount |
app.use(Plugin, options) | use = list(Plugin = options) |
v-model on the component (its value) | input = "<field>": input$<id> |
this.$emit("picked", x) | input$<id>_picked, for an event in emits |
Every function – a method, a watcher, setup() – is JavaScript, given
with JS(). data is the initial state, as R writes it: a list becomes
an object, a data.frame its rows. After that the component changes it,
and the server does with update_vue() or render_vue().
Shiny inputs
input$<id>– theinputfield, on load, on change and after an update; several fields give one value, a named list of them.input$<id>_<event>– each event inemits, sent with$emit(): one argument as it is, several as a list (arg1,arg2, ...), none asTRUE.
Data from users
Show it through data – {{ field }}, :prop="field" – which Vue
renders as text. Never paste it into the template: a template is code,
and {{ }} in it runs.
Examples
counter <- vue_app(
"counter",
template = htmltools::tags$button(`@click` = "n++", "Clicked {{ n }} times"),
data = list(n = 0),
input = "n"
)
if (interactive()) {
library(shiny)
shinyApp(
fluidPage(counter, textOutput("n")),
function(input, output) output$n <- renderText(input$counter)
)
}