1

我正在通过 Quasar 使用 Vue,页面通过 SSR 呈现。这工作得很好,但我有一个似乎行为不正常的组件。

问题是内容在服务器端正确呈现(通过检查 Chrome 中的网络日志来验证),使用 axios 调用将数据加载到元素中v-html,但是当我们进入浏览器时,状态似乎被重置并且在检查器中使用“元素”选项卡时,服务器端呈现的内容会丢失。

有任何想法吗?

Vue组件如下:

<template>
  <div class="dy-svg" v-html="svgData"></div>
</template>

<script>
/**
 * This provides a way of loading an SVG and embedding it straight into
 * the page, so that it can have css applied to it. Note, since we are
 * using XHR to load the SVG, any non-local resource will have to deal
 * with CORS.
 */
import axios from 'axios';

export default {
  props: {
    src: String,
    prefetch: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      svgData: undefined,
    };
  },
  async serverPrefetch() {
    if (this.prefetch) {
      await this.loadImage();
    }
  },
  async mounted() {
    // if (!this.svgData) {
    //   await this.loadImage();
    // }
  },
  methods: {
    async loadImage() {
      try {
        let url = this.src;

        if (url && url.startsWith('/')) {
          url = this.$appConfig.baseUrl + url;
        }

        const response = await axios.get(url);
        let data = response.data;

        const idx = data.indexOf('<svg');
        if (idx > -1) {
          data = data.substring(idx, data.length);
        }
        this.svgData = data;
      } catch (error) {
        console.error(error);
      }
    }
  }
};
</script>

注意,我确实尝试将v-once属性添加到 div,但似乎没有影响。

环境:

  • 类星体 1.1.0
  • @quasar/cli 1.0.0
  • @quasar/app 1.0.6
  • NodeJS 10.15.3
  • Vue 2.6.10(通过 Quasar 的依赖)
4

1 回答 1

0

获取的数据需要存在于视图组件之外,位于专用数据存储或“状态容器”中。在服务器上,您应该在渲染时预取数据并将其填充到存储中。为此,您可以使用Vuex.

示例Vuex商店文件:

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
// import example from './module-example'

Vue.use(Vuex)

export default function ( /* { ssrContext } */ ) {
  const Store = new Vuex.Store({
    state: () => ({
      entities: {}
    }),
    actions: {
      async get({
        commit
      }) {
        await axios.get('https://example.com/api/items')
          .then((res) => {
            if (res.status === 200) {
              commit('set', res.data.data)
            }
          })
      }
    },

    mutations: {
      set(state, entities) {
        state.entities = entities
      },
    },

    modules: {},

    // enable strict mode (adds overhead!)
    // for dev mode only
    strict: process.env.DEV
  })

  return Store
}

示例 Vue 页面脚本:

export default {
  name: 'PageIndex',

  computed: {
    // display the item from store state.
    entities: {
      get() {
        return this.$store.state.entities
      }
    }
  },

  serverPrefetch() {
    return this.fetchItem()
  },

  mounted() {
    if (!this.entities) {
      this.fetchItem()
    }
  },

  methods: {
    fetchItem() {
      return this.$store.dispatch('get')
    }

  }
}

这应该可以解决您面临的问题。

于 2019-09-11T18:59:16.123 回答