Vue.js历史记录后退按钮但保留过滤器值

时间:2016-10-06 04:05:22

标签: filtering vue.js history back

我已经交了一个使用Vue.js的项目(我是Vue的总菜鸟)

我有一个页面,根据过滤器列出项目。用户设置过滤器和列表页面更新。然后,用户点击其中一个列表,并进入具有后退按钮的详细信息页面,该页面应该将用户带回到已过滤的列表页面(保留选定的过滤器),但这不起作用:(目前我只是在使用

但这会丢失所有过滤功能,只显示所有列表。在Vue.js中执行此操作的正确方法是什么?

Suppliers.html

<section class="suppliers">
<div class="filters">
    <div class="row">
        <div class="column">
            <form action="" v-on="reset: formResetHandler">
                <div v-component="filter-expand-btn" v-ref="filter-expand-btn"></div>
                <div class="filters-expandable {{ expandFilter }}" v-transition="expand">
                    <div class="two-buttons">
                        <input type="reset" value="Reset">
                        <button class="btn" v-pointer="applyFiltersHandler">Apply</button>
                    </div>
                    <div v-component="suppliers-filter" v-ref="suppliersFilter"></div>

                </div>
            </form>
        </div>
    </div>
</div>
<div class="listing-container listing-container--filters-{{expandFilter}}">
    <div class="row">
        <div class="column">
            <ol class="suppliers-list">
                <li v-repeat="suppliers | customFilter" class="suppliers-list-item">
                    <a href="#/suppliers/{{id}}">
                        <img data-src="{{ logo }}" alt="{{ title }}">
                    </a>
                </li>
            </ol>
            <p class="listing-container__no-results" v-show="!totalSuppliers">No Suppliers found</p>
        </div>
    </div>
</div>

suppliers.js

    var Vue = require('vue');
var template = require('../views/suppliers.html');
import Lazy from '../lib/lazy';

var Suppliers = Vue.component('suppliers', {
    template: template,
    data: function () {
        return {
            suppliers: FWPA.Storage.read('Suppliers'),
            expandFilter: '',
            totalSuppliers: 1
        };
    },
    ready: function () {
        this.Lazy = new Lazy();
        this.Lazy.revalidate();
    },
    watch: {
        totalSpecies: function () {
            Vue.nextTick(() => {
                if (this.Lazy) {
                    this.Lazy.revalidate();
                }
            });
        }
    },
    filters: {
        customFilter: function(suppliers) {
            var filteredSuppliers = this.$.suppliersFilter.customFilter(suppliers);
            this.totalSuppliers = Object.keys(filteredSuppliers).length;
            return filteredSuppliers;
        }
    },
    methods: {
        formResetHandler: function (e) {
            this.$.suppliersFilter.resetFilters();
            Vue.nextTick(() => {
                if (this.Lazy) {
                    this.Lazy.revalidate();
                }
            });
            this.expandFilter = '';
        },
        applyFiltersHandler: function(e){
            e.preventDefault();
            this.expandFilter = '';
            Vue.nextTick(() => {
                if (this.Lazy) {
                    this.Lazy.revalidate();
                }
            });
        }
    }
});

export {Suppliers};

供应商-filters.html

    <fieldset>
    <label for="input-supplies-to">Location Supplies</label>
    <select id="input-supplies-to" name="supplies-to" v-model="filterGroup.suppliesTo">
        <option value="">Select location</option>
        <option value="ACT">Australian Capital Territory</option>
        <option value="NSW Rural">New South Wales - Rural</option>
        <option value="NSW Urban">New South Wales - Urban</option>
        <option value="NT">Northern Territory</option>
        <option value="QLD Rural">Queensland - Rural</option>
        <option value="QLD Urban">Queensland - Urban</option>
        <option value="SA">South Australia</option>
        <option value="TAS">Tasmania</option>
        <option value="VIC Rural">Victoria - Rural</option>
        <option value="VIC Urban">Victoria - Urban</option>
        <option value="WA">Western Australia</option>
        <option value="Export">Export</option>
    </select>
</fieldset>
<fieldset>
    <label for="input-species">Species / Product</label>
    <select id="input-species" name="species" v-model="filterGroup.species">
        <option value="">Select Species</option>
        <option v-repeat="allSpecies" value="{{ id }}">{{ title }}</option>
    </select>
</fieldset>

供应商-filters.js

var Vue = require('vue');
var template = require('../views/suppliers-filter.html');

var SuppliersFilter = Vue.component('suppliers-filter', {
    template: template,
    data: function() {

        try {
            // Get all categories in Applications category
            var allApplications = FWPA.Storage.getAllByProp(FWPA.Storage.read('Categories'), 'title', ['Applications', 'applications'])[0];
            if (!allApplications) {
                throw('FWPA - Cannot find category with name "Applications"');
            }
        } catch (e) {
            console.warn(e);
        }

        return {
            allSpecies: FWPA.Storage.read('Species'),
            allApplications: allApplications,
            filterGroup: {
                suppliesTo: '',
                species: '',
                application: ''
            }
        };
    },
    methods: {
        resetFilters: function() {
            var tempGroup = {};
            for (var filterItem in this.filterGroup) {
                tempGroup[filterItem] = '';
            }
            this.filterGroup = tempGroup;
        },
        /**
         * Loops over all filterable properties and applies a filter for each
         * @param suppliers
         * @returns Array
         */
        customFilter: function(suppliers) {
            var filteredSuppliers = suppliers;

            // Apply filter for all filterable properties
            for (var filterItem in this.filterGroup) {
                let filterVal = this.filterGroup[filterItem];
                // only apply if filter is set
                if(filterVal) {

                    // Map applications filter to "categories" property on suppler
                    if (filterItem === 'application') {
                        filterItem = 'categories';
                    }

                    // Expect integers for supplier.categories and supplier.species
                    if(filterItem === 'categories' || filterItem === 'species') {
                        filterVal = parseInt(filterVal);
                    }

                    filteredSuppliers = this.standardFilterTest(filterItem, filterVal, filteredSuppliers);
                }
            }
            return filteredSuppliers;
        },

        /**
         * Check for a filter against a single supplier
         * Checks in arrays on subject and a direct match
         * @param filterName
         * @param filterVal
         * @param suppliers
         * @returns {*}
         */
        standardFilterTest: function(filterName, filterVal, suppliers) {
            return suppliers.filter((singleSupplier) => {
                if (!singleSupplier.hasOwnProperty(filterName)) {
                    return false;
                }

                // Check for filter value in array OR do an exact match
                if( (Array.isArray(singleSupplier[filterName]) && singleSupplier[filterName].indexOf(filterVal) !== -1) || singleSupplier[filterName] == filterVal) {
                    return singleSupplier;
                } else {
                    return false;
                }
            });
        }
    }
});

export {SuppliersFilter};

supplier-detail.html(后退按钮位于顶部并带有注释)

<section class="supplier-detail">
    <div class="title-bar-strong">
        <a onclick="window.history.back();" class="topbar-back-button"><img src="img/back.png" /></a> <!-- THIS IS THE ISSUE --> 
        <h1>{{ title }}</h1>
    </div>
    <div class="row">
        <div class="column">
            <img class="supplier__logo" src="{{ logo }}" alt="{{ title }}">
            <h2 class="supplier__sub-title">{{subTitle}}</h2>
            <p class="supplier__description">{{description}}</p>
            <p v-show="websiteURL"><a href="{{ websiteURL }}">{{ websiteURL }}</a></p>
            <a v-show="brochureUrl" href="{{ brochureUrl }}" class="supplier__download-link btn-solid" download="{{brochureUrl}}" target="_blank" v-on="click: $parent.downloadHandler">Download Brochure</a>
        </div>
    </div>
    <div v-show="fullSpecies">
        <h4>Species</h4>
        <ul class="supplier__species-list">
            <li v-repeat="fullSpecies">
                <a href="#/species/{{id}}">
                    <img class="supplier__species-list__logo" src="{{ logo }}" alt="{{ title }}">
                    <span>{{ title }}</span>
                </a>
            </li>
        </ul>
    </div>
    <div v-show="contacts">
        <h4>Contacts</h4>
        <div class="contacts-list" v-repeat="contacts">
            <div class="row">
                <div class="column">
                    <h5>{{ title }}</h5>
                    <address>
                        {{ address }}
                    </address>
                    <a v-show="email" href="mailto:{{ email }}">E: {{ email }}</a><br/>
                    <a v-show="phone" href="tel:{{ phone }}">T: {{ phone }}</a><br/>
                    <a v-show="fax" href="{{ fax }}">F:{{ fax }}</a>
                </div>
            </div>
            <simple-map v-if="$parent.$parent.online" lat="{{ lat }}" lng="{{ lng }}" id="{{ $index }}" title="{{ title }}"></simple-map>
        </div>
    </div>
</section>

1 个答案:

答案 0 :(得分:1)

您好我认为您可以将keep-alive放入您的组件中: <component keep-alive></component>

通常会在keep-alive组件

中使用<router-view>