So, firstly, everything you've presented here is possible in Vue. Will firstly give an overview of the key features you can use:
this.$socket.on("msg-input:" + this.id)
- as mentioned in our docs this function call can be used to create your own on-input
listeners.
There are then two options for assigning the styling dynamically:
Option 1 - $ref
Using your current method, there is a Vue-equivalent to document.get...
:
$ref
- this will allow you to do scoped selections of elements within your template. document.querySelector
will work, but won't be constrained to the scope of the ui-template
and will be a nightmare when copying/pasting templates, or re-using elements/icons as you're likely to do here.
Putting the above together, you would result in the following:
<template>
<v-btn class="botao" stacked @click="alternar">
Externa
<v-icon ref="icon" class="icon">mdi-lightbulb</v-icon>
</v-btn>
</template>
<style>
.botao {
background-color: #4F4F4F;
border: 1px solid #808080;
border-radius: 10px;
color: black;
font-size: 11px !important;
}
.icon {
font-size: 40px;
}
</style>
<script>
export default {
methods: {
// expose a method to our <template> and Vue Application
alternar: function () {
// flip the switch
if (window.localStorage.getItem('botao01') === 'ON') {
this.desligar()
} else {
this.ligar()
}
},
ligar: function () {
// store in local storage
window.localStorage.setItem('botao01', 'ON')
// set the style
this.$refs.icon.$el.style.color = '#BD9608'
this.$refs.icon.$el.style.textShadow = '0px 0px 10px #BD9608'
// send on a message
this.send({ payload: 'ON' })
},
desligar: function () {
// store in local storage
window.localStorage.setItem('botao01', 'OFF')
// set the style
this.$refs.icon.$el.style.color = '#A9A9A9'
this.$refs.icon.$el.style.textShadow = '0px 0px 0px'
// send on a message
this.send({ payload: 'OFF' })
},
setState (value) {
if (value === 'ON') {
// turn light on
this.ligar()
} else if (value === 'OFF') {
// turn light off
this.desligar()
}
}
},
mounted () {
// load state from localstorage
this.setState(window.localStorage.getItem('botao01'))
// set up a listener for incoming messages
this.$socket.on("msg-input:" + this.id, (msg) => {
this.setState(msg.payload)
})
}
}
</script>
I have to admit though, i've just spent an hour getting this to work. I hadn't appreciated that, when using ref=
with a Vuetify component (or any Vue component for that matter) the this.$refs["my-ref"]
returns the associated Vue component, not the raw DOM element, so you need to include .$el
as you'll see in my example.
Option 2 - Computed Variables
If you're interested though, a more Vue-way of doing this would be:
<template>
<v-btn class="botao" stacked @click="alternar">
Externa
<v-icon ref="icon" class="icon" :class="iconOnOff">mdi-lightbulb</v-icon>
</v-btn>
</template>
<style>
.botao {
background-color: #4F4F4F;
border: 1px solid #808080;
border-radius: 10px;
color: black;
font-size: 11px !important;
}
.icon {
font-size: 40px;
}
.icon.on {
color: #BD9608;
text-shadow: 0px 0px 10px #BD9608;
}
.icon.off {
color: #A9A9A9;
text-shadow: 0px 0px 0px;
}
</style>
<script>
export default {
data () {
return {
state: 'OFF'
}
},
computed: {
iconOnOff: function () {
return this.state.toLowerCase()
}
},
methods: {
// expose a method to our <template> and Vue Application
alternar: function () {
// flip the switch
if (window.localStorage.getItem('botao01') === 'ON') {
this.setState('OFF')
} else {
this.setState('ON')
}
},
ligar: function () {
// store in local storage
window.localStorage.setItem('botao01', 'ON')
// send on a message
this.send({ payload: 'ON' })
},
desligar: function () {
// store in local storage
window.localStorage.setItem('botao01', 'OFF')
// send on a message
this.send({ payload: 'OFF' })
},
setState (value) {
this.state = value
if (value === 'ON') {
// turn light on
this.ligar()
} else if (value === 'OFF') {
// turn light off
this.desligar()
}
}
},
mounted () {
// load state from localstorage
this.setState(window.localStorage.getItem('botao01'))
// set up a listener for incoming messages
this.$socket.on("msg-input:" + this.id, (msg) => {
this.setState(msg.payload)
})
}
}
</script>
Here, I utilise a computed
variable which automatically updates the class on the icon whenever this.state
changes.