We're in the early stages of migrating from angularJS to use Vue 3 in conjunction with Razor .cshtml templates, but we seem to have hit a bit of a roadblock.
Where in angularJS we had controllers to handle accepting and initialising scoped variables, we're struggling to do so in VueJS due to its one-way data flow.
We have data coming from the .cshtml models that Vue obviously has no clue about and no way to do an ng-init equivalent (I've tried making a custom directive to assign a value to a data property but it won't stick for some reason)
At the moment we're using scoped slots to act as a pseudo-controller (or, an adaptation of option 1 here https://chowson.github.io/vuejs-sitecore-mvc/) :
ImageGalleryController.vue
<template>
<slot :imageData="imageData" ></slot>
</template>
<script>
export default {
name: "ImageGalleryController,",
data() {
return {
images: [],
imageData: {
selectedIndex: 0,
setIndex: this.setSelectedIndex
}
}
},
setup() {
},
methods: {
setSelectedIndex(index: number) {
this.selectedIndex = index;
return
}
}
}
</script>
And then in the .cshtml:
_ImageGallery.cshtml
<image-gallery>
<template v-slot="data" class="product-image-gallery">
<div class="row image-gallery-row">
<!-- A mix of razor and vue code goes here-->
</div>
</template>
</image-gallery>
Formerly in the above code we'd have had something like ng-init(@Newtonsoft.Json.JsonConvert.SerializeObject(images) (where images have been retrieved from the database)
I suppose the real question is whether there's a more elegant/not-hacky way to pass data from/to vue components to "external" templates?
It feels like we're breaking Vue, but I'd rather not sacrifice the benefits of having partially server-side rendered pages.
Also concerned that we'd potentially be passing a large number of objects through to the slot which doesn't feel right.
Thanks