简体   繁体   中英

Vue + Nuxt.js - How to cache a whole page with components?

I have a Vue + nuxt.js app which renders a couple of pages with Highcharts. The charts are created by a dynamic component that takes as a parameter a web service URL. How can I cache such pages for approximately 1 day?

I have found the two links, but these only refer to component caching, not the whole page. The component cache would cache the component based on a 'name' and would hinder to cache dynamically which takes a parameter? Therefore this approach doesn't look right for me.

Any suggestions on how I can cache my pages?

An example page where I call the dynamic component with the URL parameter:

<template>
   <keep-alive>
    <chart :url="this.$axios.defaults.baseURL + 'api/analytics/age'" keep-alive/>
  </keep-alive>
</template>

<script>
    import chart from '~/components/analytics/chart'

    export default {
        components: {
          chart,
        },      
    }
</script>

An example of the dynamic component, this takes the parameter and then does a web service call to get the data for rendering the chart.

<template>
  <highcharts v-if="isChartDataLoaded" :options="chartOptions"></highcharts>
</template>
<script>
    import axios from 'axios';
    import {Chart} from 'highcharts-vue'
    import Highcharts3D from 'highcharts/highcharts-3d'
    import Highcharts from 'highcharts'

    if (typeof Highcharts === 'object') {
        Highcharts3D(Highcharts);
    }

    export default {
        name: 'chart',
        props: ['url'],
        serverCacheKey: props => props.url,
        components: {
            highcharts: Chart
        },
        data() {
            return {
                isChartDataLoaded: false,
                chartOptions: {
                    title: {
                        text: ''
                    },
                    tooltip: {
                        pointFormat: '{point.percentage:.2f}%',
                    },
                    chart: {
                        type: 'pie',
                        options3d: {
                            enabled: true,
                            alpha: 50,
                        },
                    },
                    series: [{
                        name: '',
                        data: [1],
                        tooltip: {
                            valueDecimals: 0
                        },
                        animation: false

                    }],
                    plotOptions: {
                        pie: {
                            allowPointSelect: true,
                            cursor: 'pointer',
                            innerSize: '30%',
                            depth: 100,
                            dataLabels: {
                                enabled: true,
                                percentageDecimals: 2,
                                color: '#002a52',
                                connectorColor: '#002a52',
                                formatter: function () {
                                    return '<b>' + this.point.name + '</b>: ' + this.percentage.toFixed(2) + ' %';
                                }
                            }
                        }
                    },

                    credits: {
                        enabled: false
                    },
                    exporting: {
                        buttons: {
                            printButton: {
                                enabled: false
                            },
                            contextButton: {
                                enabled: false
                            }
                        }
                    },
                }
            };
        },
        mounted() {
            axios.post(this.url, {
                locale: this.$route.query.locale ? this.$route.query.locale : this.$i18n.locale
            }).then(response => {
                this.chartOptions.series[0].data = response.data;
                this.isChartDataLoaded = true
            }).catch(e => {
                console.log(e)
            })
        },
    }
</script>

My response is late but I hope it helps other people searching for an answer. If you want to cache a whole page, you can use nuxt-ssr-cacge . Then in your nuxt.config.js:

 module.exports = { // If you provide a version, it will be stored inside cache. // Later when you deploy a new version, old cache will be // automatically purged. version: pkg.version, //.... modules: [ 'nuxt-ssr-cache', ], cache: { // if you're serving multiple host names (with differing // results) from the same server, set this option to true. // (cache keys will be prefixed by your host name) // if your server is behind a reverse-proxy, please use // express or whatever else that uses 'X-Forwarded-Host' // header field to provide req.hostname (actual host name) useHostPrefix: false, pages: [ // these are prefixes of pages that need to be cached // if you want to cache all pages, just include '/' '/page1', '/page2', // you can also pass a regular expression to test a path /^\/page3\/\d+$/, // to cache only root route, use a regular expression /^\/$/ ], key(route, context) { // custom function to return cache key, when used previous // properties (useHostPrefix, pages) are ignored. return // falsy value to bypass the cache }, store: { type: 'memory', // maximum number of pages to store in memory // if limit is reached, least recently used page // is removed. max: 100, // number of seconds to store this page in cache ttl: 86400, //Actually One day }, }, //... };
I hope it helps!

here is new solution for cache the whole page

even you can cache consistent api like menu if you need

https://www.npmjs.com/package/nuxt-perfect-cache

npm i nuxt-perfect-cache

// nuxt.config.js

modules: [
    [
        'nuxt-perfect-cache',
        {
          disable: false,
          appendHost: true,
          ignoreConnectionErrors:false, //it's better to be true in production
          prefix: 'r-',
          url: 'redis://127.0.0.1:6379',
          getCacheData(route, context) {          
            if (route !== '/') {
              return false
            }
            return { key: 'my-home-page', expire: 60 * 60 }//1hour
          }
        }
      ]
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM