I'm working on a personal project where I'm trying to avoid a full npm build process and instead work within a single .html
file that uses Vue 3 and Vuetify. Here's the full HTML (basically you can drop it into a file, open it in a browser, and see what I'm seeing):
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css">
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js",
"vuetify": "https://cdnjs.cloudflare.com/ajax/libs/vuetify/3.4.3/vuetify.esm.min.js"
}
}
</script>
</head>
<body>
<div id="app">
<v-table>
<thead>
<tr>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr v-for="d in numbers" :key="d">
<td>{{ d }}</td>
</tr>
</tbody>
</v-table>
</div>
<script type="module">
import { createApp, ref } from 'vue'
import { createVuetify } from 'vuetify'
const vuetify = createVuetify()
const app = createApp({
setup() {
const numbers = ref([4, 5, 6])
return { numbers }
}
})
app.use(vuetify).mount('#app')
</script>
</body>
</html>
and I can see that Vue starts up, I can see that the Vuetify assets are being fetched properly, but I get an error in the console that I think means something's happening out of order:
[Vue warn]: Property "d" was accessed during render but is not defined on instance.
at <VTable>
at <App>
My guess is that the template is trying to render somehow before the setup()
script populates data
? Is what I'm trying to do possible?
One other thing that seems odd is that when I don't try to use data and instead just create a simple table with v-table
, eg.
<v-table>
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>R1C1</td>
<td>R1C2</td>
</tr>
</tbody>
</v-table>
the rendered output is just <table> Col 1 Col 2 R1C1 R1C2 </table>
, but there are no errors in the console. Worth noting that if I remove Vuetify from the mix and just use regular table tags, my table is created properly. It seems to happen only when Vuetify tries to render the v-table
component.
When you put Vue template code into the <div id="app">
directly, it will be processed by the browser before Vue can get to it. When table elements like thead, tbody, etc. are used outside a table, the browser kicks them out, leaving you with this:
<v-table>{{ d }}</v-table>
Since d
from the v-for
was removed along with the tr, you end up with a warning and a broken table.
There are two ways to resolve the issue, either move the template code into Vue setup and leave the app mount point empty:
<div id="app"></div>
and
<script type="module">
...
const app = createApp({
template: `
<v-table>
rest of the table code...
</v-table>
`,
setup() {
const numbers = ref([4, 5, 6])
return { numbers }
}
})
...
Alternatively, you can use a table element instead of the v-table
and have Vue replace it later on using the is
attribute:
<div id="app">
<table is="vue:v-table">
rest of the table code...
</table>
</div>
There are other issues when not using templates, have a look at the in-DOM Template Parsing Caveats section of the docs