晚风江 2024-08-07 10:59 采纳率: 0%
浏览 3

vue2预渲染动态数据读取不成功

vue2使用了插件prerender-spa-plugin-next,预渲染基本没问题,但是不能读取到动态数据
vue.config.js

const { defineConfig } = require("@vue/cli-service");
const PrerenderSPAPlugin = require("prerender-spa-plugin-next");
const path = require("path");
const fs = require("fs");
const RouteResourcePreloadPlugin = require("@route-resource-preload/webpack-plugin");

const port = process.env.port || process.env.npm_config_port || 80; // 端口

module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    host: "0.0.0.0",
    port: port,
    open: true,
    proxy: {
      [process.env.VUE_APP_BASE_API]: {
        target: `http://localhost:8081`,
        changeOrigin: true,
        pathRewrite: {
          ["^" + process.env.VUE_APP_BASE_API]: "",
        },
      },
    },
  },

  configureWebpack: {
    plugins: [
      // 预渲染
      new PrerenderSPAPlugin({
        staticDir: path.join(__dirname, "dist"),
        routes: [
          '/',
          '/news-center',
          '/overseas-warehouse',
          '/north-america',
          '/about-us',
          ...JSON.parse(fs.readFileSync(path.resolve(__dirname, 'public/news-ids.json'), 'utf8')).map(id => `/news-center/news-details/${id}`)
        ],
        rendererOptions: {
          inject: {},
          headless: false,
          timeout: 5000,
          renderAfterTime: 10000,
          renderAfterDocumentEvent: "render-event",
          pretty: true,
          devtools: true,
        },
        postProcess: function (context) {
          const titles = {
            "/": "Home",
            "/news-center": "News Center",
            "/north-america": "North America",
            "/about-us": "About Us",
            "/overseas-warehouse": "Overseas Warehouse",
          };
          if (context.route.startsWith('/news-center/news-details/')) {
            const id = context.route.split('/').pop();
            titles[context.route] = `News Details - ${id}`;
          }
          context.html = context.html.replace(
            /<title>[^<]*<\/title>/i,
            "<title>" + (titles[context.route] || "Document") + "</title>"
          );
        },
      }),

      // 预加载
      new RouteResourcePreloadPlugin({
        modulePreloadMap: {
          "/HomeLoad": ["src/components/Home"],
          "/AmericaLoad": ["src/components/NorthAmerica"],
          "/WarehouseLoad": ["src/components/OverseasWarehouse"],
          "/AboutLoad": ["src/components/AboutUs"],
          "/CenterLoad": ["src/components/NewsCenter"],
          "/DetailsLoad": ["src/components/NewsDetails"], // 修改为正确的路径
        },
        mfPreloadMap: {},
        assetPreloadMap: {},
      }),
    ],
  },
});


vue组件是

<template>
  <div id="contentBox">
    <div id="navbarOther">
      <Navbar class="navbarOther-navbar" />
    </div>
    <div id="back">
      <div>
        <el-button
          type="primary"
          class="back-button"
          @click="goBack"
          icon="el-icon-arrow-left"
          >返回列表</el-button
        >
      </div>
    </div>
    <div id="content">
      <div id="newsHead">
        <h1 class="title">{{ content.title }}</h1>
        <p class="date">{{ content.date }}</p>
      </div>
      <div v-html="content.content" class="content-div"></div>
    </div>

    <Foot />
  </div>
</template>

<script>
import Navbar from "@/components/Navbar.vue";
import Foot from "@/components/Foot.vue";
import { getNewsInfo } from "../api/news";

