├── .gitignore ├── ClientApp ├── boot.ts ├── components │ ├── app │ │ ├── app.ts │ │ └── app.vue │ ├── apps │ │ ├── app2.vue │ │ ├── app3.ts │ │ ├── app3.vue │ │ ├── app4.ts │ │ ├── app4.vue │ │ ├── example5.vue │ │ ├── login.vue │ │ ├── loginrequest.ts │ │ ├── pageauth.vue │ │ ├── protected.vue │ │ ├── slot-comp.vue │ │ ├── slot-main.vue │ │ ├── todo-editor.vue │ │ ├── todo-item.ts │ │ ├── todo-item.vue │ │ └── vuex.vue │ ├── counter │ │ ├── counter.ts │ │ └── counter.vue │ ├── fetchdata │ │ ├── fetchdata.ts │ │ └── fetchdata.vue │ ├── home │ │ └── home.vue │ └── navmenu │ │ ├── navmenu.css │ │ └── navmenu.vue ├── css │ └── site.css └── store │ ├── index.ts │ └── mutation-types.ts ├── Controllers ├── HomeController.cs └── SampleDataController.cs ├── Program.cs ├── README.adoc ├── Startup.cs ├── Views ├── Home │ └── Index.cshtml ├── Shared │ ├── Error.cshtml │ └── _Layout.cshtml ├── _ViewImports.cshtml └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json ├── karma.conf.js ├── netcore.csproj ├── package.json ├── test ├── index.js └── unit │ ├── TestApp3.spec.ts │ └── TestMe.spec.ts ├── tsconfig.json ├── vue-shims.d.ts ├── webpack.config.js ├── webpack.config.vendor.js ├── wwwroot └── favicon.ico └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /Properties/launchSettings.json 2 | 3 | ## Ignore Visual Studio temporary files, build results, and 4 | ## files generated by popular Visual Studio add-ons. 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | coverage/ 13 | .vscode 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease/ 21 | [Rr]eleases/ 22 | x64/ 23 | x86/ 24 | build/ 25 | bld/ 26 | bin/ 27 | Bin/ 28 | obj/ 29 | Obj/ 30 | 31 | # Visual Studio 2015 cache/options directory 32 | .vs/ 33 | /wwwroot/dist/ 34 | 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # DNX 50 | artifacts/ 51 | 52 | *_i.c 53 | *_p.c 54 | *_i.h 55 | *.ilk 56 | *.meta 57 | *.obj 58 | *.pch 59 | *.pdb 60 | *.pgc 61 | *.pgd 62 | *.rsp 63 | *.sbr 64 | *.tlb 65 | *.tli 66 | *.tlh 67 | *.tmp 68 | *.tmp_proj 69 | *.log 70 | *.vspscc 71 | *.vssscc 72 | .builds 73 | *.pidb 74 | *.svclog 75 | *.scc 76 | 77 | # Chutzpah Test files 78 | _Chutzpah* 79 | 80 | # Visual C++ cache files 81 | ipch/ 82 | *.aps 83 | *.ncb 84 | *.opendb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | *.sap 94 | 95 | # TFS 2012 Local Workspace 96 | $tf/ 97 | 98 | # Guidance Automation Toolkit 99 | *.gpState 100 | 101 | # ReSharper is a .NET coding add-in 102 | _ReSharper*/ 103 | *.[Rr]e[Ss]harper 104 | *.DotSettings.user 105 | 106 | # JustCode is a .NET coding add-in 107 | .JustCode 108 | 109 | # TeamCity is a build add-in 110 | _TeamCity* 111 | 112 | # DotCover is a Code Coverage Tool 113 | *.dotCover 114 | 115 | # NCrunch 116 | _NCrunch_* 117 | .*crunch*.local.xml 118 | nCrunchTemp_* 119 | 120 | # MightyMoose 121 | *.mm.* 122 | AutoTest.Net/ 123 | 124 | # Web workbench (sass) 125 | .sass-cache/ 126 | 127 | # Installshield output folder 128 | [Ee]xpress/ 129 | 130 | # DocProject is a documentation generator add-in 131 | DocProject/buildhelp/ 132 | DocProject/Help/*.HxT 133 | DocProject/Help/*.HxC 134 | DocProject/Help/*.hhc 135 | DocProject/Help/*.hhk 136 | DocProject/Help/*.hhp 137 | DocProject/Help/Html2 138 | DocProject/Help/html 139 | 140 | # Click-Once directory 141 | publish/ 142 | 143 | # Publish Web Output 144 | *.[Pp]ublish.xml 145 | *.azurePubxml 146 | # TODO: Comment the next line if you want to checkin your web deploy settings 147 | # but database connection strings (with potential passwords) will be unencrypted 148 | *.pubxml 149 | *.publishproj 150 | 151 | # NuGet Packages 152 | *.nupkg 153 | # The packages folder can be ignored because of Package Restore 154 | **/packages/* 155 | # except build/, which is used as an MSBuild target. 156 | !**/packages/build/ 157 | # Uncomment if necessary however generally it will be regenerated when needed 158 | #!**/packages/repositories.config 159 | 160 | # Microsoft Azure Build Output 161 | csx/ 162 | *.build.csdef 163 | 164 | # Microsoft Azure Emulator 165 | ecf/ 166 | rcf/ 167 | 168 | # Microsoft Azure ApplicationInsights config file 169 | ApplicationInsights.config 170 | 171 | # Windows Store app package directory 172 | AppPackages/ 173 | BundleArtifacts/ 174 | 175 | # Visual Studio cache files 176 | # files ending in .cache can be ignored 177 | *.[Cc]ache 178 | # but keep track of directories ending in .cache 179 | !*.[Cc]ache/ 180 | 181 | # Others 182 | ClientBin/ 183 | ~$* 184 | *~ 185 | *.dbmdl 186 | *.dbproj.schemaview 187 | *.pfx 188 | *.publishsettings 189 | orleans.codegen.cs 190 | 191 | /node_modules 192 | 193 | # RIA/Silverlight projects 194 | Generated_Code/ 195 | 196 | # Backup & report files from converting an old project file 197 | # to a newer Visual Studio version. Backup files are not needed, 198 | # because we have git ;-) 199 | _UpgradeReport_Files/ 200 | Backup*/ 201 | UpgradeLog*.XML 202 | UpgradeLog*.htm 203 | 204 | # SQL Server files 205 | *.mdf 206 | *.ldf 207 | 208 | # Business Intelligence projects 209 | *.rdl.data 210 | *.bim.layout 211 | *.bim_*.settings 212 | 213 | # Microsoft Fakes 214 | FakesAssemblies/ 215 | 216 | # GhostDoc plugin setting file 217 | *.GhostDoc.xml 218 | 219 | # Node.js Tools for Visual Studio 220 | .ntvs_analysis.dat 221 | 222 | # Visual Studio 6 build log 223 | *.plg 224 | 225 | # Visual Studio 6 workspace options file 226 | *.opt 227 | 228 | # Visual Studio LightSwitch build output 229 | **/*.HTMLClient/GeneratedArtifacts 230 | **/*.DesktopClient/GeneratedArtifacts 231 | **/*.DesktopClient/ModelManifest.xml 232 | **/*.Server/GeneratedArtifacts 233 | **/*.Server/ModelManifest.xml 234 | _Pvt_Extensions 235 | 236 | # Paket dependency manager 237 | .paket/paket.exe 238 | 239 | # FAKE - F# Make 240 | .fake/ 241 | -------------------------------------------------------------------------------- /ClientApp/boot.ts: -------------------------------------------------------------------------------- 1 | import './css/site.css'; 2 | import 'bootstrap'; 3 | import Vue from 'vue'; 4 | import VueRouter from 'vue-router'; 5 | import store from './store' 6 | Vue.use(VueRouter); 7 | const routes = [ 8 | { path: '/', component: require('./components/home/home.vue') }, 9 | { path: '/counter', component: require('./components/counter/counter.vue') }, 10 | { path: '/fetchdata', component: require('./components/fetchdata/fetchdata.vue') }, 11 | { path: '/app2', component: require('./components/apps/app2.vue') }, 12 | { path: '/app3', component: require('./components/apps/app3.vue'), 13 | props: { 14 | 'simple': true, 15 | 'headerText': `this is a trival example of using Vuex for centralized state storage. However, in this case, the state isn't 16 | shared - so we could have done the same thing with a data function.` 17 | } }, 18 | { path: '/app4', component: require('./components/apps/app4.vue') }, 19 | { path: '/slots', component: () => import(/* webpackChunkName: "comps" */ './components/apps/slot-main.vue') }, 20 | { path: '/example5', component: () => import(/* webpackChunkName: "comps" */ './components/apps/example5.vue')}, 21 | { path: '/Vuex', component: require("./components/apps/vuex.vue") }, 22 | { path: "/login", component: require("./components/apps/login.vue")}, 23 | { path: "/pageauth", component: require("./components/apps/pageauth.vue")}, 24 | { path: "/protected", component: require("./components/apps/protected.vue")}, 25 | { path: "/route-meta", component: require("./components/apps/protected.vue"), meta: {requiresAuth: true}} 26 | ]; 27 | let router = new VueRouter({ mode: 'history', routes: routes }) 28 | new Vue({ 29 | el: '#app-root', 30 | store: store, 31 | router: router, 32 | render: h => h(require('./components/app/app.vue')) 33 | }); 34 | 35 | router.beforeEach((to, from, next) => { 36 | if (to.matched.some(r => r.meta.requiresAuth)) { 37 | if (!store.getters.isLoggedIn) { 38 | next({ 39 | path: "/login", 40 | query: { 41 | from: to.fullPath 42 | } 43 | }); 44 | } else { 45 | next() 46 | } 47 | } else { 48 | next() 49 | } 50 | }); -------------------------------------------------------------------------------- /ClientApp/components/app/app.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { Component } from 'vue-property-decorator'; 3 | 4 | @Component({ 5 | components: { 6 | MenuComponent: require('../navmenu/navmenu.vue') 7 | } 8 | }) 9 | export default class AppComponent extends Vue { 10 | } 11 | -------------------------------------------------------------------------------- /ClientApp/components/app/app.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ClientApp/components/apps/app2.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 21 | -------------------------------------------------------------------------------- /ClientApp/components/apps/app3.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | interface todo { 3 | text: string, 4 | } 5 | export default Vue.component("app3", { 6 | props: ["simple", "headerText"], 7 | computed: { 8 | todos: function(this: Vue) { return this.$store.getters.todos }, 9 | hasActive: function(this:Vue) { return this.$store.getters.hasActive} 10 | }, 11 | methods: { 12 | setActive(this:Vue, todo:todo) { 13 | console.log("in edit", todo) 14 | this.$store.commit('setActive', todo); 15 | } 16 | } 17 | 18 | }); -------------------------------------------------------------------------------- /ClientApp/components/apps/app3.vue: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /ClientApp/components/apps/login.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | -------------------------------------------------------------------------------- /ClientApp/components/apps/loginrequest.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | export default interface LoginRequest { 3 | username:string 4 | password:string 5 | } 6 | 7 | var LoginMixin = { 8 | created(this:Vue) { 9 | console.log("LoginMixin.created() called") 10 | if (!this.$store.getters.isLoggedIn) { 11 | this.$router.replace ({path:"/login", query: {"from": this.$route.fullPath}}) 12 | } 13 | }, 14 | beforeUpdate(this:Vue) { 15 | console.log("LoginMixin.beforeUpdate() called") 16 | if (!this.$store.getters.isLoggedIn) { 17 | this.$router.replace ({path:"/login", query: {"from": this.$route.fullPath}}) 18 | } 19 | }, 20 | computed : { 21 | t(this:Vue):string{ 22 | return this.$route.query.t 23 | } 24 | } 25 | }; 26 | export {LoginMixin}; -------------------------------------------------------------------------------- /ClientApp/components/apps/pageauth.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ClientApp/components/apps/protected.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | -------------------------------------------------------------------------------- /ClientApp/components/apps/slot-comp.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /ClientApp/components/apps/slot-main.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /ClientApp/components/apps/todo-editor.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /ClientApp/components/apps/todo-item.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { Component, Prop } from 'vue-property-decorator'; 3 | 4 | @Component 5 | export default class TodoItem extends Vue{ 6 | @Prop() 7 | todo:any; 8 | 9 | @Prop() 10 | active:any; 11 | 12 | setActive(e:any) { 13 | this.$emit("update:active", this.todo) 14 | } 15 | get isActive() { 16 | return this.active && this.todo.id == this.active.id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ClientApp/components/apps/todo-item.vue: -------------------------------------------------------------------------------- 1 | 2 | c 8 | -------------------------------------------------------------------------------- /ClientApp/components/counter/counter.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { Component } from 'vue-property-decorator'; 3 | 4 | @Component 5 | export default class CounterComponent extends Vue { 6 | currentcount: number = 0; 7 | 8 | incrementCounter() { 9 | this.currentcount++; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ClientApp/components/counter/counter.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ClientApp/components/fetchdata/fetchdata.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { Component } from 'vue-property-decorator'; 3 | 4 | interface WeatherForecast { 5 | dateFormatted: string; 6 | temperatureC: number; 7 | temperatureF: number; 8 | summary: string; 9 | } 10 | 11 | @Component 12 | export default class FetchDataComponent extends Vue { 13 | forecasts: WeatherForecast[] = []; 14 | 15 | mounted() { 16 | fetch('api/SampleData/WeatherForecasts') 17 | .then(response => response.json() as Promise) 18 | .then(data => { 19 | this.forecasts = data; 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ClientApp/components/fetchdata/fetchdata.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ClientApp/components/home/home.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ClientApp/components/navmenu/navmenu.css: -------------------------------------------------------------------------------- 1 | .main-nav li .glyphicon { 2 | margin-right: 10px; 3 | } 4 | 5 | /* Highlighting rules for nav menu items */ 6 | .main-nav li a.router-link-active, 7 | .main-nav li a.router-link-active:hover, 8 | .main-nav li a.router-link-active:focus { 9 | background-color: #4189C7; 10 | color: white; 11 | } 12 | 13 | /* Keep the nav menu independent of scrolling and on top of other items */ 14 | .main-nav { 15 | position: fixed; 16 | top: 0; 17 | left: 0; 18 | right: 0; 19 | z-index: 1; 20 | } 21 | 22 | @media (min-width: 768px) { 23 | /* On small screens, convert the nav menu to a vertical sidebar */ 24 | .main-nav { 25 | height: 100%; 26 | width: calc(25% - 20px); 27 | } 28 | .main-nav .navbar { 29 | border-radius: 0px; 30 | border-width: 0px; 31 | height: 100%; 32 | } 33 | .main-nav .navbar-header { 34 | float: none; 35 | } 36 | .main-nav .navbar-collapse { 37 | border-top: 1px solid #444; 38 | padding: 0px; 39 | } 40 | .main-nav .navbar ul { 41 | float: none; 42 | } 43 | .main-nav .navbar li { 44 | float: none; 45 | font-size: 15px; 46 | margin: 6px; 47 | } 48 | .main-nav .navbar li a { 49 | padding: 10px 16px; 50 | border-radius: 4px; 51 | } 52 | .main-nav .navbar a { 53 | /* If a menu item's text is too long, truncate it */ 54 | width: 100%; 55 | white-space: nowrap; 56 | overflow: hidden; 57 | text-overflow: ellipsis; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ClientApp/components/navmenu/navmenu.vue: -------------------------------------------------------------------------------- 1 | 76 | 77 |