简体   繁体   English

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

[英](Nuxt.js/Vue.js) - Script only works once, stops working after changing route/refreshing the page

I'm "transferring" my projects website to Vue.js with Nuxt.js on top. 我正在将我的项目网站“转移”到Vue.js,最上面是Nuxt.js。 I'm copying over the contents of all the files stored in the remote server to the local "static" folder. 我正在将存储在远程服务器中的所有文件的内容复制到本地“静态”文件夹中。

Everything is working fine, except the JavaScript that runs for the first time the page is loaded, but if I switch to another page through the routes, or refresh the current page, the JavaScript will stop working. 除了第一次加载该页面时运行的JavaScript之外,其他所有东西都工作正常,但是如果我通过路由切换到另一个页面或刷新当前页面,则JavaScript将停止工作。

For instance, there's this page in my projects website: http://archy-user.name/drag/ 例如,我的项目网站中有以下页面: http : //archy-user.name/drag/

Where you can basically drag the image to other boxes, with class changes when you hover over any box with the image. 当您将鼠标悬停在带有图像的任何框上时,基本上可以在其中将图像拖动到其他框,并在其中更改类。

I copied over the CSS to the local static folder, works fine, copied over the JavaScript, it only works once and stops working after changing route/refreshing the page... 我通过CSS复制到本地静态文件夹,工作正常,通过JavaScript复制,仅工作一次,并且在更改路由/刷新页面后停止工作...

It works just like the website when you first load the page, but after reloading/changing route the script just stops working, and there are no class changes when hovering over boxes, etc... Albeit working fine the first time the page is loaded. 它的工作原理与首次加载页面时的网站一样,但是在重新加载/更改路由后,脚本将停止工作,并且将鼠标悬停在框上时类也不会发生变化,等等。尽管在第一次加载页面时工作正常。

Yesterday when researching about this, answers to related questions were saying that this happened because the script is ran only once when the page is loaded, so when there are route changes or the page is refreshed, the script doesn't run again. 昨天,当对此进行研究时,对相关问题的回答是,发生这种情况是因为脚本在页面加载时仅运行了一次,因此当路由更改或页面刷新时,脚本不会再次运行。

Some suggested adding the function supposed to be executed when the page is loaded to the "created()" method inside "export default" in the vue component. 一些建议增加在页面加载到Vue组件的“ export default”内部的“ created()”方法时应执行的功能。

However, in my case, I don't have something that I actually want to execute every time the page is loaded, rather, I want to execute only a certain portion of the script, which would be specific functions triggered only when certain actions are performed by the user in the page through interactions... 但是,就我而言,我并不需要每次页面加载时真正要执行的操作,而是只执行脚本的特定部分,这是仅在执行某些操作时才触发的特定功能。用户在页面中通过互动执行的...

Loading the script every time wouldn't be necessary, as the interactions may not even happen, making the script useless, as well as the load time. 不需要每次都加载脚本,因为甚至可能不会发生交互,从而使脚本以及加载时间变得无用。 Not to mention the mess that the component would become if I were to add the whole script to the "created" method. 更不用说如果我将整个脚本添加到“创建的”方法中,组件将变得一团糟。

Basically I didn't find any real fix for this issue, only workarounds that cause side-effects... 基本上,我没有找到任何针对此问题的真正解决方案,只是找到了会产生副作用的解决方法...

Here's how my components are structured (below component is from http://archy-user.name/drag ): 这是我的组件的结构方式(下面的组件来自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>

Any tips to fix this issue? 有解决此问题的提示吗? Or workarounds to my situation? 还是针对我的情况的解决方法?

PS - Everytime I close the tab and open a new one, the scripts works again until the page is refreshed/route is changed PS-每当我关闭标签并打开一个新标签时,脚本就会再次起作用,直到刷新页面/更改路由为止

You can rewrite your code in vue component style. 您可以用vue组件样式重写代码。 it will be more clear. 这将更加清楚。 and easy to reuse 易于重用

 <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>

this is ugly and totally a bad idea but is exact what you ask. 这是丑陋的,完全是个坏主意,但这正是您要问的。 using nuxt you can bypass the navigation issue using the old link element instead router-link or nuxt-link, with that you force to refresh the entire page. 使用nuxt,您可以使用旧的link元素(而不是router-link或nuxt-link)绕过导航问题,从而强制刷新整个页面。

remember nuxt in universal mode, server render the first page, the rest of the navigation is live reload as SPA, your issue is realted with addEventListener, because in the first visit you add this but you never remove them. 请记住,在通用模式下nuxt,服务器呈现第一页,其余导航作为SPA实时重新加载,您的问题已通过addEventListener解决,因为在第一次访问中,您添加了此内容,但从未将其删除。

So using a link element for navigation you force to refresh the entire page, every time will be the first visit. 因此,使用link元素进行导航时,您将强制刷新整个页面,每次都是第一次访问。 after that to be sure the elements exist before apply you can add the script at the bottom of the template, the page will be: 之后,要确保元素存在,然后再应用,可以在模板底部添加脚本,页面将为:

<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>

I add a link to / for testing 我将链接添加到/进行测试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM