基于html5的通用webim组件的前端设计与实现-基于c#房屋租赁管理系统的设计和实现
这种方式的优缺点非常明显:
缺点:前端代码和服务端代码过度集成,开发协同非常混乱。 服务器压力大,因为构建html的工作都放在了服务器上;
后来... 随着ajax的流行,可以在不刷新浏览器的情况下进行异步数据请求。
然后……更高级的体验随之而来——单页应用。
在单页应用中,不仅页面内的交互不刷新页面,就连页面跳转也不刷新页面。
单页应用的特点:
支持单页应用特性的是前端路由。
2.前端路由特性
前端路由有什么需求?
也就是可以在改变url的前提下保证页面不刷新。
3.面试! ! !
Hash路由和History路由有什么区别?
四、哈希原理及实现 1、特点
hash的出现满足了这一要求,它具有以下特点:
hash值的变化不会导致页面刷新;
location.hash = "#aaa"; location.hash = "#bbb"; // 从 #aaa 到 #bbb,页面是不会刷新的
location.hash = "#aaa"; location.hash = "#bbb"; window.addEventLisenter("hashchange", () => {});
2.如何更改哈希
我们还有两种方式来控制hash的变化:
location.hash = "#aaa"; location.hash = "#bbb";
点击跳转到 user location.hash = "#user";
3. 手动实现一个基于散列的路由
Document
.container { width: 100%; height: 60px; display: flex; justify-content: space-around; align-items: center; font-size: 18px; font-weight: bold; background: black; color: white; } a:link, a:hover, a:active, a:visited { text-decoration: none; color: white; }
/* 期望看到的效果:点击三个不同的 a 标签,页面的背景颜色会随之变化 */ class BaseRouter { constructor() { this.routes = {}; // 存储 path 以及 callback 的对应关系 this.refresh = this.refresh.bind(this); // 如果不 bind 的话,refresh 方法中的 this 指向 window // 处理页面 hash 变化,可能存在问题:页面首次进来可能是 index.html,并不会触发 hashchange 方法 window.addEventListener("hashchange", this.refresh); // 处理页面首次加载 window.addEventListener("load", this.refresh); } /** * route * @param {*} path 路由路径 * @param {*} callback 回调函数 */ route(path, callback) { console.log("========= route 方法 ========== ", path); // 向 this.routes 存储 path 以及 callback 的对应关系 this.routes[path] = callback || function () {}; } refresh() { // 刷新页面 const path = `/${location.hash.slice(1) || ""}`; console.log("========= refresh 方法 ========== ", path); this.routes[path](); } } const body = document.querySelector("body"); function changeBgColor(color) { body.style.backgroundColor = color; } const Router = new BaseRouter(); Router.route("/", () => changeBgColor("white")); Router.route("/green", () => changeBgColor("green")); Router.route("/gray", () => changeBgColor("gray"));
五、History原理与实现
hash有#符号,不美观,服务器接收不到hash路径和参数。
历史的车轮无情地碾过hash基于html5的通用webim组件的前端设计与实现,HTML5时代推出了History API。
一、HTML5 History常用API
window.history.back(); // 后退 window.history.forward(); // 前进 window.history.go(-3); // 接收 number 参数,后退 N 个页面 window.history.pushState(null, null, path); window.history.replaceState(null, null, path);
最重要的两个API是pushState和replaceState,这两个API都可以在不刷新页面的情况下操作浏览器历史记录。
不同的是pushState会增加历史,replaceState会直接替换当前的历史。
2. pushState/replaceState的参数
它们的参数是一样的,三个参数分别是:
三、历史的特点
History API 具有以下特点:
4.面试! ! !
我们可以使用popstate来监听url的变化;
popstate什么时候触发:
5.手动实现一个基于历史的路由
.container { width: 100%; height: 60px; display: flex; justify-content: space-around; align-items: center; font-size: 18px; font-weight: bold; background: black; color: white; } a:link, a:hover, a:active, a:visited { text-decoration: none; color: white; }
class BaseRouter { constructor() { this.routes = {}; // location.href; => hash 的方式 console.log("location.pathname ======== ", location.pathname); // http://127.0.0.1:8080/green ==> /green this.init(location.pathname); this._bindPopState(); } init(path) { // pushState/replaceState 不会触发页面的渲染,需要我们手动触发 window.history.replaceState({ path }, null, path); const cb = this.routes[path]; if (cb) { cb(); } } route(path, callback) { this.routes[path] = callback || function () {}; } // ! 跳转并执行对应的 callback go(path) { // pushState/replaceState 不会触发页面的渲染,需要我们手动触发 window.history.pushState({ path }, null, path); const cb = this.routes[path]; if (cb) { cb(); } } // ! 演示一下 popstate 事件触发后,会发生什么 _bindPopState() { window.addEventListener("popstate", e => { /* 触发条件: 1、点击浏览器前进按钮 2、点击浏览器后退按钮 3、js 调用 forward 方法 4、js 调用 back 方法 5、js 调用 go 方法 */ console.log("popstate 触发了"); const path = e.state && e.state.path; console.log("path >>> ", path); this.routes[path] && this.routes[path](); }); } } const Router = new BaseRouter(); const body = document.querySelector("body"); const container = document.querySelector(".container"); function changeBgColor(color) { body.style.backgroundColor = color; } Router.route("/", () => changeBgColor("white")); Router.route("/gray", () => changeBgColor("gray")); Router.route("/green", () => changeBgColor("green")); container.addEventListener("click", e => { if (e.target.tagName === "A") { e.preventDefault(); console.log(e.target.getAttribute("href")); // /gray /green 等等 Router.go(e.target.getAttribute("href")); } });
六、Vue-Router1、路由器使用
使用 Vue.js基于html5的通用webim组件的前端设计与实现,我们已经可以通过组合组件来组合应用程序。 当你想要添加 Vue Router 时,我们需要做的是将组件映射到路由,并告诉 Vue Router 在哪里渲染它们。
例如:
// 如果使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter) // 1、定义(路由)组件 // 可以从其他文件 import 进来 const Foo = { template: "foo" }; const Bar = { template: "bar" }; // 2、定义路由 //每个路由应该映射一个组件,其中 component 可以是通过 Vue.extend() 创建的组件构造器,或者只是一个组件配置对象 const routes = [ { path: "/foo", component: Foo }, { path: "/bar", component: Bar }, ]; // 3、创建 router 实例,然后传 routes 配置 const router = new VueRouter({ routes, }); // 4、创建和挂载根实例 // 记得要通过 router 配置参数注入路由,从而让整个应用都有路由功能 const app = new Vue({ router, }).$mount("#app");
2、动态路由匹配
我们经常需要将所有匹配某种模式的路由映射到同一个组件,比如用户信息组件,不同的用户使用同一个组件。
您可以传递 $route.params.id 或参数。
const router = new VueRouter({ routes: [ // 动态路径参数,以冒号开头 { path: "/user/:id", component: User }, ], }); const User = { template: "User: {{ $route.params.id }}", };
3、响应路由参数的变化
复用组件时,如果想响应路由参数的变化,可以使用watch或者beforeRouteUpdate:
例如:
const User = { template: "...", watch: { $route(to, from) { // 对路由变化作出响应... }, }, }; const User = { template: "...", beforeRouteUpdate(to, from, next) { // 对路由变化作出响应... // don"t forget to call next() }, };
4.捕获所有路由或404 Not found路由
使用通配符路由时,请保证路由的顺序正确,即包含通配符的路由应该在末尾。
例如:
5.导航卫士
vue-router提供的导航守卫,主要是用来守卫跳转或者取消的导航。 有多种方法可以将路由嵌入到导航过程中:
6. 完成单条航线独有的组件级导航分析过程
例如:
// 全局 const router = new VueRouter({ mode: "history", base: process.env.BASE_URL, routes, }); // 全局的导航守卫 router.beforeEach((to, from, next) => { console.log(`Router.beforeEach => from=${from.path}, to=${to.path}`); // 可以设置页面的 title document.title = to.meta.title || "默认标题"; // 执行下一个路由导航 next(); }); router.afterEach((to, from) => { console.log(`Router.afterEach => from=${from.path}, to=${to.path}`); }); // 路由独享 const router = new VueRouter({ routes: [ { path: "/foo", component: Foo, beforeEnter: (to, from, next) => { // 配置数组里针对单个路由的导航守卫 console.log(`TestComponent route config beforeEnter => from=${from.path}, to=${to.path}`); next(); }, }, ], }); // 组件 const Foo = { template: `...`, beforeRouteEnter(to, from, next) { // 在渲染该组件的对应路由被 comfirm 前调用 // 不!能!获取组件实例 this,因为当守卫执行前,组件实例还没被调用 }, beforeRouteUpdate(to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举个例子来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候 // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用 // 可以访问组件实例 this }, beforeRouteLeave(to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 this }, };
接下来必须调用:
7.Navigation guard执行顺序(面试!!!)【配置文件】,下一个beforeEnter【组件】内部声明的beforeRouteEnter【全局】router.afterEach8,滚动行为(面试!!!)
vue-router中,如何记住上一页滚动条的位置? ? ?
使用前端路由,当切换到新的路由时,希望页面滚动到顶部,或者保持原来的滚动位置,就像重新加载页面一样。
Vue-router 可以做到,而且更好的是,它允许你自定义路由切换时页面如何滚动。
【注意】:该功能仅在支持history.pushState的浏览器中可用。
scrollBehavior 生效的条件:
window.history.back(); // 后退 window.history.forward(); // 前进 window.history.go(-3); // 接收 number 参数,后退 N 个页面
例如:
// 1. 记住:手动点击浏览器返回或者前进按钮,记住滚动条的位置,基于 history API 的,其中包括:go、back、forward、手动点击浏览器返回或者前进按钮 // 2. 没记住:router-link,并没有记住滚动条的位置 const router = new VueRouter({ mode: "history", base: process.env.BASE_URL, routes, scrollBehavior: (to, from, savedPosition) => { console.log(savedPosition); // 已保存的位置信息 return savedPosition; }, });
9.路由懒加载
在包中构建应用程序时,JavaScript 包可能会变得非常大,从而影响页面加载。 如果我们能把不同路由对应的组件分成不同的代码块,然后在路由访问时加载相应的组件,效率会更高。
例如:
const Foo = () => import(/* webpackChunkName: "foo" */ "./Foo.vue"); const router = new VueRouter({ routes: [{ path: "/foo", component: Foo }], });
Vue.js前端路由和异步组件的介绍到此结束。 更多关于Vue.js异步组件的内容请搜索云海天教程往期文章或继续浏览以下相关文章。 希望大家以后多多学习支持云海天教程!