Skip to contents

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 what update_vue() and call_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 data follows, rendered with render_vue_data(): each render sets the fields it names, which must be in data (or setup()'s state). Inside a module, ns("stats"). While Shiny recalculates one, $recalculating.<id> is true in 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.

Value

A tag, with its dependencies.

What goes where

VueHere
createApp(options).mount('#app')vue_app(id, ...)
data(), methods, computed, watch, setup(), emits, hooksthe 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> – the input field, on load, on change and after an update; several fields give one value, a named list of them.

  • input$<id>_<event> – each event in emits, sent with $emit(): one argument as it is, several as a list (arg1, arg2, ...), none as TRUE.

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)
  )
}