Best approach when replacing jQuery with VueJS 2 in multi-page existing .NET MVC application

10,777

Solution 1

Extremely Basic

The most basic way to get started I know of with Vue in ASP.NET is just to include the Vue script in your project. You can use the vue.js Nuget package, which will add the Vue scripts to your Scripts directory and just include either the development or minified version in your MVC view.

<script src="~/Scripts/vue.min.js"></script>

Then in your view cshtml, just add a script block.

<script>
    new Vue({
        el: "#app",
        data: {
            message: "Hello from Vue"
        }
    })
</script>

where #app refers to an element on your view. If you want to use a component, just add it to your script block.

<script>
    Vue.component("child", {
        template:"<h1>I'm a child component!</h1>"
    })

    new Vue({
        el: "#app",
        data: {
            message: "Hello from Vue"
        }
    })
</script>

and modify your Vue template.

<div id="app">
    {{message}}
    <child></child>
</div>

If you find yourself building a lot of components (which you likely will), extract them into a vue.components.js file or something similar, define all your components there, and include that on your views in addition to the vue script.

Using Single File Components

In order to use single file components, you need to integrate the node.js build process for single file components into your ASP.NET MVC build process.

Install node.js. After node.js is installed, install webpack globally.

npm install webpack -g

Add a package.json to your project. Here is what I use.

{
  "version": "1.0.0",
  "name": "vue-example",
  "private": true,
  "devDependencies": {
    "babel-core": "^6.23.1",
    "babel-loader": "^6.3.2",
    "babel-preset-env": "^1.1.8",
    "css-loader": "^0.26.1",
    "style-loader": "^0.13.1",
    "vue-loader": "^11.1.0",
    "vue-template-compiler": "^2.1.10",
    "webpack": "^2.2.0"
  },
  "dependencies": {
    "vue": "^2.2.1"
  }
}

I typically create a folder in my project to hold my Vue scripts and .vue files called Vue. Add a file to serve as the entry point for your Vue build process. We can call this index.js (or anything you want).

import Vue from 'vue'
import App from './App.vue'

new Vue({
    el: '#app',
    render: h => h(App)
})

Create App.vue.

<template>
    <div id="app">
        {{msg}}
    </div>
</template>

<script>
    export default {
      name: 'app',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      }
    }
</script>

Add a webpack.config.js to your project. Here is what I use.

module.exports = {
    entry: "./Vue/index.js",
    output: {
        path: __dirname,
        filename: "./Vue/bundle.js",
    },
    module: {
        loaders: [
            { test: /\.vue$/, loader: 'vue-loader' },
        ],
    }
}

This config specifies index.js as the entry point for webpack to figure out what to include in a bundle.js file, which will be compiled and put in the Vue folder.

In order to compile the bundle.js file whenever the project builds, I modify the project file to include the following.

<Target Name="RunWebpack">
  <Exec Command="npm install" />
  <Exec Command="webpack" />
</Target>
<Target Name="BeforeBuild" DependsOnTargets="RunWebpack"></Target>

This will install the necessary npm packages and then run webpack to build the bundle.js. This is necessary if you are building your project on a build server.

Now you just need to include the bundle.js file on a view that has an element with #app on it. You do not need to include vue.js or vue.min.js. That will be in the bundle.

Compile Individual Single File Components

We found there were times we wanted to use a single file component, but did not want to bundle it all into a single script. To do this, you mainly need only modify the webpack.config.js.

const fs = require("fs");
const path = require("path");

// build an object that looks like 
// {
//      "filename": "./filename.vue"
// }
// to list the entry points for webpack to compile.
function buildEntry() {
    const reducer = (entry, file) => { entry[file.split(".").shift()] = `./Vue/${file}`; return entry; };

    return fs.readdirSync(path.join(__dirname, "Vue"))
        .filter(file => file.endsWith(".vue"))
        .reduce(reducer, {});
}

module.exports = {
    entry: buildEntry(),
    output: {
        path: path.join(__dirname, "Vue"),
        filename: "[name].js",
        library: "[name]"
    },
    module: {
        loaders: [
            { test: /\.vue$/, loader: 'vue-loader' },
        ],
    }
}

