Flask MVVM 开发(vue.js) - ajax如何同步更新地址栏history 以及使用浏览器返回按钮


前端框架使用ajax请求数据,使得用户可以不刷新页面,就能得到新的数据。

但有些场景,ajax请求了几次后(比如,跳转不同 page),用户想使用浏览器返回按钮返回刚才浏览的某个 page,那怎么实现?


DEMO: https://tianya.herokuapp.com/articles/ty556242?page=1


效果:

Flask MVVM 开发(vue.js) - ajax如何同步更新地址栏history 以及使用浏览器返回按钮_第1张图片


1)HTML5 提供 history.pushState() and history.replaceState() methods, 允许你添加和修改 history entries. 


(以下例子请 git clone https://github.com/moling3650/mblog-Flask.git,感谢作者:moling3650

功能:

用户进入Manage页面时,history.replaceState来同步替换地址栏的地址(不增加新的history entity)

history.state 从 null -> Object {pg_his: "1"}

用户点击pagination页码时,会触发 ajax请求,这时我们加入 history.pushState来同步修改地址栏的地址(增加新的history entity)

history.state (add) Object {pg_his: "2"}



JS: manage.js

var vm = new Vue({
    el: '#vm',
    data: {
        table: location.pathname.split('/').pop(),
        items: [],
        page: null,
        models: {
            'users': {'name': '名字', 'email': '电子邮箱'},
            'blogs': {'name': '标题', 'user_name': '作者'},
            'comments': {'user_name': '作者', 'content':'内容'},
            'oauth': {'id': 'ID', 'user_id': '用户ID'},
            'logs': {'id': 'ID', 'ip': '用户IP'},
        },
    },
    computed:{
        fields: function () {
            return this.models[this.table];
        }
    },
    ready: function () {
        var pg = getUrlParams('page');
        pg = pg || 1
        history.replaceState({pg_his: pg}, "", this.table+"?page="+pg)  // 打开首页时,/blogs -> replace  /blogs?page=1
        this.getItemsByPage(pg, getUrlParams('size'));
    },
    methods: {
        getItemsByPage: function  (page, size) {
            var self = this;
            getJSON('/api/' + this.table, {
                page: page || '1',
                size: size || '10'
            }, function (err, data) {
                self.items = data.items;
                self.page = data.page;
            })
        },
        vaildPage: function(i) {
            return (i > 1) && (Math.abs(i - this.page.index) < 3);
        },
        gotoPage: function (page, back) {
            if (! back) {
            history.pushState({pg_his: page}, "", this.table+"?page="+page);  // /logs?page=3
            }
            return this.getItemsByPage(page, this.page.limit);
        }
    }
});


HTML: bootstrap-manage.html

<ul class="pagination">
    <li :class="{'active': page.index===1}">
        <a href="javascript:void(0)" v-on:click="gotoPage(1, false)" v-text="1">a>
    li>
    <li class="disabled" v-if="(page.index - 1) > 3"><span>...span>li>

    <li :class="{'active': page.index===i}" v-for="i in page.last | filterBy vaildPage">
        <a href="javascript:void(0)" v-on:click="gotoPage(i, false)" v-text="i">a>
    li>

    <li class="disabled" v-if="(page.last - page.index) > 3"><span>...span>li>
    <li :class="{'active': page.index===page.last}" v-if="page.last > 1">
        <a href="javascript:void(0)" v-on:click="gotoPage(page.last, false)" v-text='page.last'>a>
    li>
ul>


2)点击浏览器返回按钮,则响应事件:window.onpopstate event

为了跟 点击 pagination页码 区分,加入布尔值 (back)

JS:

window.onpopstate = function(event) {
    var state = event.state
    if (state===null) {
    return null;
    }
    var pg = state.pg_his
  console.log("location: " + document.location + ", state: " + JSON.stringify(state) +"length:"+window.history.length)

  vm.gotoPage(page=pg, back=true)
};



你可能感兴趣的:(Vue,Flask)