{"id":673,"date":"2019-05-31T12:10:20","date_gmt":"2019-05-31T16:10:20","guid":{"rendered":"http:\/\/salzlechner.com\/dev\/?p=673"},"modified":"2019-08-10T11:50:25","modified_gmt":"2019-08-10T15:50:25","slug":"vue-js-front-end-with-a-net-core-web-api-backend","status":"publish","type":"post","link":"http:\/\/salzlechner.com\/dev\/2019\/05\/31\/vue-js-front-end-with-a-net-core-web-api-backend\/","title":{"rendered":"Vue.js front end with a .Net core web api backend"},"content":{"rendered":"<p>Here is a quick walk through on creating a project that contains both a dot net core web api as well as a vue.js front end.<\/p>\n<p>To get started we enter the following command line<\/p>\n<pre class=\"lang:default decode:true \">dotnet new webapi -o vue_and_dotnet\n<\/pre>\n<p>this will create a simple net core web api project<\/p>\n<p>next we will use the vue cli to create the vue app<\/p>\n<pre class=\"lang:default decode:true \">vue create vue_and_dotnet\n<\/pre>\n<p>the vue cli will warn that the directory already exists. Choose the merge option.<\/p>\n<p>Then select the features you would like in your Vue application such as Vue Router , Vuex, Linter, Unit Testing, etc<\/p>\n<p>Once all features are selected the vue cli will create a simple vue app to get started.<\/p>\n<p>To support hot module reloading (HMR) we need to install the following two modules<\/p>\n<p>navivgate to the vie_and_dotnet folder and run the following command line<\/p>\n<pre class=\"lang:default decode:true\">npm install -D aspnet-webpack webpack-hot-middleware<\/pre>\n<p>next we need to configure Vue to stop using its HMR and to redirect its output to the wwwroot folder<\/p>\n<p>to do this we create the following vue.config.js file<\/p>\n<pre class=\"lang:default decode:true\">module.exports = {\n    outputDir: 'wwwroot',\n    baseUrl: \"\/\",\n    chainWebpack: config =&gt; {\n        \/\/ remove hmr plugin, we will use ASP.NET HMR\n        config.plugins.delete('hmr');\n    }\n}<\/pre>\n<p>next we need to modify startup.cs as follows<\/p>\n<pre class=\"lang:default decode:true \">using System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.HttpsPolicy;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Logging;\nusing Microsoft.Extensions.Options;\nusing Microsoft.AspNetCore.SpaServices.Webpack;\n\nnamespace vue_and_dotnet\n{\n    public class Startup\n    {\n        public Startup(IConfiguration configuration)\n        {\n            Configuration = configuration;\n        }\n\n        public IConfiguration Configuration { get; }\n\n        \/\/ This method gets called by the runtime. Use this method to add services to the container.\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);\n        }\n\n        \/\/ This method gets called by the runtime. Use this method to configure the HTTP request pipeline.\n        public void Configure(IApplicationBuilder app, IHostingEnvironment env)\n        {\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n\n                \/\/ Use HMR\n                app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions\n                {\n                    HotModuleReplacement = true,\n                    ConfigFile = Path.Combine(env.ContentRootPath, @\"node_modules\\@vue\\cli-service\\webpack.config.js\")\n                });\n            }\n            else\n            {\n                app.UseHsts();\n            }\n\n            app.UseHttpsRedirection();\n\n            app.UseStaticFiles();\n\n            app.UseMvc(routes =&gt;\n            {\n                routes.MapRoute(\n                    name: \"default\",\n                    template: \"{controller=Home}\/{action=Index}\/{id?}\");\n            });\n             \n            app.MapWhen(x =&gt; !x.Request.Path.Value.StartsWith(\"\/api\"), builder =&gt;\n            {\n                builder.UseMvc(routes =&gt;\n                {\n                    routes.MapSpaFallbackRoute(\n                        name: \"spa-fallback\",\n                        defaults: new { controller = \"Home\", action = \"Index\" });\n                });\n            });\n        }\n    }\n}\n<\/pre>\n<p>thats all there is.&nbsp; You can start debugging and after a little while the browser should start and show the vue js app.<\/p>\n<p>but now lets see if we can call the web api. In order to do that we will install axios first as follows<\/p>\n<pre class=\"lang:default decode:true \">npm install axios --save<\/pre>\n<p>now lets add a view called Values.vue with the following content<\/p>\n<pre class=\"lang:default decode:true \">&lt;template&gt;\n  &lt;div&gt;\n    {{ info }}\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script&gt;\n\/\/ @ is an alias to \/src\nimport axios from 'axios';\n\nexport default {\n  data () {\n    return {\n      info: null\n    }\n  },\n  mounted () {    \n    axios\n      .get('api\/values')\n      .then(response =&gt; (this.info = response))\n  }\n\n}\n&lt;\/script&gt;\n<\/pre>\n<p>then we will need to add a route as follows<\/p>\n<pre class=\"lang:default decode:true \"> {\n      path: '\/values',\n      name: 'values',\n      \/\/ route level code-splitting\n      \/\/ this generates a separate chunk (about.[hash].js) for this route\n      \/\/ which is lazy-loaded when the route is visited.\n      component: () =&gt; import(\/* webpackChunkName: \"about\" *\/ '.\/views\/Values.vue')\n    }<\/pre>\n<p>and lat but not least a router link<\/p>\n<pre class=\"lang:default decode:true\">&lt;router-link to=\"\/values\"&gt;Values&lt;\/router-link&gt;<\/pre>\n<p>when navigating to the values page it will call the web api endpoint and show the information on the page<\/p>\n\n\t\t<div class='author-shortcodes'>\n\t\t\t<div class='author-inner'>\n\t\t\t\t<div class='author-image'>\n\t\t\t<img src='http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2016\/02\/mike5crop-566174_60x60.jpg' alt='' \/>\n\t\t\t<div class='author-overlay'><\/div>\n\t\t<\/div> \n\t\t<div class='author-info'>\n\t\t\tMichael Salzlechner is the CEO of StarZen Technologies, Inc.<\/p>\n<p>He was part of the Windows Team at Data Access Worldwide that created the DataFlex for Windows Product before joining&nbsp;<a href=\"http:\/\/starzen.com\">StarZen Technologies<\/a>. StarZen Technologies provides consulting services as well as custom Application development and third party products<\/p>\n\t\t<\/div>\n\t\t\t<\/div>\n\t\t<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here is a quick walk through on creating a project that contains both a dot net core web api as well as a vue.js front end. To get started we enter the following command line dotnet new webapi -o vue_and_dotnet this will create a simple net core web api project next we will use the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":730,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","ngg_post_thumbnail":0,"footnotes":""},"categories":[42,7,37,38],"tags":[],"class_list":["post-673","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-c","category-javascript","category-vue-js"],"_links":{"self":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/673","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/comments?post=673"}],"version-history":[{"count":4,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/673\/revisions"}],"predecessor-version":[{"id":731,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/673\/revisions\/731"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/media\/730"}],"wp:attachment":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/media?parent=673"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/categories?post=673"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/tags?post=673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}