【问题标题】:NuxtJS/VueJS: How to know if page was rendered on client-side only?NuxtJS/VueJS:如何知道页面是否仅在客户端呈现?
【发布时间】:2020-05-12 08:43:40
【问题描述】:

目前我为通用 nuxtjs/vuejs 应用程序创建了一个 html5 视频播放器组件。 视频标签有一个自动播放属性,可以在导航到视频后开始播放视频。 通常浏览器不会在页面加载后直接这样做,这是被禁止的。 我需要在我的组件中使用一个变量来了解自动播放是否可以根据此信息设置元素样式。 换句话说:如果当前页面仅在客户端呈现,则该变量应为 true,但如果首先在服务器端呈现,则该变量为 false。

无法使用“window.history.length”,因为刷新后也无法自动播放,尽管这不会影响历史长度。

此外,不能在“created”方法中设置变量,因为它也会在服务器端和客户端调用。

【问题讨论】:

  • 也许我们应该在继续之前看到一个代码框最小示例?
  • 一个例子真的很简单。它只是一个带有视频标签和自动播放属性的默认 nuxtjs 项目。 codesandbox.io/s/great-frog-ue5j8?file=/pages/index.vue 如果你用firefox加载页面,你会在控制台得到这个错误:“NotAllowedError: the play method is not allowed by the user agent or the platform in the current context,可能是因为用户拒绝了权限。”目标是有一个变量来知道它是否可能,这样我就可以应用初始样式。
  • 让我稍后检查
  • 添加了对上述错误的解释——火狐需要用户“选择播放”才能播放。防止垃圾网站自动播放视频
  • 是的,很明显。对不起,但答案是没有用的。如果您知道如何在当前路由的初始渲染时获取媒体是否可播放的信息,请发表评论。

标签: vue.js vuejs2 nuxt.js


【解决方案1】:

在 nuxt - 有一个 <client-only> 组件,它只在客户端呈现组件

<template>
  <div>
    <sidebar />
    <client-only placeholder="Loading...">
      <!-- this component will only be rendered on client-side -->
      <comments />
    </client-only>
  </div>
</template>

nuxt中有asyncData,运行beforeCreate(),即可以在组件挂载前从asyncData的服务器端获取数据。

或者,您可以查看created() 的进程,例如

created() {
  if (process.client) {
    // handle client side
  }
}


编辑

https://stackoverflow.com/a/53058870/2312051

Audio.play() 返回一个 Promise,当播放成功开始时该 Promise 被解析。由于任何原因(例如权限问题)未能开始播放,都会导致 Promise 被拒绝。

const playedPromise = video.play();
if (playedPromise) {
  playedPromise.catch((e) => {
    if (e.name === 'NotAllowedError' ||
        e.name === 'NotSupportedError') {
        //console.log(e.name);
    }
  });
}

在您的情况下,您的浏览器/操作系统似乎不允许自动播放音频。用户代理(浏览器)或操作系统不允许在当前上下文或情况下播放媒体。例如,如果浏览器要求用户通过单击“播放”按钮明确地开始媒体播放,这可能会发生。 Here 是参考。

【讨论】:

  • 是的,你是对的,我没有想到 asyncData。应该可以在组件数据中设置 process.client 的值。所以我可以使用该状态进行初始渲染。问题是我在组件级别并且没有 asyncData 方法。我想防止将值从页面组件级联到视频组件。
  • 参考您的编辑:不可能等待承诺。我需要之前的信息。我可以这样得到它:“如果当前页面仅在客户端呈现,则该变量应该为真,但如果它首先在服务器端呈现,则该变量为假。”
【解决方案2】:

一种可能的解决方案是获取 Vue 路由器条目的长度。如果没有手动跟踪,目前这似乎是不可能的。所以我在布局组件中以这段代码结束:

watch: {
  $route () {
    Vue.prototype.$navigated = true
  }
}

$navigated 的值是 undefined 或 true,因此我在布局子组件中知道是否可以自动播放视频。

【讨论】:

  • 很好的解决方案,谢谢。羞于需要将其复制粘贴到我的所有布局(这是网站其余部分的潜在登录页面)。我对音频元素和自动播放有同样的问题!
猜你喜欢
  • 2020-12-11
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 2021-08-22
  • 1970-01-01
  • 2010-11-17
相关资源
最近更新 更多