ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue前端路由及异步组件

2021-05-16 11:33:22  阅读:128  来源: 互联网

标签:异步 Vue hash cb location routes path 路由 history


hash 和 history的区别

  1. hash 有#,history 没有,Hash式基于锚点,History 模式 基于H5的History API
  2. hash 的#部分内容不会传给服务端, history 的所有内容都会给服务端,应用在部署的时候需要注意html的访问,因为无论访问什么/a,/b,/c之类的路径,其实都要访问那个html文件
  3. hash 通过 hashchange 监听变化,history 通过 popstate 监听变化

Hash

  1. url中带有一个#,它只是浏览器/客户端的状态,不会传递给服务器,服务器拿到的都是#前面的

  2. hash值的改变不会导致页面的刷新

    location.hash = '#aaa';
    location.hash = '#bbb';
    
  3. hash值的更改可以在浏览器访问历史中添加一条记录,所以可以通过浏览器的返回前进来控制hash的切换

  4. hash值的更改会触发hashchange事件

History

window.history.pushState();// 页面的浏览记录里添加一个历史记录
window.history.replaceState(); // 替换当前历史记录
window.history.go(-1)

pushState的参数

  1. state, 是一个对象,是一个与指定网址相关的对象,当 popstate 事件触发的时候,该对象会传入回调函数
  2. title, 新页面的标题,浏览器支持不一,可以传入null
  3. url, 页面的新地址

​ 当点击浏览器的前进和后退按钮,或者调用history的back和forward方法的时候,会触发popstate事件,可以记录改变后的地址并渲染。(要注意的是,当调用pushState,或者replaceState时,并不会触发该事件)

部署时如何配置nginx

假设访问www.lubai.com/main/

  • 假设index.html 存在服务器本地(index.html文件与nginx在同一个服务器)(vue官方的写法):就可以通过try file的形式,假设访问main这个路径的话
location /main/ { // 如果是根路由可以直接 /
  try_files $uri $uri/ /home/dist/index.html 
}

​ 这样无论访问 /main/a 或 /main/b 就都会访问那个 index.html

  • 假设html文件 存在于远程地址,oss或cdn,地址为www.lubai-cdn.com/file/index.html
location /main/ { // 路径的匹配规则
  rewrite ^ /file/index.html // ^指的是全部,全部重写成这个路径
  proxy_pass https://www.lubai-cdn.com,// 通过代理的形式
}

手写一个hash-router

<div class="container">
  <a href="#gray">灰色</a>
  <a href="#green">绿色</a>
  <a href="#">白色</a>
  <button onclick="window.history.go(-1)">返回</button>
</div>

​ 希望能达到下面的效果,点击三个不同的a标签,页面的背景色会随之改变。使用 new BaseRouter 的形式创建并使用

const Router = new BaseRouter();

Router.route('/', function () {
  changeBgColor('white');
});
Router.route('/green', function () {
  changeBgColor('green');
});
Router.route('/gray', function () {
  changeBgColor('gray');
});
// ---
const body = document.querySelector('body');

function changeBgColor(color) {
  body.style.backgroundColor = color;
}

​ 实现BaseRouter

class BaseRouter {
  constructor() {
    this.routes = {}; // 存储path以及callback的对应关系
    this.refresh = this.refresh.bind(this);
    window.addEventListener('load', this.refresh); // 处理页面首次加载
    window.addEventListener('hashchange', this.refresh); // 处理页面hash的变化
  }

  route(path, callback) {
    // 向this.routes存储path以及callback的对应关系
    this.routes[path] = callback || function () { };
  }

  refresh() {
    // 刷新页面
    const path = `/${location.hash.slice(1) || ''}`;
    console.log(location.hash);
    this.routes[path]();
  }
}

手写一个history-router

​ 改路径

<div class="container">
  <a href="/gray">灰色</a>
  <a href="/green">绿色</a>
  <a href="/">白色</a>
  <button onclick="window.history.go(-1)">返回</button>
</div>

​ 此外我们不希望a标签它执行,这个相当于执行了location.href = '/a',就出问题了,我们先阻止默认行为

const container = document.querySelector('.container');

container.addEventListener('click', e => {
  if (e.target.tagName === 'A') {
    e.preventDefault();
    Router.go(e.target.getAttribute('href'));
  }
});

​ 实现BaseRouter

class BaseRouter {
  constructor() {
    this.routes = {};
    // location.hash; hash的方式
    this.init(location.pathname);
    this._bindPopState();
  }

  init(path) {
    window.history.replaceState({
      path
    }, null, path);
    const cb = this.routes[path];
    // cb && cb();
    if (cb) {
      cb();
    }
  }

  route(path, callback) {
    this.routes[path] = callback || function () { };
  }

  go(path) {
    // 跳转并执行对应的callback
    window.history.pushState({
      path
    }, null, path);
    const cb = this.routes[path]; // 这里pushState无法被popState监听
    // cb && cb();
    if (cb) {
      cb();
    }
  }

  _bindPopState() {
    // 演示一下popstate事件触发后,会发生什么
    window.addEventListener('popstate', (e) => {
      const path = e.state && e.state.path;
      console.log(`in popstate listener path=${path}`);
      this.routes[path] && this.routes[path]();
    })
  }
}

标签:异步,Vue,hash,cb,location,routes,path,路由,history
来源: https://www.cnblogs.com/hyhwy/p/14773423.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有