Переход на VueJS - Другой способ

Я нашел способ, который лучше соответствует нашей реальности. В этом посте я покажу, как я это делаю.

В моем последнем посте Переход с Angular на VueJS я показал, как я начал переходить с AngularJS на VueJS.

Это был не лучший способ для нас. Мы нашли другой ответ.

Во-первых: контекст

Для тех, кто не читал первый пост (Переход с Angular на VueJS): я собираюсь перенести устаревшую веб-платформу, написанную на AngularJS.

Первой попыткой было разместить несколько маршрутов AngularJS для нескольких экземпляров VueJS и иметь код Vue внутри Angular.

Основная проблема с этим подходом заключается в том, что в какой-то момент мне придется реорганизовать код в соответствии с Vue.

Не хорошая идея.

Решение

Решение состоит в том, чтобы иметь ОДНУ точку входа в приложение VueJS внутри Angular и писать и строить на VueJS.

Общая идея такова:
1. Создайте приложение Vue с помощью vue-cli
2. Заставьте Webpack build генерировать файл в папку webapp, где находится Angular
3. Поместите единственный путь в Angular router
4. В этом маршрутизаторе контроллер Angular создает экземпляр единственного экземпляра Vue.

Создание приложения Vue с помощью vue-cli

Структура папок проекта выглядит примерно так:

+ Project
   + web
      - index.html(Vue)
   + webapp
      - index.jsp (Tomcat + Angular)

В веб-папке запускаем:

$ vue init webpack .

Будет создан проект Vue.
Теперь нам нужно изменить конфигурацию сборки по умолчанию. Давайте создадим сборку для миграции:

Создание сборки для переноса

Сборка миграции - это сборка для разработки, но для нашего контекста она перемещает все сгенерированные файлы в папку webapp / dist /,, чтобы их можно было использовать в приложении.

  1. Отредактируйте package.json и добавьте новый скрипт
{
    ...
    "scripts": {
        "dev-migration": "node build/build-migration.js"
    }    
    ...
}

2. Создайте build / build-migration.js с тем же содержанием из build / build.js и отредактируйте следующие строки:

process.env.NODE_ENV = 'development'; // it was 'production'
...
const webpackConfig = require('./webpack.migration.conf') // it was webpack.prod.js
...
const spinner = ora('building for migration...') // it was for production

Правильно, мы используем производственную сборку со схемой разработки.

3. Создайте build / webpack.migration.js с тем же содержанием, что и build / webpack.dev.conf.js.

Добавьте watch: true в конфигурацию веб-пакета:

// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
watch: true,
// these devServer options should be customized in /config/index.js
devServer: {

Удалите и измените module.exports из Promise на конфигурацию webpack:

module.exports = devWebpackConfig

4. Измените сгенерированный путь в config / index.js.

Измените его на конечную папку назначения, в моем случае это была webapp / dist, потому что мы используем Tomcat, и он читает и сервер файлы из webapp

...
dev: {
  index: path.resolve(__dirname, '../../webapp/dist/index.html'),
  assetsRoot: path.resolve(__dirname, '../../webapp/dist/'),
...

Обратите внимание на относительный путь в нашей структуре папок.

5. Теперь запустите npm run dev-migration.

$ npm run dev-migration

Он должен создать режим разработки, но теперь файлы копируются в webapp / dist.

6. Включите сгенерированные файлы в приложение.

Теперь в webapp / index.jsp можно включить приложение Vue.

<script src="./dist/app.js"></script>

Изменение Vue и Angular для рендеринга экземпляров Vue

  1. Настройте контроллер Angular и маршрутизатор для рендеринга экземпляра Vue

В вашем роутере сделайте что-то вроде этого:

{
    path: '/vue/*',
    controller: 'VueJSController',
    template: '<div id="vue-app"></div>'
}

Он будет обрабатывать ВСЕ пути vue внутри / vue / something с помощью VueJSController.

Создайте VueJSController:

angular.controller('VueJSController', function($scope) {
   // do it for now, I'll explain later
   // pay attention to this id, it matches the Angular template
   var vueApp = window.initVue('#vue-app'); 
   $scope.$on('$destroy', function(){
     vueApp.$el.remove();
     vueApp.$destroy();
     vueApp = null;
   });
})

Уничтожение позволяет избежать повторного создания одного и того же экземпляра, что приводит к утечке памяти и проблемам с маршрутизацией.

2. Измените VueJS main.js, добавив в него метод initVue (el).

Вот что дает vue-cli:

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

Мы создаем функцию для генерации этого экземпляра:

window.initVue = (id) => {
  new Vue({
    el: id,
    router,
    template: '<App/>',
    components: { App }
  })
}

Измените VueRouter, чтобы / vue был корневым

Перейдите к корневому маршруту маршрутизатора VueJS и добавьте / vue, чтобы он соответствовал маршруту Angular. Это заставит Vue Router работать с Angular.

СДЕЛАНО!

Что теперь происходит?

Когда вы переходите к / vue / something, Angular сопоставит этот маршрут, создаст контроллер, контроллер создаст экземпляр приложения Vue в этом элементе, и все перейдет во Vue.

Когда вы редактируете компонент Vue, Webpack пересобирает и помещает все новые файлы в папку dist. Затем после перезагрузки приложения весь новый код Vue будет, например, внутри Tomcat.

Единственный минус в том, что у вас нет Hot Module Reload, потому что Tomcat обслуживает все файлы.

В следующем посте я покажу, как создать проект библиотеки для создания общих компонентов.

Поделитесь, прокомментируйте, поставьте лайк.

Спасибо!!