[Vuejs]-Override Vuetify RTL for specific component/component tree

1πŸ‘

βœ…

The slider uses this.$vuetify.rtl to determine the direction. However, this.$vuetify is a global object, where changing the rtl value will change it for the whole application.

But you can replace the object in the component instance. To do this, you need to access the component instance, which you can do through a template ref or using a directive:

Vue.directive(
  'vuetify-ltr', 
  (el, binding, vnode) => {
    const instance = vnode.componentInstance
    if (!instance.$vuetify) return
    instance.$vuetify = new Proxy(instance.$vuetify, {
      get(target, prop, receiver) {
        return prop === 'rtl' ? false : target[prop]
      },
    })
  }
)

This uses a Proxy to keep the other data from $vuetify bound to the original object. But since VSlider does not use any other values from $vuetify, you could also just override the whole thing.

With the directive, you can now switch the direction for individual Vuetify components:

<v-slider
  v-vuetify-ltr
  ...
/>

Here it is in a snippet:

Vue.directive(
  'vuetify-ltr', 
  (el, binding, vnode) => {
    const instance = vnode.componentInstance
    if(!instance.$vuetify) return
    instance.$vuetify = new Proxy(instance.$vuetify, {
      get(target, prop, receiver) {
        return prop === 'rtl' ? false : target[prop]
      },
    })
  }
)

new Vue({
  el: '#app',
  vuetify: new Vuetify({
    rtl: true,
  }),
})
<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-slider label="rlt"></v-slider>
      <v-slider label="ltr" v-vuetify-ltr></v-slider>
      <v-slider label="still rlt"></v-slider>
    </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>

Leave a comment