Use Vue Components in Angular 1.x
ngVue is a JavaScript module designed to integrate Vue 2 components within AngularJS 1.x applications. It provides a bridge, enabling developers to use Vue's reactive data binding and component-based architecture within existing Angular 1.x codebases. This allows for a gradual migration of view layers from Angular 1.x to Vue 2, addressing common performance bottlenecks related to Angular's scope watchers and offering a more predictable one-way data flow. The current stable version is 2.2.1. While the project sees occasional maintenance releases to address minor issues and improve compatibility (e.g., ESM support), its primary use case targets older, established Angular 1.x applications rather than new development. Key differentiators include its `vue-component` directive and `createVueComponent` factory, specifically tailored for interop between these two legacy frameworks. For Vue 3 support, users are explicitly directed to use the separate `ngVue3` package.
Common errors
-
Uncaught ReferenceError: process is not defined
cause ngVue versions prior to 1.7.5 attempted to access the Node.js `process` global in browser environments, leading to errors.fixUpgrade `ngVue` to version 1.7.5 or later. If using an older version and a bundler, ensure `process` is properly polyfilled or mocked for browser builds. -
Uncaught TypeError: e.warn is not a function
cause This error occurred in `ngVue` versions prior to 1.7.4 when the internal logger attempted to call a `warn` method on an object that did not have it defined.fixUpgrade `ngVue` to version 1.7.4 or later to fix the logger initialization logic.
Warnings
- breaking ngVue is specifically designed for Vue 2 and AngularJS 1.x. For applications targeting Vue 3, users *must* switch to the separate `ngVue3` package, as `ngVue` is not compatible with Vue 3.
- breaking Earlier versions of ngVue (2.0.0 to 2.1.0) had incomplete or broken ESM (ECMAScript Module) support, which could lead to build failures or runtime errors when bundling with modern tools. This was primarily due to incorrect `exports` field in `package.json`.
- gotcha Version 2.0.0 introduced support for Vue 2 Composition API. While described as having no *expected* breaking changes, this was a significant internal refactor. Existing components or integrations might exhibit subtle behavioral differences or require minor adjustments if they relied on specific internal behaviors of `ngVue` before this update.
- gotcha Versions of `ngVue` prior to 1.7.8 had a known memory leak issue related to the mounted lifecycle hook of Vue components, which could cause performance degradation in long-running Angular 1.x applications with a high turnover of Vue components.
- deprecated Before version 2.2.1, a deprecation warning related to camelCase event naming styles could appear during bootstrapping. Although the specific warning was removed, it's generally best practice to use kebab-case for custom events in Vue components exposed through `ngVue` to ensure consistency and avoid potential issues with HTML attribute parsing.
Install
-
npm install ngVue -
yarn add ngVue -
pnpm add ngVue
Imports
- ngVue (module registration)
const ngVue = require('ngVue'); angular.module('yourApp', [ngVue]);import 'ngVue'; angular.module('yourApp', ['ngVue']); - createVueComponent
import createVueComponent from 'ngVue';
import { createVueComponent } from 'ngVue'; - ngVueReduxPlugin (example)
import { ngVueReduxPlugin } from 'ngVue/plugins/redux';import 'ngVue/plugins/redux'; angular.module('yourApp', ['ngVue', 'ngVueReduxPlugin']);
Quickstart
import angular from 'angular';
import Vue from 'vue';
import 'ngVue';
// Define a simple Vue component
const MyGreetingComponent = {
template: `
<div>
<h3>Hello from Vue!</h3>
<p>{{ message }}</p>
<button @click="emitEvent">Click me (Vue)</button>
</div>
`,
props: ['message'],
methods: {
emitEvent() {
this.$emit('vue-clicked', 'Hello from Vue event!');
}
}
};
// Register ngVue and define the Angular app
angular.module('myApp', ['ngVue'])
.controller('MyController', function($scope, $rootScope, createVueComponent) {
// Expose the Vue component to ngVue via $rootScope.components
// This is a common pattern for ngVue to find components by name
$rootScope.components = {
MyGreetingComponent: MyGreetingComponent
};
$scope.angularMessage = 'Data from Angular scope.';
$scope.vueData = {
message: 'This prop is passed from Angular to Vue.'
};
$scope.vueEvents = {
'vue-clicked': function(payload) {
console.log('Vue component clicked! Payload:', payload);
alert('Vue component received event: ' + payload);
}
};
});
// To use in HTML (assuming an index.html file):
// <div ng-app="myApp" ng-controller="MyController">
// <h2>Angular App with Vue Component</h2>
// <p>Message from Angular: {{ angularMessage }}</p>
// <vue-component name="MyGreetingComponent" v-props="vueData" v-on="vueEvents"></vue-component>
// </div>