Skip to content

Can't use import statement in custom Vue components(sfc) #1198

@DaelonSuzuka

Description

@DaelonSuzuka

Description

I want to write a Vue Single-File Component (SFC). There are several Vue features I want to use that have to be imported.

The Vue documentation very clearly prescribes using import statements inside the <script> block in the SFC.

The Quasar docs also very clearly use imports. Here's a link to an SFC example from Quasar's documentation:

https://github.com/quasarframework/quasar/blob/dev/docs/src/examples/QTable/PopupEditing.vue#L48

I combine that .vue file with these python files:

table.py

from nicegui.element import Element

class Table(Element, component='table.vue'):
    def __init__(self) -> None:
        super().__init__()

main.py

from nicegui import ui
from table import Table

@ui.page('/')
def index():
    ui.label('hello')

ui.run(port=8081)

When I try to load that page in the browser, I get Uncaught SyntaxError: missing ) after argument list. This error points to the following generated code (only the first line is important):

index.html

//                                                            v---------------v this is not correct
var table = app.component('nicegui-table', {template:'#tpl-t', ref } from 'vue'

const columns = [
  {
    name: 'name',
    required: true,
    label: 'Dessert (100g serving)',
    align: 'left',
    field: row => row.name,
    format: val => `${val}`,
    sortable: true
  },
  { name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true },
  { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true, style: 'width: 10px' },
  { name: 'carbs', label: 'Carbs (g)', field: 'carbs' },
  { name: 'protein', label: 'Protein (g)', field: 'protein' },
  { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' },
  { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) },
  { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }
]

const rows = [
  {
    name: 'Frozen Yogurt',
    calories: 159,
    fat: 6.0,
    carbs: 24,
    protein: 4.0,
    sodium: 87,
    calcium: '14%',
    iron: '1%'
  },
  {
    name: 'Ice cream sandwich',
    calories: 237,
    fat: 9.0,
    carbs: 37,
    protein: 4.3,
    sodium: 129,
    calcium: '8%',
    iron: '1%'
  }
]

export default {
  setup () {
    return {
      columns,
      rows: ref(rows)
    }
  }
});

I don't fully understand how index.html is being generated, but I believe I've tracked this block of code to here: https://github.com/zauberzeug/nicegui/blob/main/nicegui/dependencies.py#L65.

vbuild.VBuild() is from another package, and it looks (to me) like the root cause of this problem is how vbuild is parsing the .vue file?

I know you guys don't control vbuild, but this issue caused me several days of confusion as I tried to use official examples from Vue and Quasar docs to build a custom component in NiceGUI and nothing worked for vague reasons.

I did finally get a .vue SFC working with no import statements, so I'm not blocked by this today, but imports will be required if I want to use many of Vue's features in the future.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugType/scope: Incorrect behavior in existing functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions