vuetify change theme to a custom one - vue.js

I've been using Vuetify for a few weeks now.
Having read the docs and some posts in that regard I tried to alter the 'dark' theme to suite my needs.
From some reason, I can only alter colours to components by specifically setting their colours of via CSS of course.
my vuetify.js file (under plugins) looks like that:
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import colors from 'vuetify/lib/util/colors';
Vue.use(Vuetify);
export default new Vuetify({
theme: {
themes: {
light: {
primary: colors.purple,
secondary: colors.grey.darken1,
accent: colors.shades.black,
error: colors.red.accent3,
},
dark: {
primary: colors.blueGrey.darken2,
secondary: colors.blueGrey.lighten2,
accent: colors.blueGrey.darken3,
},
},
},
});
My App.vue file looks like that:
<div>
<v-app dark>
<v-tabs background-color="#2c394f" color="white">
<v-tab to="/deploy">Deploy</v-tab>
<v-tab to="/dashboard">Dashboard</v-tab>
</v-tabs>
<keep-alive>
<router-view/>
</keep-alive>
</v-app>
</div>
</template>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<style scoped>
</style>
As you may notice, I'm using dark theme (in v-app component) and since my theme definitions are not being applied, I've manually set the (for instance) v-tabs component.
Ideally, I'd like to just set the colour of v-tabs using color="primary" or something like that, but if I remove the properties, I'm getting the default theme, which is 'light' in that case.
Any help will be appreciated.

You just need to set theme.dark:true to enable dark for the entire app.
Then the custom dark colors will be applied..
export default new Vuetify({
theme: {
dark: true,
themes: {
light: {
primary: colors.purple,
secondary: colors.grey.darken1,
accent: colors.shades.black,
error: colors.red.accent3,
},
dark: {
primary: colors.blueGrey.darken2,
secondary: colors.blueGrey.lighten2,
accent: colors.blueGrey.darken3,
},
},
},
})
Demo

To extend Zim answer, there's also the ability to set it programatically if you want to provide that option to the user using this.$vuetify.theme.dark //bolean.
This example may be seen in the documentation https://vuetifyjs.com/en/features/theme/#theme-provider
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: ['One', 'Two', 'Three']
}),
})
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-main>
<v-container>
<v-card flat>
<v-toolbar flat height="72">
<v-switch v-model="$vuetify.theme.dark" hint="This toggles the global state of the Vuetify theme" inset label="Vuetify Theme Dark" persistent-hint></v-switch>
</v-toolbar>
<v-card-text>
<v-list dark>
<v-subheader>I inherit dark from my parent</v-subheader>
<v-list-item v-for="item in items" :key="item">
<v-list-item-title v-text="item"></v-list-item-title>
</v-list-item>
</v-list>
<v-divider class="mb-y"></v-divider>
<v-theme-provider root>
<v-list>
<v-subheader>
<span>I inherit from the root</span>
<strong> $vuetify.theme.dark</strong>
</v-subheader>
<v-list-item
v-for="item in items"
:key="item"
>
<v-list-item-title v-text="item"></v-list-item-title>
</v-list-item>
</v-list>
</v-theme-provider>
</v-card-text>
</v-card>
</v-container>
</v-main>
<v-footer>Footer without app</v-footer>
</v-app>
</div>

Related

Center text vertically in v-chip

How can I center the text inside a v-chip component vertically?
Since it's a vuetify component, I looked at the documentation but there's no such property for this.
<v-chip
v-if="this.drawerNodeData.type == 'Telecom'"
:color="telecom"
text-color="white"
class="chips"
>
{{ this.drawerNodeData.type }}
</v-chip>
As you said styles for chips class are not yet implemented. In that case your code should work as per the requirement as by default chip text center aligned vertically and horizontally. Here is the demo :
new Vue({
el: '#app',
vuetify: new Vuetify()
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/vuetify#2.0.1/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify#2.0.1/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"/>
<div id="app">
<v-app id="inspire">
<v-container>
<v-chip color="primary" text-color="white">Default</v-chip>
</v-container>
</v-app>
</div>

Vuetify switch/checkbox label displaying wrong

I'm trying to add a v-switch to my web app.
But it displays wrong (label should be next to v-switch, but as you can see from the picture)
Any ideas on how to fix this?
I am not sure about your source code but ideally it should work. Here is the Demo :
Vue.use(Vuetify);
new Vue({
el: '#app',
data () {
return {
switch1: false,
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<script src="https://unpkg.com/vuetify#0.14.8/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#0.14.8/dist/vuetify.min.css"/>
<div id="app">
<v-app id="inspire">
<v-container>
<v-switch
v-model="switch1"
label="Test Switch Label"
></v-switch>
</v-container>
</v-app>
</div>
Please let me know what challenge you are facing as per above code snippet.
Solved it with this easy-CSS trick!
<style>
.v-input__control label {
top: 0px;
}
</style>

How to insert a <a> tag or icon inside Vuetify internationalization?

I'm currently working on a project based on Vuetify. I need to insert a <a> tag and icon inside an internationalization text. Generally, it is easy to insert a variable as below shows,
this.$vuetify.lang.$t('I'm {0}', varirable_name)
but in this way, I cannot insert <a> tag or an icon <v-icon>, how could I achieve it?
Just like this,
`this.$vuetify.lang.$t('Here is an icon {0} and a {1}', <v-icon />, <a>link</a>)`
You can use v-html directive to output raw HTML. It will work for basic tags but won't work for Vuetify's v-tags (for example, v-icon).
new Vue({
vuetify: new Vuetify(),
data() {
return {
message: this.$vuetify.lang.t('Here is an bold {0} and a {1}', "<strong>text</strong>", "<a>link</a>")
}
}
}).$mount('#app')
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-container><span v-html="message"></span ></v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
I wouldn't recommend using Vuetify tags in composite format strings. Instead, translate the text inside of the tag.
<v-btn class="ma-2" color="primary" dark>
Accept // <- translate only this
<v-icon dark right>
mdi-checkbox-marked-circle
</v-icon>
</v-btn>

Is possible extract vuetify rules in external file to reuse it?

i'm using vue + vuetify + typescript to build a login/register form.
According to official documentation from vuetify https://vuetifyjs.com/en/components/forms#creating-rules is possible add custom rules.
My question is: is possible extract this rules in separate files as classes, functions, etc...that could be parametrized from template to reuse it?
You can have your rules written to an external file. Here's an example where the rules are in a js variable:
Vue.use(Vuetify)
// or : import externalRules from '#/rules/MyRules.js'
var externalRules = [
v => !!v || 'Name is required',
v => (v && v.length <= 10) || 'Name must be less than 10 characters'
]
new Vue({
el: "#app",
data: {
valid: true,
name: '',
nameRules: externalRules
},
methods: {
validate() {
if (this.$refs.form.validate()) {
this.snackbar = true
}
},
reset() {
this.$refs.form.reset()
},
resetValidation() {
this.$refs.form.resetValidation()
}
}
})
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-form ref="form" v-model="valid" lazy-validation>
<v-text-field v-model="name" :counter="10" :rules="nameRules" label="Name" required></v-text-field>
<v-btn :disabled="!valid" color="success" #click="validate">
Validate
</v-btn>
<v-btn color="error" #click="reset">
Reset Form
</v-btn>
<v-btn color="warning" #click="resetValidation">
Reset Validation
</v-btn>
</v-form>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
</body>
</html>

Vuetify breakpoints not breaking?

I am having an issue with Vuetify not breaking my flex boxes like expected when viewing on small screen. I expect the form to break into 3 parts each spanning 12 cols when viewing on a small screen. However what happens is it just retains it's size from the original. It does not stack verticly like expected. The template code is below;
EDIT: I can tell that vuetify is updating the the breakpoints, but the layout does not change. If I set a computed property to this.$vuetify.breakpoint.lgandup I can see that when changing the screen size the boolean changes to false when it should and back to true when it should. But the layout does not change.
EDIT: I've updated my question with some more information and tried to include all relevant files.
EDIT: I want to add that I have figured out a small work around, by adding 'wrap'.. <v-layout row wrap> however it seems that this would not be needed since I'm already telling vuetify to break that into a full 12 col span on small screens, so there shouldn't be anything to wrap. Still looking for more insight here.
main.js
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import '#mdi/font/css/materialdesignicons.css'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// Override default theme for Vuetify
Vue.use(Vuetify, {
iconfont: 'mdi',
theme: {
"primary": "#673ab7",
"secondary": "#757575",
"accent": "#d500f9",
"error": "#ff1744",
"info": "#d500f9",
"success": "#4caf50",
"warning": "#ff9100"
}
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
app.vue
<template>
<div id="app">
<v-app>
<nav-draw/>
<nav-bar/>
<v-content>
<v-container fluid>
<v-layout row>
<v-flex x12 sm12 md12 lg1 xl1>
Test
</v-flex>
<v-flex xs12 sm12 md12 lg9 xl9>
{{ this.$vuetify.breakpoint.mdAndDown }}
</v-flex>
<v-flex xs12 sm12 md12 lg2 xl2>
{{ this.$vuetify.breakpoint.lgAndUp }}
</v-flex>
</v-layout>
</v-container>
</v-content>
<v-footer app>2019 .com</v-footer>
</v-app>
</div>
</template>
<script>
import NavDraw from '#/components/NavDraw'
import NavBar from '#/components/NavBar'
export default {
components: {NavDraw, NavBar }
}
</script>
public/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="<%= webpackConfig.output.publicPath
%>favicon.ico">
<title>FranchiseFaves</title>
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
Any help is appreciated!
try to remove the <div id="app"> in you app.vue. because you already call it in
public/index.html