Streamlit Custom Components + Vite + VueJS

Create Component based on VueJS
  • From the template folder
  • Create new component using vite and add init.py code for testing the component
  • $ mkdir vite_vue_component
    $ cd vite_vue_component
    $ npm init vite@latest frontend --template vue # npm v6 (v7 is different)
    $ touch __init__.py # command may be different in Windows
  • Add in the init.py code below
  • import os
    import streamlit.components.v1 as components
    
    _RELEASE = False
    
    if not _RELEASE:
      _component_func = components.declare_component(
        "vite_vue_component",
        url="http://localhost:3000", # vite dev server port
      )
    else:
      parent_dir = os.path.dirname(os.path.abspath(__file__))
      build_dir = os.path.join(parent_dir, "frontend/dist")
      _component_func = components.declare_component("vite_vue_component", path=build_dir)
    
    def my_component(name, key=None):
      component_value = _component_func(name=name, key=key, default=0)
      return component_value
    
    if not _RELEASE:
      import streamlit as st
      st.subheader("Component Test")
      num_clicks = my_component(name = "NameViteVue")
      st.markdown("You've clicked %s times!" % int(num_clicks))
  • install the frontend node libraries, streamlit-component-lib, create vite.config.js
  • $ cd frontend
    $ npm i
    $ npm i streamlit-component-lib
  • Add the following property to vite.config.js
  • base: './',
  • replace App.vue file with the following code
  • <template>
      <div>
        <h1>{{ msg }}</h1>
        <button @click="doClick">click</button>
        <p>Count {{ count }}</p>
      </div>
    </template>
    
    <script>
    import { Streamlit } from 'streamlit-component-lib'
    import { ref, onMounted } from 'vue'
    
    export default {
      setup(props, context) {
        const msg = ref('No Msg')
        const count = ref(0)
    
        const doClick = () => {
          count.value += 1
    
          Streamlit.setComponentValue(count.value)
        }
    
        const onRender = (event) => {
          const data = event.detail
          msg.value = `Hello, ` + data.args['name']
          Streamlit.setFrameHeight()
        }
    
        onMounted(() => {
          Streamlit.events.addEventListener(Streamlit.RENDER_EVENT, onRender)
          Streamlit.setComponentReady()
          Streamlit.setFrameHeight()
        })
    
        return {
          doClick,
          count,
          msg
        }
      }
    }
    
    </script>
    Running the example
    From the base directory, navigate to the frontend and serve it from a dev server:
    $ cd template/vite_vue_component/frontend
    $ npm run dev
    On a separate terminal, from base directory, navigate to and run the Streamlit app (assuming python environment has been activated):
    $ cd template
    $ streamlit run vite_vue_component/__init__.py  # run the example
    You should see the following image below. Button click will increment the count.

    83

    This website collects cookies to deliver better user experience

    Streamlit Custom Components + Vite + VueJS