I am experimenting with widgets in D2 ui-template. I have a v-select
and the docs suggests that @update:modelValue
should be fired when the selected value changes, but I can't get this to work. @click
does work. This is what I have so far. The code that changes the selection when an option is passed in msg.payload does work. Can anyone see what I am doing wrong?
<template>
<div>
<v-select
:items="items"
:model-value="value"
@update:modelValue="mvchanged"
@click="clicked"
></v-select>
</div>
</template>
<script>
export default {
data() {
return {
dropdownData: {options: ['Foo', 'Bar', 'Fizz', 'Buzz']}
}
},
watch: {
msg: function(){
if (typeof this.msg.payload === "string" && this.dropdownData.options.includes(this.msg.payload)) {
this.dropdownData.value = this.msg.payload
}
// prevent redraw on deploy
//this.msg.payload = null
}
},
methods:{
mvchanged:function(){
this.send({payload: "modelValue changed"});
},
clicked:function(){
this.send({payload: "clicked"});
},
},
computed : {
items: function(){
return this.dropdownData?.options ?? ""
},
value: function(){
return this.dropdownData?.value ?? ""
}
}
}
</script>
[Clarification Edit] When I said that I can update the selection by passing in a message, that does change the selection but does not trigger the event.
I think it should be v-model="value"
going by example
<v-rating hover :length="5" :size="32" v-model="value"
active-color="primary" @update:modelValue="send({payload: value})"/>
Both work for me, possibly for compatibility with an older version of vue. Changing that does not make the update trigger work. The docs I linked to show model-value.
I also tried @change.
I noticed also that @update:modelValue
didnt work,
when i was testing recently for another post that used v-select
After some research on the internet, what worked for me is to use @update:model-value="mvchanged"
instead.
<template>
<div>
<v-select
:items="items"
v-model="value"
@update:model-value="mvchanged"
></v-select>
</div>
</template>
<script>
export default {
data() {
return {
dropdownData: {options: ['Foo', 'Bar', 'Fizz', 'Buzz']},
value: this.dropdownData?.value ?? ""
}
},
watch: {
msg: function(){
if (typeof this.msg.payload === "string" && this.dropdownData.options.includes(this.msg.payload)) {
this.dropdownData.value = this.msg.payload
}
// prevent redraw on deploy
//this.msg.payload = null
}
},
methods:{
mvchanged:function(){
this.send({payload: this.value});
},
clicked:function(){
this.send({payload: "clicked"});
},
},
computed : {
items: function(){
return this.dropdownData?.options ?? ""
}
}
}
</script>
Great, that works. Thanks.
Did you manage to access the new value? I can't work out how to do that. If, in the mvchanged function I put
this.send({payload: "model-value changed " + this["model-value"]})
then it just sends the value as undefined.
The only way I could get this to fire an event when a msg (via an inject node) is sent to the widget is this;
<template>
<div>
<v-select
:items="items"
v-model="value"
@update:model-value="mvchanged"
></v-select>
</div>
</template>
<script>
export default {
data() {
return {
dropdownData: {options: ['Foo', 'Bar', 'Fizz', 'Buzz']},
value: ""
}
},
watch: {
value: function () {
this.send({value: this.value})
},
},
methods: {
mvchanged: function() {
this.send({payload: this.value})
},
},
computed : {
items: function() {
return this.dropdownData?.options ?? ""
},
},
mounted () {
this.$socket.on("msg-input:" + this.id, (msg) => {
/**
*
* topic: ,
* payload: "<value>"
*
*/
if (typeof msg.payload === "string" && this.dropdownData.options.includes(msg.payload)) {
this.value = msg.payload
}
})
},
}
</script>
mvchanged
only fires when a selection is clicked on in the dropdown. With the code above the @update:model-value="mvchanged"
(and therefor the mvchanged
function) is not required. The send
works both ways (selection & msg in)
All good with that solution. Thanks.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.