How can i make all v-text-field components outlined by default in nuxt/vuetify module - vue.js

i'm using the nuxt/vuetify module and would like to make all v-text-fields components outlined.
Try to create and register plugin which register new vue component, that extends vuetify VTextField component.
import Vue from 'vue';
import { VTextField } from "vuetify/lib"
Vue.component('mTextField', {
extends: VTextField,
props: {
outlined: {
type: Boolean,
default: true
}
}
})
But always catch error while try to use mTextField component
Unexpected token 'export'
How can i make all v-text-fields components outlined?

Add transpile section in nuxt.config.js with 'vuetify/lib' worked for me
build: {
transpile: ['vuetify/lib']
},

Related

How to use uploadAreaMask slot component in vue formulate in Nuxt

I tried by configuring my own component as below in plugins. But my component haven't overrided default component.Please help.
import Vue from "vue";
import VueFormulate from "#braid/vue-formulate";
import FileUploadArea from "~/components/app/FileUploadArea";
// Register your component with vue
Vue.component("FileUploadArea", FileUploadArea);
// Let Vue Formulate know which slot you want to override for a given type
Vue.use(VueFormulate, {
library: {
// the `type` of input you’re targeting.
file: {
slotComponents: {
uploadAreaMask: "FileUploadArea",
},
},
},
});

Vite vuetify plugin doesn't load components listed in external libraries

I am creating a library that wraps Vuetify 3 components. But when I try to use the library it gives the following error:
[Vue warn]: Failed to resolve component: v-btn If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
Library vite.config.ts :
import { fileURLToPath, URL } from 'node:url';
import { resolve } from 'node:path';
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import vueJsx from '#vitejs/plugin-vue-jsx';
import vuetify from 'vite-plugin-vuetify';
export default defineConfig({
plugins: [
vue(),
vueJsx(),
// vuetify({ autoImport: true, styles: 'none' }), // Don't export vuetify
],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
},
},
build: {
lib: {
entry: resolve(__dirname, 'src/main.ts'),
name: '#my/ui',
// the proper extensions will be added
fileName: 'my-ui',
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['vue', 'vuetify'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue',
vuetify: 'Vuetify',
},
},
},
},
});
Nuxt project nuxt.config.ts:
import { defineNuxtConfig } from 'nuxt';
import vuetify from 'vite-plugin-vuetify';
export default defineNuxtConfig({
css: ['#/assets/css/main.css'],
modules: [
async (options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) =>
config.plugins.push(vuetify({ autoImport: true }))
);
},
],
build: {
transpile: ['#my/ui', 'vuetify'],
},
});
Nuxt project app.vue:
<template>
<v-app>
<v-main>
<HelloWorld label="Test" primary />
</v-main>
</v-app>
</template>
<script lang="ts" setup>
import { HelloWorld } from '#my/ui';
</script>
Nuxt project plugin vuetify.ts:
import 'vuetify/styles';
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({
// components, if imported components getting resolved but treeshaking doesn't work.
// directives
});
nuxtApp.vueApp.use(vuetify);
});
Expected Behavior
Vuetify components from the Library project should be auto imported.
Current workaround:
If the vuetify components are imported in the parent project then the components are resolved. But this causes issue as the library users has to know what to import or import on global which is creating larger bundle size.
Is there an alternative way to implement and meet the following criteria:
Wrapping module doesn't depend on vuetify (Peer dep only)
Consuming app can auto import and get all of the benefits of tree shaking
Consuming app doesn't need to import any of the peer dependencies of the wrapping module.
Thank you so much in advance.
Just to create an answer for the workaround Sasank described:
If you just want to get rid of the error, import the components into the parent project as described in this link: https://next.vuetifyjs.com/en/features/treeshaking/#manual-imports

Vuetify Storybook remapInternalIcon issue

Using Vuetify 2 and Storybook 6 (source https://github.com/lydonchandra/vuetify2storybook6 )
The component renders fine, but keep getting this error TypeError because vm.$vuetify.icons is undefined, when rendering component for first time.
Not sure which storybook-vuetify initialization bridge did I miss ?
TypeError: Cannot read property 'component' of undefined
at remapInternalIcon (vuetify.js:44048)
at VueComponent.getIcon (vuetify.js:16881)
at Proxy.render (vuetify.js:17009)
at VueComponent.Vue._render (vue.esm.js:3557)
at VueComponent.updateComponent (vue.esm.js:4075)
at Watcher.get (vue.esm.js:4488)
at new Watcher (vue.esm.js:4477)
function remapInternalIcon(vm, iconName) {
// Look for custom component in the configuration
var component = vm.$vuetify.icons.component; // <-- issue here when rendering for first time
if (iconName.startsWith('$')) {
// Get the target icon name
src/plugins/vuetify.ts
import Vue from "vue";
import Vuetify from "vuetify/lib";
import { UserVuetifyPreset } from "vuetify";
Vue.use(Vuetify);
export const options: UserVuetifyPreset = {
icons: {
iconfont: "mdiSvg"
}
};
export default new Vuetify(options);
Workaround for now is to set addon-essentials.docs to false. (Ref.
https://github.com/storybookjs/storybook/issues/7593)
file: .storybook/main.js
...
"addons": [
"#storybook/addon-links",
{
name: "#storybook/addon-essentials",
options: {
docs: false
}
}
],
...
If you don't want to disable addon-essentials.docs, you can add the following style in .storybook/preview-head.html
<style>
.sb-errordisplay {
display: none !important;
}
</style>
Another workaround without having to disable addon-essentials or adding any styles in the preview-head.html file you can import Vuetify at the top of your .stories.js (or .stories.ts) file like so e.g.
import vuetify from '#/plugins/vuetify'
then when you declare your storybook Template, pass in your vuetify object
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { YourComponent },
vuetify, // <-- Very important line
template: `<YourComponent />`
})
I found this workaround in this thread Cannot read property 'mobile' of undefined - Vue/Vuetify/Storybook

Gridsome Full Calendar build error - no SSR

I'm trying to use the Full Calendar vue component (https://github.com/fullcalendar/fullcalendar-vue) in a Gridsome project like so:
<template>
<div class="tabStaffManage">
<div>
<FullCalendar
ref="staffCalendar"
class="fullCalendar"
defaultView="dayGridMonth"
:events="calendarEvents"
:plugins="calendarPlugins"
:allDaySlot="false"
:header="{
center: 'dayGridMonth, timeGridDay',
right: 'prev, next'
}"
minTime="09:00:00"
:selectable="true"
maxTime="18:30:00"
#eventClick="onEventClick"
#select="onDateSelect"
:showNonCurrentDates="false"
></FullCalendar>
</div>
</div>
</template>
<script>
import { formatDate } from "#fullcalendar/core"
import FullCalendar from "#fullcalendar/vue"
import timeGridPlugin from "#fullcalendar/timegrid"
import dayGridPlugin from "#fullcalendar/daygrid"
import interactionPlugin from "#fullcalendar/interaction"
export default {
components: {
FullCalendar,
},
data() {
return {
calendarPlugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
}
},
}
</script>
This, however, produces an error on build:
Could not generate HTML for "/staff/dashboard/":
ReferenceError: Element is not defined
at Object.338 (node_modules/#fullcalendar/core/main.esm.js:102:0)
at __webpack_require__ (webpack/bootstrap:25:0)
at Module.552 (assets/js/page--src-pages-staff-dashboard-vue.ea5234e7.js:598:16)
at __webpack_require__ (webpack/bootstrap:25:0)
I understand that Full Calendar does not support SSR. So as per the Gridsome documentation (https://gridsome.org/docs/assets-scripts/#without-ssr-support) I did this to import the component:
I created an alias for it's dependencies in gridsome.config.js like so:
var path = require('path');
api.configureWebpack({
resolve: {
alias: {
"timeGridPlugin": path.resolve('node_modules', '#fullcalendar/timegrid'),
etc....
}
},
})
and required those plugins in the mounted() lifecycle hook:
mounted() {
if (!process.isClient) return
let timeGridPlugin = require('timeGridPlugin')
...
},
components: {
FullCalendar: () =>
import ('#fullcalendar/vue')
.then(m => m.FullCalendar)
.catch(),
}
I then wrapped the FullCalendar component in:
<ClientOnly>
<FullCalendar></FullCalendar>
</ClientOnly>
The extra dependencies required in the mounted() hook are included no problem.
However I now get the following error:
TypeError: Cannot read property '__esModule' of undefined
It seems that components() is failing to import the '#fullcalendar/vue' component.
Am I doing something wrong when importing the '#fullcalendar/vue' component?
Is there another way to include both the '#fullcalendar/vue' component and the plugin dependencies with no SSR?
Requiring the full calendar vue component in main.js by checking the gridsome client API and registering the component globally in vue seems to work and does what I expected:
// Include no SSR
if (process.isClient) {
const FullCalendar = require("#fullcalendar/vue").default
Vue.component("full-calendar", FullCalendar)
}
I also was not pointing to the default object when requiring the other modules in the component:
mounted() {
if (!process.isClient) return
let timeGridPlugin = require('timeGridPlugin').default
...
}

How to inject Vuetify into my custom vue plugin

I would like to create a Vue plugin with a function which programatically renders a Vue component. That component depends on Vuetify. Everything works fine if I use vanilla HTML/CSS in that component, but using Vuetify-related things in there (e.g. a ) does not work. I assume that I didn't inject vuetify itself into the component correctly.
In my custom component, I tried importing every Vuetify component separately, but without success. I also tried creating the component with the syntax: new Vue({vuetify}), but also without success.
import MyCustomComponent from '#/components/MyCustomComponent'
import vuetify from '#/plugins/vuetify';
export default {
install(Vue, options) {
function renderMyCustomComponent() {
const CustomComponent= Vue.extend(MyCustomComponent)
Vue.use(vuetify)
let instance = new CustomComponent()
instance.$mount()
document.body.appendChild(instance.$el)
}
Vue.prototype.$renderMyComponent = renderMyCustomComponent
}
}
The error message indicates, that vuetify (or at least some of it's properties) are not available in my component
[Vue warn]: Error in getter for watcher "isDark": "TypeError: Cannot read property 'dark' of undefined"
HINT/EDIT: I am using Vuetify 2.0. The way Vuetify is injected into the app changed a little bit. Here's the code of my vuetify plugin file:
import Vue from 'vue';
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
import de from 'vuetify/es5/locale/de';
Vue.use(Vuetify)
export default new Vuetify({
theme: {
themes: {
light: {
primary: '#3f51b5',
secondary: '#b0bec5',
accent: '#8c9eff',
error: '#b71c1c'
},
},
},
});
Not sure if you solved this issue, but I had the same problem where Vuetify in a plugin would not be initialized correctly.
Vuetify documentation states that you need to define a vuetify option when creating your vue instance:
new Vue({
vuetify,
}).$mount('#app')
Fortunately, custom Vue plugins has an options parameter that we can use.
Here is the code that consumes your plugin:
const options = {}; // add other options here! (vuex, router etc.)
Vue.use(YourCustomPlugin, options);
new Vue(options).$mount('#app');
And here is your plugin code:
import vuetify from "./src/plugins/vuetify";
export default {
install(Vue, options) { // options is undefined unless you pass the options param!
Vue.component('my-custom-component', MyCustomComponent);
Vue.use(Vuetify);
options.vuetify = vuetify;
}
};
The vuetify module is very simple:
import Vuetify from "vuetify";
import "vuetify/dist/vuetify.min.css";
const opts = {}
export default new Vuetify(opts);
The problem is that you actualy don't export plugin itself in '#/plugins/vuetify';
import MyCustomComponent from '#/components/MyCustomComponent'
import Vuetify from 'vuetify';
export default {
install(Vue, options) {
function renderMyCustomComponent() {
Vue.use(Vuetify)
const CustomComponent= Vue.extend(MyCustomComponent)
let instance = new CustomComponent()
instance.$mount()
document.body.appendChild(instance.$el)
}
Vue.prototype.$renderMyComponent = renderMyCustomComponent
}
}