33

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

kheya
  • 7,546
  • 20
  • 77
  • 109
  • 1
    I understand single-file vue component but the bundling process seems over killing. Can I have some tool and point to the folder where I have *.vue components and compile all files. Then deploy the output files to right folder in my app? OR am I thinking old way here?? – kheya Mar 01 '17 at 20:28
  • Do you need the single file components? Vue is touted as a progressive framework; you don't have to use them. – Bert Mar 01 '17 at 20:36
  • I am all for simplicity. I want the simplest approach that is easy to understand and maintain. – kheya Mar 01 '17 at 20:57
  • When we were getting started, for components, all we did was create a single file that had the commonly used components, used string templates for those components, and included that script on the page. Then in the page, do a new Vue() and you're off to the races. Editing string templates can be a pain, but to get started it's no harder than that. – Bert Mar 01 '17 at 21:04
  • Bert, You haven't created .vue file for components and then use pre-compiler to generate the js\css files or just .js file for the component? Also how big was this project or app? – kheya Mar 01 '17 at 21:17
  • I've done it both ways. I have some .vue files that we now compile using webpack (though we did not use the style section, we just added styles to our theme) and I've used just a straight up javascript file or included script sections. .vue files are great, but you have to integrate the node build process with your msbuild process. – Bert Mar 01 '17 at 21:20
  • Will it be OK to post your answer with steps and sample for both approach? Hello world would suffice. Thanks – kheya Mar 01 '17 at 22:29

3 Answers3

78

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.

Bert
  • 80,741
  • 17
  • 199
  • 164
  • 1
    Really nice, thorough answer! – Peter Mar 02 '17 at 20:10
  • Awesome! I can't thank you enough. I will let you know how it goes. – kheya Mar 02 '17 at 21:12
  • I am not after a single page app. I need to hook vueJS as script on my page and take benefits of components, data binding, validation, reactivity, transition etc. – kheya Mar 02 '17 at 21:13
  • @kheya With the very basic approach you need not have a SPA. Just initialize a Vue where you want it on the page. You can use the last approach I describe to take advantage of .vue files if you want. – Bert Mar 02 '17 at 21:17
  • 2
    I would suggest taking a look at the Laravel (PHP) community. Laravel is the MVC of PHP which basically embraced Vue from the very start. They have a lots of guides and tutorials including setups for projects with and without webpack configurations. I would suggest starting really basic with the scripts only then when you get confortable to it, make a webpack configuration if you need it. – Cristi Jora Mar 03 '17 at 08:41
  • Is that good idea to have vuejs and mvc? is that not like anuglar? – Jeeva J Jul 14 '17 at 06:34
  • In the "Compile Individual Single File Components", at one point you refer to Vue from node_modules (webpack NPM) and from the wwwroot. Did I got it correct? – juanora Sep 05 '17 at 13:25
  • @juanora If I understand you correctly, you can add the Vue script to the page from anywhere. I typically wouldn't reference it from the npm modules because you don't really want to publish those. – Bert Sep 05 '17 at 21:44
  • Fantastic answer @Bert !. Thanks for the help :) – Terje Nygård Sep 24 '17 at 22:54
  • @Bert: when I run the command 'webpack', I receive the following error: throw new Error("'output.filename' is required, either in config file or as --output-filename"); – Saif Nov 06 '17 at 09:57
  • @SaifUllah Sounds like an issue with the webpack.config.js file. – Bert Nov 06 '17 at 19:27
  • I think I'm missing something obvious here, I created a SO [question](https://stackoverflow.com/questions/47134555/webpack-error-output-filename-is-required-in-my-asp-net-vue-app) do you see any issue with my webpack.config.js file. – Saif Nov 07 '17 at 05:30
  • Uhm, I still got an error: `The command "webpack" exited with code 1`. Can anyone help me? – 1_bug Mar 22 '18 at 07:47
  • Im trying the "Compile Individual Single File Components" its not creating new files. How do i troubleshoot where i got the webpack wrong @bret Can anyone help me with this? – barryDev Nov 05 '19 at 19:50
7

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.
1_bug
  • 5,505
  • 4
  • 50
  • 58
  • Simple code formatting doesn't working :( so I decided to put code sample into snippets. If anyone can help with formatting please let me know. – 1_bug Mar 22 '18 at 12:10
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()
  ]
}
Marek
  • 90
  • 1
  • 7