(Nuxt.js/Vue.js) - 脚本只运行一次,更改路由/刷新页面后停止运行

Posted

技术标签:

【中文标题】(Nuxt.js/Vue.js) - 脚本只运行一次,更改路由/刷新页面后停止运行【英文标题】:(Nuxt.js/Vue.js) - Script only works once, stops working after changing route/refreshing the page 【发布时间】:2019-08-16 09:51:21 【问题描述】:

我正在将我的项目网站“转移”到 Vue.js,顶部是 Nuxt.js。 我正在将存储在远程服务器中的所有文件的内容复制到本地“静态”文件夹。

一切正常,除了第一次加载页面时运行的 javascript,但是如果我通过路由切换到另一个页面,或者刷新当前页面,JavaScript 将停止工作。

例如,我的项目网站中有这个页面:http://archy-user.name/drag/

您基本上可以将图像拖到其他框,当您将鼠标悬停在带有图像的任何框上时,类会发生变化。

我将 CSS 复制到本地静态文件夹,工作正常,复制到 JavaScript,它只工作一次,在更改路由/刷新页面后停止工作......

它在您第一次加载页面时就像网站一样工作,但是在重新加载/更改路线后,脚本停止工作,并且在将鼠标悬停在框上时没有类更改等......尽管第一次工作正常页面已加载。

昨天在研究这个问题的时候,相关问题的回答说是因为页面加载时脚本只运行了一次,所以当路由改变或页面刷新时,脚本不会再次运行.

有人建议将页面加载时应该执行的函数添加到vue组件中“export default”内的“created()”方法中。

但是,就我而言,我并没有在每次加载页面时真正想要执行的内容,而是只想执行脚本的特定部分,这将是仅在以下情况下触发的特定功能某些操作是用户在页面中通过交互执行的...

没有必要每次都加载脚本,因为交互甚至可能不会发生,从而使脚本变得无用,加载时间也是如此。更不用说如果我将整个脚本添加到“created”方法中,组件会变得一团糟。

基本上我没有找到任何真正解决这个问题的方法,只有导致副作用的解决方法......

这是我的组件的结构(以下组件来自http://archy-user.name/drag):

<template>
<div class="container">
    <div class="box">
        <div class="fill" draggable="true"></div>
    </div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
</div>
</template>

<script>
export default 
    name: 'Drag',
    head: 
        link: [  rel: 'stylesheet', type: 'text/css', href: 'css/drag.css' ],
        script: [  src: 'js/drag.js'  ]
    

</script>

<style>

</style>

有解决此问题的提示吗?或者针对我的情况的解决方法?

PS - 每次我关闭选项卡并打开一个新选项卡时,脚本都会再次运行,直到页面刷新/路由更改

【问题讨论】:

在您的示例中一切正常 - 不确定您的情况如何?你想在组件之外使用你的脚本吗? 该脚本停止工作,就好像它在页面刷新后根本没有链接一样,或者当我转到主页并返回当前页面时,虽然它在页面第一次运行时工作加载到当前标签中 【参考方案1】:

你可以用 vue 组件风格重写你的代码。它会更清楚。并且易于重复使用

 <template>
  <div class="drag">
    <div
      v-for="n in range"
      :key="n"
      class="box"
      @dragenter="dragEnter"
      @dragover="dragOver"
      @dragleave="dragLeave"
      @drop="dragDrop"
    >
      <div
        v-if="n === 1"
        class="fill"
        draggable="true"
        @dragstart="dragStart"
        @dragend="dragEnd"
      />
    </div>
  </div>
</template>

<script>
export default 
  name: 'Drag',
  props: 
    range: 
      type: Number,
      default: 5
    
  ,
  data() 
    return 
      dragged: ''
    
  ,
  methods: 
    dragEnter: function(e) 
      e.target.className += ' hovered'
    ,

    dragOver: function(e) 
      e.preventDefault()
    ,

    dragLeave: function(e) 
      e.target.className = 'box'
    ,

    dragDrop: function(e) 
      e.target.className = 'box'
      e.target.appendChild(this.dragged)
    ,

    dragStart: function(e) 
      e.target.className += ' ondrag'
      this.dragged = e.target
      setTimeout(() => (e.target.className = 'invisible'), 0)
    ,

    dragEnd: function(e) 
      e.target.className = 'fill'
    
  

</script>

<style>
.drag 
  background-color: darksalmon;
  display: flex;
  justify-content: flex-start;


.box 
  background-color: white;
  width: 160px;
  height: 160px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  margin-right: 15px;
  border: 3px white solid;


.fill 
  background-image: url('http://source.unsplash.com/random/150x150');
  width: 150px;
  height: 150px;
  margin: 5px 5px;
  cursor: pointer;


.ondrag 
  border: solid #ccc 4px;


.invisible 
  display: none;


.hovered 
  background: #f4f4f4;
  border-style: dashed;

</style>

【讨论】:

这是解决问题的唯一方法吗?我真的不想这样做,因为对所有页面都需要一段时间......并且组件中可能有太多功能,具体取决于脚本 另外,有没有办法在外部 JavaScript 文件中设置方法,并在组件内部使用它们而不从其中导入函数?例如,在元素的 div 中设置 vue 方法,并在外部 JavaScript 文件中定义相同的函数名称,该文件与页面一起加载 也感谢您花时间为我制作这个sn-p!我很感激 这不是唯一的方法,但是如果您要迁移到 vue 和 Nuxt,它会更好地封装在易于重用的组件中,但这是 Vue 的一部分魔法,它可以与旧的共存代码。我看到了您的网站,我认为您可以更轻松地在 nuxt 中使用 generate 来创建静态网站,我很确定您的收费问题将会消失,nuxtjs.org/guide【参考方案2】:

这是丑陋的,完全是一个坏主意,但正是你所要求的。使用 nuxt,您可以使用旧的链接元素而不是 router-link 或 nuxt-link 绕过导航问题,从而强制刷新整个页面。

记住 nuxt 在通用模式下,服务器渲染第一页,导航的其余部分作为 SPA 实时重新加载,您的问题与 addEventListener 相关,因为在第一次访问时您添加了它,但您从不删除它们。

所以使用链接元素进行导航,你强制刷新整个页面,每次都会是第一次访问。之后为了确保元素在应用之前存在,您可以在模板底部添加脚本,页面将是:

<template>
  <div>
    <a href="/">
      go Home
    </a>
    <div class="container">
      <div class="box">
        <div
          class="fill"
          draggable="true"
          dragstart="dragStart"
          dragend="dragEnd"
        />
      </div>
      <div class="box" />
      <div class="box" />
      <div class="box" />
      <div class="box" />
      <div class="box" />
    </div>
    <script src="js/drag.js" />
  </div>
</template>

<script>
export default 
  name: 'Drag',
  head: 
    link: [ rel: 'stylesheet', type: 'text/css', href: 'css/drag.css' ]
  

</script>

我添加了一个指向 / 的链接用于测试

【讨论】:

我已经试过了,也有一些副作用,我想我会接受你的第一个建议

以上是关于(Nuxt.js/Vue.js) - 脚本只运行一次,更改路由/刷新页面后停止运行的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Nuxt.js (Vue.js) 中使用 vue-infinite-loading

当 nuxt.js (vue.js) 中的路由更改时,Facebook 分享按钮消失

使用 nuxt-mail 在 Nuxt.js 中发送邮件

如何将 Naver Analytics 添加到 Nuxt.js SPA 应用程序?

如何在 Nuxt 中使路由区分大小写

(代码重构)在 javascript 中使用 child_process 的 shell 命令