Vuetify theme is being ignored - vue.js

I have created a file in my plugins directory which looks like this:
import Vue from "vue";
import Vuetify from "vuetify/lib/framework";
Vue.use(Vuetify);
export default new Vuetify({
theme: {
themes: {
light: {
primary: "#081d4d", // $blue
secondary: "#00c8b7", // $jade
//anchor: "#081d4d", // $blue (by default vuetify styles anchors with the same colour of primary)
accent: "#82B1FF", // $blue
error: "#ff4438", // $warm-red
info: "#835dd0", // $violet
success: "#4CAF50", // none
warning: "#ff8204", // $orange
},
},
},
});
And then I use it in my main.ts like this:
import "./registerServiceWorker";
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import { provide } from "#vue/composition-api";
import { DefaultApolloClient } from "#vue/apollo-composable";
import "./plugins/axios";
import vuetify from "./plugins/vuetify";
import apolloClient from "./plugins/vue-apollo";
Vue.config.productionTip = false;
new Vue({
router,
store,
vuetify,
setup() {
provide(DefaultApolloClient, apolloClient);
},
render: (h) => h(App),
}).$mount("#app");
When I use a button or alert and set their colours, it's not using my theme.
Also, even if I try to change to the dark theme, nothing happens.
This is the template:
<template>
<div class="container-fluid d-flex align-items-center justify-content-center">
<div class="row">
<div class="col">
<div class="section section-white">
<h1>This is a test</h1>
<p>With some tests content</p>
<v-btn color="primary">Test</v-btn>
<v-alert type="info"></v-alert>
</div>
</div>
</div>
</div>
</template>
This is what my UI looks like:
As far as I can tell, I have followed the directions correctly, so I have no idea why this is not working.

Try to change this from
import Vuetify from "vuetify/lib/framework";
to
import Vuetify from "vuetify/lib";
Moreover, if you are not able to use theme attributes directly use it like this.
<v-btn :color="$vuetify.theme.themes["light"].primary">Test</v-btn>
or you can also use computed property for that
computedPrimaryColor(){
return this.$vuetify.theme.themes["light"].primary;
}
and use it like
<v-btn color="computedPrimaryColor">Test</v-btn>

Related

I am unable to use vue render functions to render Vuetify uicomponents (v-app-bar, v-navigation-in a standalone vue component

Main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
Vue.config.productionTip = false
new Vue({
vuetify,
render: h => h(App)
}).$mount('#app')
App.vue
template>
<v-app>
<Navbar/>
<div>
<v-content class="mx-4 mb-4">
<router-view></router-view>
</v-content>
</div>
</v-app>
</template>
<script>
import Navbar from '#/components/Navbar'
export default {
name: 'App',
components: {
Navbar
},
data: () => ({
//
}),
};
</script>
Navbar.vue (current)
<template>
<div>
<v-app-bar app flat color="">
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-toolbar-title>
<span>Sample App</span>
</v-toolbar-title>
</v-app-bar>
</div>
</template>
....
....
Navbar.vue (desired)
no template because I want to use render function
<script>
export default {
...
...
render(createElement){
const icon = createElement('v-app-bar-nav-icon')
return createElement('v-app-bar', [icon])
...
...
}
}
When I try this I get an errors:
vue.common.dev.js?4650:630 [Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
Any suggestions?
For future reference:
You simply have to import the vuetify components manually into the vue component.
Navbar.vue
<script>
import { VAppBar, VAppBarNavIcon } from "vuetify/lib";
export default {
render(createElement) {
const icon = createElement(VAppBarNavIcon)
return createElement(VAppBar, {}, [icon]);
},
};
</script>
More info at this link.

How do I add Vuetify 2.0 to an existing project?

I've recently upgraded from Vuetify 1.5 to Vuetify 2.0 and I'm having trouble getting it to work. I feel like I'm missing something.
I downloaded the newest Vuetify package and the #mdi/font package as well. I've followed the instructions in the docs, as far as I can tell: I've added the plugins folder with the vuetify.js file, and as far as I can tell, I've instantiated Vuetify into my Main.js file properly, but none of the stylings appear in my app. I've also tried adding a element tag to my project in various places (my App.vue file and various other page files), but all that seems to do is break things even more; I either get an element to appear on the DOM with no stylings, or the DOM comes up completely white.
Here is my vuetify.js file:
import Vue from "vue";
import Vuetify from "vuetify";
import "#mdi/font/css/materialdesignicons.css";
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: "mdi"
}
});
Here is my main.js file:
import Vue from "vue";
import App from "./App.vue";
import router from "./Router";
import Vuetify from "#/plugins/vuetify";
import 'vuetify/dist/vuetify.min.css'
Vue.config.productionTip = false;
new Vue({
router,
Vuetify,
render: h => h(App)
}).$mount("#app");
Here is my App.vue file:
<template>
<div id="app">
<Header />
<router-view></router-view>
<Footer />
</div>
</template>
<script>
import Header from "./components/Layout/Header";
import Home from "./components/Home";
import InstructorProfile from "./components/InstructorProfile";
import ClassRoster from "./components/ClassRoster";
import Footer from "./components/Layout/Footer";
export default {
name: "app",
components: {
Header,
Home,
InstructorProfile,
ClassRoster,
Footer
},
data() {
return {};
}
};
</script>
As I mentioned before, I have tried adding elements to this file, both like this:
<v-app>
<div id="app">...</div>
</v-app>
And like this:
<div id="app">
<v-app>...</v-app>
</div>
But neither seemed to work better than the other.
I'd like to know if there's something I've left out or I've done wrong.
Any help is much appreciated. Thank you in advance.
try with this:
In vuetify.js file:
import Vue from "vue";
import Vuetify from "vuetify";
import "vuetify/dist/vuetify.min.css"; // Add this line
Vue.use(Vuetify);
const opts = {
theme: {
dark: false
},
options: {
customProperties: true
},
icons: {
iconfont: "mdi"
}
};
export default new Vuetify(opts);
In main.js file:
import Vue from "vue";
import App from "./App.vue";
import router from "#/router";
import vuetify from "#/plugins/vuetify";
Vue.config.productionTip = false;
new Vue({
vuetify,
router,
render: h => h(App)
}).$mount("#app");
I do it this way (vue 3.9, vuetify 2.0)
In main.js
import vuetify from './plugins/vuetify'
...
new Vue({
...
vuetify,
render: h => h(App)
}).$mount('#app')
In plugins/vuetify.js
import Vue from "vue"
import Vuetify from "vuetify/lib"
Vue.use(Vuetify)
export default new Vuetify({
icons: {
iconfont: 'md', // 'mdi' || 'mdiSvg' || 'md' || 'fa' || 'fa4'
},
theme: {
dark: false,
},
themes: {
light: {
primary: "#4682b4",
secondary: "#b0bec5",
accent: "#8c9eff",
error: "#b71c1c",
},
},
})
in App.vue
<template>
<v-app>
...
</v-app>
</template>
I fixed with
npm install vuetify-loader vue-cli-plugin-vuetify -D
https://vuetifyjs.com/en/getting-started/frequently-asked-questions/#questions
I just had to run: vue add vuetify.
From the docs for Vuetify 3
Follow these steps if for example you are adding Vuetify to an existing project, or simply do not want to use a scaffolding tool.
yarn add vuetify#^3.0.0
In the file where you create the Vue application, add the following code
import { createApp } from 'vue'
import App from './App.vue'
// Vuetify
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
const vuetify = createVuetify({
components,
directives,
})
createApp(App).use(vuetify).mount('#app')
See the docs for more info.

FontAwesome SVG icons with Vuetify - how to use within v-icon/prepend-icon?

I'm new to Vue, can't find the exact answer how to use FA SVG icons in v-icon and prepend-icon.
If i use:
<font-awesome-icon :icon="dekstop" color="gray"></font-awesome-icon>
Icons are displayed, but how i can use FA SVG icons in v-icon and prepend-icon?
Sample:
<v-autocomplete v-model="replUser"
:items="users"
color="accent white--text"
label="User"
prepend-icon="dekstop></i>" // i can use material font icons here, but FA SVG not worked
>
</v-autocomplete>
my main.js:
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
// import colors from 'vuetify/es5/util/colors'
import './plugins/vuetify'
import App from './App.vue'
import i18n from './i18n'
import {
library
} from '#fortawesome/fontawesome-svg-core'
import {
FontAwesomeIcon
} from '#fortawesome/vue-fontawesome'
import {
fas
} from '#fortawesome/free-solid-svg-icons'
Vue.component('font-awesome-icon', FontAwesomeIcon) // Register component globally
library.add(fas) // Include needed icons.
Vue.use(Vuetify, {
iconfont: 'faSvg',
})
Vue.config.productionTip = false
new Vue({
i18n,
render: h => h(App)
}).$mount('#app')
What am I doing wrong?
If you want to use svg icons in v-icon/prepend-icon, then you need to access them through $vuetify.icons object. Any other text in the v-icon/prepend-icon will be interpreted as webfont/css class.
But for use $vuetify.icons object you should register custom icons. Example:
import Vue from "vue";
import Vuetify from "vuetify";
import { library } from "#fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "#fortawesome/vue-fontawesome";
import { faVuejs } from "#fortawesome/free-brands-svg-icons";
Vue.component("font-awesome-icon", FontAwesomeIcon); // Register component globally
library.add(faVuejs); // Include needed icons.
Vue.use(Vuetify, {
icons: {
vue: {
component: FontAwesomeIcon,
props: {
icon: ["fab", "vuejs"]
}
}
}
});
And now you can use vue-brand icon:
<v-icon>$vuetify.icons.vue</v-icon>
<v-text-field prepend-icon="$vuetify.icons.vue"/>
Also, you can use without register via font-awesome-icon:
<font-awesome-icon :icon="['fab', 'vuejs']" />
<v-text-field>
<font-awesome-icon :icon="['fab', 'vuejs']" slot="prepend"/>
</v-text-field>
Out of the box vuetify has a preset of icons config that can be associated with SVG:
...
import { fas } from "#fortawesome/free-solid-svg-icons";
...
library.add(fas);
...
Vue.use(Vuetify, {
iconfont: "faSvg"
});
But for use it you should call $vuetify.icons again (vuetify just wrap preset as component):
<v-icon>$vuetify.icons.warning</v-icon>
Full example codesandbox
From Vuetify documention:
Font Awesome is also supported. Simply use the fa- prefixed icon name.
Please note that you still need to include the Font Awesome icons in
your project.
Maybe it helps you. But, without your sample code I can't be sure
<v-autocomplete v-model="replUser"
:items="users"
color="accent white--text"
label="User"
prepend-icon="fa-dekstop">
</v-autocomplete>

Vue2-Leaflet with No-SSR causes Window is not defined error

I've been trying a bunch of stuff now. I've tried nuxt-leaflet dependency, I've tried writing my own plugin and including it. However, everything keeps ending in the "window is not defined" error.
The map should only be loaded on the client.
My vue component:
<template>
<no-ssr>
<l-map
id="map"
:zoom="zoom"
:min-zoom="3"
:center="center"
>
</l-map>
</no-ssr>
</template>
<script lang="ts">
import Vue from 'vue';
import {latLng, marker} from 'leaflet';
import {ExploreItemType} from '~/components/explore/ExploreItem';
import {Component} from "nuxt-property-decorator";
#Component()
export default class ExplorerMap extends Vue {
url = 'https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoia2dydWVuZWJlcmciLCJhIjoiY2puajJ3c3dmMGV1YzNxbDdwZ3Y5MXc0bCJ9.kuHo67NUkzqya1NtSjTYtw';
attribution = 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox';
zoom = 3;
center = latLng(51.505, -0.09);
drawCluster = true;
}
</script>
So I wrote my own plugin in plugins/vue-leaflet.ts
import Vue from 'vue'
import Vue2Leaflet from 'vue2-leaflet'
import Vue2LeafletMarkerCluster from 'vue2-leaflet-markercluster';
Vue.component('l-circle', Vue2Leaflet.LCircle);
Vue.component('l-geo-json', Vue2Leaflet.LGeoJson);
Vue.component('l-icon-default', Vue2Leaflet.LIconDefault);
Vue.component('l-layer-group', Vue2Leaflet.LLayerGroup);
Vue.component('l-map', Vue2Leaflet.LMap);
Vue.component('l-marker', Vue2Leaflet.LMarker);
Vue.component('l-popup', Vue2Leaflet.LPopup);
Vue.component('l-tile-layer', Vue2Leaflet.LTileLayer);
Vue.component('l-tooltip', Vue2Leaflet.LTooltip);
And included it in the nuxt.config.js
{src: "~/plugins/vue-leaflet.ts", ssr: false}
No matter what I've tried, I always end up getting the window is not defined error. I'm out of ideas.
Its because in your component you do
import {latLng, marker} from 'leaflet';
Which probably will do some window check and fail straight away. So you need to import it conditionally with if (process.client) check
Thanks to the hint from Aldarund, I got this to work:
<template>
<div>
<no-ssr>
<l-map
id="map"
:zoom="zoom"
:min-zoom="3"
:center="center"
>
<l-tile-layer :url="url" :attribution="attribution"/>
....
</l-map>
</no-ssr>
</div>
</template>
<script lang="ts">
const isBrowser = typeof window !== 'undefined';
let leaflet;
if (isBrowser) {
leaflet = require('leaflet');
}
import Vue from 'vue';
import {Component, Prop, Watch} from "nuxt-property-decorator";
#Component({})
export default class ExplorerMap extends Vue {
url = 'https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoia2dydWVuZWJlcmciLCJhIjoiY2puajJ3c3dmMGV1YzNxbDdwZ3Y5MXc0bCJ9.kuHo67NUkzqya1NtSjTYtw';
attribution = 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox';
zoom = 3;
center;
created() {
if (isBrowser) {
this.center = leaflet.latLng(51.505, -0.09);
}
....
}

Use vue component in other vue component file

I tried to use a vue component(Global.vue) in other component(App.vue), but there
Failed to mount component: template or render function not defined
error.
Global.vue:
<template>
<div class="global-view">
<p>Global </p>
</div>
</template>
<script>
export default {
name: 'global'
}
</script>
App.vue:
<template>
<div id="app">
<global></global>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
main.js:
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.component('global', require('./components/Global'))
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
You need to import the component within the component file that you want to use it in.
`import Global from './components/Global'
From there you need to add a new key inside your components option that will "register" the component.
Here is what you want your app component to look like.
<template>
<div id="app">
<global></global>
<router-view></router-view>
</div>
</template>
<script>
import Global from './components/Global
export default {
name: 'app'
components: {
'global': Global,
}
}
</script>
<global></global> should be able to render at this point.
I use import instead of require(in main.js) and it works for me:
import Global from './components/Global.vue
Vue.component('global', Global)`