单页Web应用(single page web application,SPA)
就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
对比传统应用
单页面应用程序:
只有第一次会加载页面, 以后的每次请求, 仅仅是获取必要的数据.然后, 由页面中js解析获取的数据, 展示在页面中,对单页应用来说模块化的开发和设计显得相当重要。
传统多页面应用程序:
对于传统的多页面应用程序来说, 每次请求服务器返回的都是一个完整的页面。
优势
·速度:更好的用户体验,让用户在web app感受native app的速度和流畅。
·MVVM:经典MVVM开发模式,前后端各负其责。
·ajax:重前端,业务逻辑全部在本地操作,数据都需要通过AJAX同步、提交。
·路由:在URL中采用#号(HTML中的锚点)来作为当前视图的地址,改变#号后的参数,页面并不会重载。
实现
1.主要依托于Ajax和锚点技术的使用。
2.监听锚点值变化的事件,根据不同的锚点值,请求相应的数据。
3.原本用作页面内部进行跳转,定位并展示相应的内容。
Vue的路由
通过vue的路由可实现多视图的单页Web应用(基于html的SPA)。
1.引入必要库
<script src="js/vue.js"></script> <script src="js/vue-router.min.js"></script>
2.创建自定义组件(extend是构造一个组件的语法器. 你给它参数,他给你一个组件),也可以通过component注册组件。
const Home = Vue.extend({ template: '<div><h2>{{index}}</h2><div>这里是首页内容</div></div>', //模板 data(){ return {index:'首页'} } }); const About = Vue.extend({ template: '<div><h2>{{about}}</h2><div>这里是关于内容</div></div>', //模板 data(){ return {about:'关于'}; } }); const Role = Vue.extend({ template: '<div><h2>{{role}}</h2><div>这里是角色内容</div></div>', //模板 data(){ return {role:'角色'}; } });
3.定义路由(即线路)。
const routes = [{ path: '/home', component: Home }, { path: '/about', component: About }, { path: '/role', component: Role }];
4.定义Vue的路由器。
const router = new VueRouter({ routes: routes });
5.创建Vue实例并且挂载路由。
//创建Vue实例并且挂载路由 var vm = new Vue({ // el:'#app',//改用方法挂载模式 router:router,//指定路由器 data: { ts: new Date().getTime(), index: '这里是首页', about: '这里是关于页面', role: '这里是角色页面', }, methods: { go(){ this.$router.go(1);//获取当前路由器并且前进一个路由 }, back(){ this.$router.go(-1);//获取当前路由器并且后退一个路由 }, change(v){ this.$router.push({//获取当前路由并且切换到指定的组件 path: v }); } } }).$mount("#app");//挂载区域
6.在HTML中使用router-link和router-view使用路由。
<!-- 使用RouterLink组件导航. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <!-- 通过传入 `to` 属性指定链接. --> <router-link to="/home">go to Home</router-link> <!-- 使用RouterView组件显示. --> <router-view></router-view>
router-link相关属性
-
to :表示目标路由的链接
- replace :设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。
- append :设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b。
- tag:设置router-link标签渲染为何种标签形式。
- 例:
<p>按钮方式:<router-link to="/home" tag="button" replace>Home</router-link></p> <p>li标签:<router-link to="/about" tag="li" >about</router-link></p> <p>默认a标签:<router-link to="/role" tag="a">role</router-link></p>
- active-class :渲染组件时指定组件的class的样式。
- event :声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。
最后附上所有源码。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Vue的路由</title> <!-- 核心库 --> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" type="text/javascript" charset="utf-8"></script> <!-- 路由器库 --> <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/2.6.0/vue-router.js"></script> </head> <body> <div id="app"> <h1>{{ts}}</h1> <!-- 使用RouterLink组件导航. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <!-- 通过传入 `to` 属性指定链接. --> <p>按钮方式:<router-link to="/home" tag="button" replace>Home</router-link></p> <p>li标签:<router-link to="/about" tag="li" >about</router-link></p> <p>默认a标签:<router-link to="/role" tag="a">role</router-link></p> <!-- 使用RouterView组件显示指定视图. --> <p><router-view></router-view></p> <!-- 指定前进 和 后退的组件、切换的组件 --> <div> <button @click="go" type="button">前进</button> <button @click="back" type="button">后退</button> <button @click="change('/role')" type="button">切换指定组件</button> </div> </div> </body> <script type="text/javascript"> /* SPA(single page application )单页面应用技术,只加载单个HTML页面,动态更新页面的内容的Web程序。 实现思路及技术点: 1.ajax异步请求。 2.锚点使用。(window.loaction.hash #) */ //1.创建自定义组件 const Home = Vue.extend({ template: '<div><h2>{{index}}</h2><div>这里是首页内容</div></div>', //模板 data(){ return {index:'首页'} } }); const About = Vue.extend({ template: '<div><h2>{{about}}</h2><div>这里是关于内容</div></div>', //模板 data(){ return {about:'关于'}; } }); const Role = Vue.extend({ template: '<div><h2>{{role}}</h2><div>这里是角色内容</div></div>', //模板 data(){ return {role:'角色'}; } }); //2.定义路由(及路线) const routes = [{ path:'/',//根路径,默认显示 component:Home },{ path: '/home', component: Home }, { path: '/about', component: About }, { path: '/role', component: Role }]; //3.定义路由器 const router = new VueRouter({ routes: routes }); //创建Vue实例并且挂载路由 var vm = new Vue({ // el:'#app',//改用方法挂载模式 router:router,//指定路由器 data: { ts: new Date().getTime(), index: '这里是首页', about: '这里是关于页面', role: '这里是角色页面', }, methods: { go(){ this.$router.go(1);//获取当前路由器并且前进一个路由 }, back(){ this.$router.go(-1);//获取当前路由器并且后退一个路由 }, change(v){ this.$router.push({//获取当前路由并且切换到指定的组件 path: v }); } } }).$mount("#app");//挂载区域 /** * var、const、let三个声明变量的关键字有何区别? */ //1.const定义的变量不可以修改,而且必须初始化。 /* const x;//编译报错,常量值丢失Missing initializer in const declaration // x = 20;//编译报错,常量不可赋值Assignment to constant variable. const y = 10;//定义并初始化,正确 //y = 30;//编译报错,常量不可赋值 console.log(y);//打印->10 */ //2.var定义的变量可以修改,如果不初始化会输出undefined,不会报错。 /* var x;//声明变量 console.log(x);//可以打印undefined,不会报错 console.log(y);//var变量会提升优先级,打印->20 var y = 20; function test(){ y = 10;//不指定关键字默认全局变量,方法外可以访问 console.log(y);//可以打印->10 } test();//执行方法 console.log(y);//打印->10 */ //3.let定义的变量是块级作用域,函数内部使用let定义后,对函数外部无影响(编译报错后面部分不执行)。 let c = 3; console.log('函数外let定义c:' + c);//输出c=3 { let s = 20; var x = 30; } if(true){ var y = 40; let q = 50; } let arr = [1,2,3,4]; for (let i = 0; i <arr.length; i++) { var sum = arr[i]; let sums = arr[i]; } console.log(sum);//打印->4//可以访问var变量 // console.log(sums);//编译报错sums is not defined console.log(y);//打印->40,说明var声明的变量外部可以访问 // console.log(q);//编译报错 is not defined console.log(x);//打印->30 // console.log(s);//编译报错s is not defined var sa = 120; function change(){ sa = 130; c = 6; console.log('函数内let定义c:' + c);//输出c=6 } change(); console.log('函数调用后let定义c不受函数内部定义影响:' + c);//输出c=3 console.log(sa); </script> </html>