var _hmt = _hmt || [];
(function () {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?66b6397027a120b4b7a90787267949b4";
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(hm, s);
})();
export default {
  components: {
    Navbar,
    Foot,
  },
  props: ["id"],
  data() {
    return {
      news: {
        title: "",
      },
      newsId: this.id,
      content: {},
      windowWidth: 0,
      windowHeight: 860,
    };
  },
  async mounted() {
    // 初始滚动位置
    window.scrollTo(0, 0);

    // 设置窗口尺寸
    this.getWindowWidth();

    try {
      // 获取数据并确保 DOM 更新
      await this.getNews(); // 获取新闻数据
      await this.$nextTick(); // 等待 DOM 更新

      // 在 DOM 完全准备好后触发 render-event
      document.dispatchEvent(new Event("render-event"));
    } catch (error) {
      // 捕获并打印任何错误
      console.error("Error during mounted lifecycle:", error);
    }
  },

  methods: {
    getWindowWidth() {
      this.windowWidth = window.innerWidth; // 获取窗口宽度
      this.windowHeight =
        window.innerWidth / 2 - 80 > 860 ? 860 : window.innerWidth / 2 - 80;
    },
    async getNews() {
      try {
        const response = await getNewsInfo(this.id);
        if (response && response.data && response.data.data) {
          this.content = response.data.data;
          console.log("this.content",this.content)
        } else {
          console.warn("Unexpected response structure:", response);
          // 设置合理的默认值
          this.content = {
            title: "Default Title1",
            date: "N/A1",
            content: "<p>No content available1.</p>",
          };
        }
      } catch (error) {
        console.error("Error fetching news:", error);
        // 设置合理的默认值
        this.content = {
          title: "Default Title",
          date: "N/A",
          content: "<p>No content available2.</p>",
        };
      }
    },

最后预渲染显示的是 这些内容,但是动态数据是读取的到的

// 设置合理的默认值
          this.content = {
            title: "Default Title1",
            date: "N/A1",
            content: "<p>No content available1.</p>",
          };
  • 写回答

1条回答 默认 最新

  • 一直免费一直爽 2024-08-11 20:37
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    在Vue项目中,当尝试获取动态数据时遇到问题,可能是由于一些特定的配置问题或者JavaScript环境设置不当导致的。为了更好地解决这个问题,建议遵循以下步骤:

    1. 检查prerender-spa-plugin-next插件是否正确安装和配置

    首先确认已经正确安装了prerender-spa-plugin-next插件,并且将其添加到了项目的配置文件(如vue.config.js)中。

    const prerenderPlugin = require('prerender-spa-plugin-next');
    module.exports = {
      // ...
      plugins: [
        prerenderPlugin({
          // 其他配置...
        }),
      ],
    };
    

    检查配置文件中的插件设置是否与实际需求一致。

    2. 确保JavaScript运行环境支持动态属性

    对于Vue2项目,确保Node.js版本足够高,至少需要大于等于12.x。此外,检查浏览器的JavaScript引擎是否支持动态属性(例如:ES6+),因为动态属性功能是在这些环境中实现的。

    3. 检查前端渲染逻辑

    在你的Vue组件内,确保<template>标签中的数据结构能够适配动态渲染的需求。例如,使用模板语法动态插入HTML元素或使用生命周期钩子处理DOM变化。

    <!-- 示例:将标题和日期动态插入 -->
    <div id="newsHead">
      <h1>{{ content.title }}</h1>
      <p class="date">{{ content.date }}</p>
    </div>
    
    <!-- 示例:更新DOM时调用方法处理数据 -->
    mounted() {
      this.$nextTick(() => {
        this.renderContent();
      });
    }
    
    methods: {
      renderContent() {
        const newsElement = document.getElementById("content");
        newsElement.innerHTML = `
          <div id="newsContent">
            <!-- 内容根据实际情况动态插入 -->
          </div>
        `;
      },
    }
    

    4. 检查动态数据来源

    确保从动态获取的数据格式与预期的展示方式相匹配。比如,如果使用了API请求获取数据,确保接口响应符合预期的结构。

    5. 测试兼容性问题

    测试不同浏览器和设备上可能出现的问题。特别是对于跨域资源的访问,确保所有必要的权限都被允许。

    通过以上步骤逐步排查问题,希望能找到并解决问题。如果你遇到了其他具体的技术难题,欢迎随时提问!

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 8月7日

悬赏问题

  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp
  • ¥15 自己做的代码上传图片时,报错
  • ¥15 Lingo线性规划模型怎么搭建
  • ¥15 关于#python#的问题,请各位专家解答!区间型正向化
  • ¥15 unity从3D升级到urp管线,打包ab包后,材质全部变紫色
  • ¥50 comsol温度场仿真无法模拟微米级激光光斑
  • ¥15 上传图片时提交的存储类型
  • ¥15 VB.NET如何绘制倾斜的椭圆