Nuxtjs 文档未定义

Nuxtjs document is not defined

我正在尝试在 nuxtjs 中创建评论页面,我正在使用 vue-star-rating 库来实现此目的,但即使我尝试了一些似乎适用于许多人的解决方案,我仍面临此错误。这是我的脚本:

<template>
  <!--MAIN-->
  <main>
    <!--REVIEW ADDRESS-->
    <div class="reviewPage mt-3">
      <div class="container-fluid c-section">
        <div class="row">
          <div class="col-sm-2"></div>
          <div class="col-sm-8">
            <div class="a-spacing-top-medium">
              <h1 class="a-spacing-base">
                <b>Create Review</b>
              </h1>
              <div class="row">
                <!-- Product Photo -->
                <div class="col-md-2 col-sm-3 col-3">
                  <img :src="product.image" style="width: 80px" />
                </div>
                <!-- Product Title -->
                <div class="col-md-10 col-sm-9 col-9 m-auto">
                  <h4>
                    <b>{{ product.title }}</b>
                  </h4>
                </div>
              </div>
              <div class="a-spacing-top-medium"></div>
              <hr />
              <h2 class="a-spacing-base">Overall Rating</h2>
              <div class="a-row">
                <!-- Rating -->
                <!-- Get rid of document is not defined error -->
                <client-only>
                  <star-rating v-model="rating"></star-rating>
                </client-only>
              </div>
              <div class="a-row a-spacing-top-large">
                <h2>Add photo or video</h2>
                <p style="font-size: 14px; font-weight: 700;">
                  Shoppers find images and videos more helpful than text alone.
                </p>
              </div>
              <div class="a-row a-spacing-top-medium">
                <!-- Choose a Photo -->
                <label class="choosefile-button">
                  <i class="fal fa-plus"></i>
                  <input
                    type="file"
                    ref="file"
                    v-on:change="handleImageUpload"
                  />
                </label>
                <p>{{ imageName }}</p>
              </div>
              <div class="a-spacing-top-large"></div>
              <hr />
              <!-- Headline -->
              <div class="headline a-spacing-large">
                <h2 class="a-spacing-base">Add a headline</h2>
                <input
                  type="text"
                  class="a-input-text"
                  style="width: 70%;"
                  placeholder="What's most important to know?"
                  v-model="headline"
                />
              </div>
              <!-- Body -->
              <div class="a-spacing-base">
                <h2 class="a-spacing-base">Write your review</h2>
                <textarea
                  placeholder="What do you like or dislike? What did you see this product for?"
                  style="height:6em; width: 100%;"
                  v-model="body"
                ></textarea>
              </div>
            </div>
            <br />
            <br />
            <hr />
            <div class="a-spacing-top-medium">
              <p style="font-size: 14px; font-weight: 700;">
                This is how you'll appear to other customers:
              </p>
              <div class="media a-spacing-top-large">
                <div class="media-left">
                  <img
                    src="/img/avatar.png"
                    class="img-fluid"
                    style="width: 50px;"
                  />
                </div>
                <div class="media-body pl-3 pt-2">
                  <input
                    type="text"
                    class="a-input-text"
                    style="width: 100%;"
                    :value="$auth.$state.user.name"
                  />
                </div>
              </div>
            </div>
            <div class="a-row a-spacing-top-medium">
              <span class="a-color-tertiary"
                >Don't worry, you can always change this on your profile</span
              >
            </div>
            <div class="a-row text-right a-spacing-top-large">
              <span class="a-button-register">
                <span class="a-button-inner">
                  <span class="a-button-text" v-on:click="submitForm"
                    >Submit</span
                  >
                </span>
              </span>
            </div>
          </div>
          <div class="col-sm-2"></div>
        </div>
        <div class="a-spacing-large pb-5"></div>
        <hr />
      </div>
    </div>
    <!--/REVIEW ADDRESS-->
  </main>
  <!--/MAIN-->
</template>

<script>
import StarRating from "vue-star-rating";
export default {
  components: {
    StarRating
  },
  async asyncData({ $axios, params }) {
    try {
      const response = await $axios.$get(`/api/products/${params.id}`);
      console.log(response);
      return { product: response.product };
    } catch (error) {
      console.log(error);
    }
  },
  data() {
    return {
      headline: "",
      body: "",
      rating: 0,
      image: "",
      imageName: "",
      product: "",
      user: ""
    };
  },
  methods: {
    handleImageUpload(e) {
      this.image = this.$refs.file.files[0];
      console.log(this.image);
      this.imageName = e.target.files[0].name;
    },
    async submitForm() {
      try {
        // Initialize the form data
        let formData = new FormData();
        // Add the form data we need to submit
        formData.append("headline", this.headline);
        formData.append("body", this.body);
        formData.append("image", this.image, this.imageName);
        formData.append("rating", this.rating);
        formData.append("product", this.product);
        formData.append("user", this.user);
        //   Make the request to the POST http://localhost:8080/api/reviews/product/:id URL
        await this.$axios.$post(
          `/api/reviews/product/${this.$route.params.id}`,
          formData
        );
        // Redirect to home page
        this.$router.push(`/products/${this.$route.params.id}`);
      } catch (error) {
        console.log(error);
      }
    }
  }
};
</script>

我安装了这个 vue-star-rating 库,正如你所看到的,我将它作为 StarRating 导入,并且在模板中我按照建议用 'client-only' 标签包装它,之前我使用 no-ssr 但是它也不起作用,因为有人说最新的 nuxt 版本建议只使用客户端。 所以我什至尝试用这个内容在插件中创建文件夹

import Vue from 'vue'
import StarRating from 'vue-star-rating'
Vue.use(StarRating)

而且我还按照建议将此行添加到 nuxt.config.js

{ src: '~/plugins/vue-star-rating.js', mode: 'client' }

但错误仍然存​​在

这是我的 review.js 脚本:

const router = require('express').Router()
const Review = require('../models/review')
const Product = require('../models/product')
const verifyToken = require('../middlewares/verify-token')
const upload = require('../middlewares/upload-photo')

router.post('/reviews/:productID', [verifyToken, upload.single('photo')], async(req, res) => {
    try{
        const review = new Review()

        review.headline = req.body.headline
        review.body = req.body.body
        review.rating = req.body.rating
        review.photo = req.file.location
        review.productID = req.params.productID
        review.user = req.decoded._id

        await Product.update({ $push: review._id })

        const savedReview = await review.save()

        if(savedReview) {
            res.json({
                success: true,
                message: 'Succesfully added review'
            })
        }
    } catch(err) {
        res.status(500).json({
            success: true,
            message: err.message
        })
    }
})

router.get('/reviews/:productID,', async(req, res) => {
    try{
        const productReviews = await Review.find({
            productID: req.params.productID
        }).populate('user').exec()

        res.json({
            success: true,
            reviews: productReviews
        })
    } catch(err) {
        res.status(500).json({
            success: false,
            message: err.message
        })
    }
})
module.exports = router

A在这里写了一个,但是缺少一些部分,所以我觉得我也可以在这里回答。

您的库可能处于与 vue2-editor 相同的状态,这意味着您只需要在客户端 加载和导入 它。为此,您可以使用类似这样的东西

export default {
  components: {
    [process.browser && 'star-rating']: () => import('vue-star-rating'),
  }
}