а vue выступает сугубо в роли небольших компонентов на разных страницах
Исходя из этого я могу предположить, что подобные виджетики скорее всего не нуждаются в серверном рендере, а значит все довольно просто.
Настраиваем любой сборщик (webpack, vite). На входе будет какой-нибудь main.js, на выходе готовый файл (по умолчанию), пара файлов (main и vendor, если настроили разделение) или больше, в зависимости от хитрожопости настроек. Вот эти файлы и подключаем (соблюдая порядок, если их несколько, например vendor перед main)
В main можно писать весь фронт сайта, или модульно импортировать.
Туда же подключается вью и компоненты ваших виджетов
import Vue from 'vue';
import Calculator from './calc/Calculator.vue';
На странице, где нужно вставить компонент пишем нечто вроде
<div class="calc"></div>
Сюда будет рендериться компонент в рантайме. Например так (в том же main.js)
document.querySelectorAll('.calc').forEach(el => {
new Vue({
el : el,
render: h => h(Calculator, {
props: {
/// Пропсы, если надо
},
}),
});
});
То есть каждый виджет в этом случае будет независимым vue приложением.
Если нужно передавать в компоненты какие-то данные, то можно научить компонент самому их запрашивать. Но тут придется отдельные роуты создавать. Или прямо на страницу в head выплевывать их в виде json
<script>window.calcData = <?= json_encode($calcData) ?>;</script>
а в компоненте по mounted их доставать
mounted() {
const d = window.calcData;
}