This webpack configuration will build a script file for every individual single file component. Then you can just include that script on a page where you are using the "Extremely Basic" technique above and use the component in your Vue by either exposing it globally or as part of the Vue. For example, if I have a Modal.vue, I would include Modal.js on the ASP.NET MVC view and then expose it to Vue by

Vue.component("Modal", Modal);

or

new Vue({
    ...
    components:{
        "Modal": Modal
    }
})

Webpack is very configurable, so you may want to take a different approach and build a single bundle for each page.

Finally, you can open a command line while you are developing and run

webpack --watch

in your project directly and your bundle(s) or individual components will be built every time you save them.

Solution 2

I was trying to set up Vue with ASP.NET MVC 5 (.NET 4.5, not Core!) by following a post published above by @Bert, but I have encountered many problems so I found another way:

(WARNING: if you want use vue.js with own components you need install node.js - for npm, webpack - for building bundles and vue-loader - for parsing *.vue files)

  1. Install node.js
  2. Run Node.js command prompt and navigate to your Visual Studio project folder (where is placed the *.csproj file)
  3. Type: npm init -y and hit enter - it should generate packages.json file with dependencies and basic settings
  4. Add necessary loaders for Vue (without these, *.vue files can't be parsed to javascript in bundle): npm install --save-dev vue-loader vue-template-compiler
  5. Add webpack (globally) and save it in our package.json file:

    a) npm install -g webpack

    b) npm install –-save-dev webpack

  6. Finally, add Vue.js to project: npm install --save vue

For now, my package.json looks like:

{
  "name": "VueExample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "vue-loader": "^14.2.1",
    "vue-template-compiler": "^2.5.16",
    "webpack": "^4.2.0"
  },
  "dependencies": {
    "vue": "^2.5.16"
  }
}
  1. The next step is configuring webpack - go back to Visual Studio and add to project webpack.config.js file, and paste the following code to it:

module.exports = {
    entry: './Vue/index.js',
    output: {
        path: __dirname,
        filename: './Vue/dist/bundle.js'
    },
    devtool: 'source-map',
    module: {
        rules: [
            {
                test: /\.vue$/,
                exclude: /node_modules/,
                loader: 'vue-loader'
            }
        ]
    }
};
  1. Add Vue folder to your project and place two files in it - index.js and App.vue:

index.js:

import Vue from 'vue'
import App from './App.vue'

new Vue({
    el: '#app',
    render: h => h(App)
});

App.vue:

<template>
    <div id="app">
        {{msg}}
    </div>
</template>

<script>
    export default {
      name: 'app',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      }
    }
</script>
  1. Sample index.cshtml file:

@{
    ViewBag.Title = "Home Page";
}

<div id="app">

</div>

@section scripts{
    <script src="~/Vue/dist/bundle.js"></script>
}
  1. Go back to Node.js command prompt opened in 2) and run webpack by typing: webpack, hit enter and wait for build your bundle.js which you can find in ~/Vue/dist/bundle.js
  2. Build your project in Visual Studio and run it.

Solution 3

I used a lot of the answer as provided by @1_bug to set up Vue Single File Component bundling with webpack in my ASP.NET MVC 4.5 project.

However, when trying to build the bundle, using the webpack command, I received the following error :

"vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config."

Looking into this, I found that the latest update of vue-loader (v15), requires a slight change to the webpack.config.js file.

From the vue-loader website (https://vue-loader.vuejs.org/migrating.html), you need to reference the vue-loader plugin in the webpack.config.js file, as below:

// webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  // ...
  plugins: [
    new VueLoaderPlugin()
  ]
}
Share:
10,777
kheya
Author by

kheya

Updated on June 22, 2022

Comments

  • kheya
    kheya almost 2 years

    I am very new in VueJS

    I have multi-page ASP.NET MVC app where I want to use VueJS (components, 2-way binding, validation, CRUD operations)

    Currently using jQuery for DOM manipulation, Ajax requests etc

    How should I approach this? I am getting way too much variations in thoughts from different posts (online)

    Could anyone please guide me and give me some pointers to get started?

    Some step by step doc will be great that shows how to do this with a hello world page (MVC View) with vuejs single file component and bundling

    The bundling seems complicated process. But I would love to use LESS in my code

    Thanks for reading