检测浏览器关闭或页面更改 VueJs [英] Detect browser close or page change VueJs

查看:28
本文介绍了检测浏览器关闭或页面更改 VueJs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试检测用户何时更改/插入输入,并且他尝试更改/关闭页面以向他发出警告.我做了一些研究,但直到现在我什么也没找到.

<b-表单输入id="名称输入"v-model="名称"></b-form-input></b-form-group>创建(){document.addEventListener('beforeunload', this.handlerClose)},handlerClose:函数处理程序(事件){console.log('改变!!!!');},

解决方案

更简单的方法是简单地比较所选数据的字符串化 JSON.如果它们是等价的,那么我们就知道数据没有被用户更改/更新/变异.

这是一个简单的设置:

  1. 创建一个方法,为您要观察更改的用户数据生成 JSON.
  2. 在创建组件/应用程序时,您缓存创建它的数据并存储/缓存它
  3. 创建一个计算属性,它只返回用户数据和缓存用户数据的当前状态
  4. 在 beforeunload 处理程序中,您可以检查此计算属性的返回值以确定用户是否已更改数据.

请参阅下面的概念验证:

new Vue({el: '#app',//组件数据数据: {//虚拟数据firstName: '约翰',lastName: 'Doe',//缓存表单数据cachedFormData:空,},//组件生命周期挂钩创建:函数(){//创建组件/应用程序时创建缓存this.cachedFormData = this.formDataForComparison();document.addEventListener('beforeunload', this.handlerClose);},//计算属性计算:{//将缓存的用户数据与实时数据进行比较已经改变() {返回 this.cachedFormData !== this.formDataForComparison();}},//组件方法方法: {//回调处理程序处理程序关闭:函数(){如果(this.hasChanged){//检测到变化时的逻辑//例如您可以显示一个确认()对话框来询问用户是否要继续} 别的 {//未检测到变化时的逻辑}},//生成 JSON 进行字符串比较的 Helper 方法formDataForComparison:函数(){返回 JSON.stringify({名字:this.firstName,姓氏:this.lastName});}}});

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script><div id="应用程序"><input type="text" v-model="firstName"/><input type="text" v-model="lastName"/><br/><br/><span>用户是否更改了数据?<strong>{{ hasChanged }}</strong></span>

<小时>

另一种方法是简单地存储一个具有 false 基态的标志,正如另一个答案所建议的那样.每当在元素上检测到输入/更改事件时,标志状态就会切换到 true.但是,这种方法有几个缺点:

  1. 即使用户撤消了他/她的更改,它仍然会标记为已更改.这构成了误报.
  2. 您需要将观察者绑定到所有 v-model 成员,或者将输入/更改事件侦听器绑定到页面上的所有输入元素.如果您的表单很大,您可能会忘记对输入元素执行此操作.

I try to detect when user change/insert into an input and he try to change/close page to give him a warning. I do some research but till now I didn't find anything.

<b-form-group label="Name" label-for="name-input">
<b-form-input
        id="name-input"
        v-model="name"
></b-form-input>
</b-form-group>

created() {
    document.addEventListener('beforeunload', this.handlerClose)
},
handlerClose: function handler(event) {
    console.log('CHANGE!!!!');
},

解决方案

The easier way is to simply compare the stringified JSON of your selected data. If they are equivalent, then we know that the data has not been changed/updated/mutated by the user.

Here's a simple setup:

  1. Create a method that generates the JSON for the user data that you want to observe for changes.
  2. When the compoonent/app is created, you cache the data that it is created with and store/cache it
  3. Create a computed property that simply returns the current state of the user data and cached user data
  4. In the beforeunload handler, you can then check the returned value of this computed property to determine of the user has mutated data or not.

See proof-of-concept below:

new Vue({
  el: '#app',
  
  // COMPONENT DATA
  data: {
    // Dummy data
    firstName: 'John',
    lastName: 'Doe',
    
    // Cache form data
    cachedFormData: null,
  },
  
  // COMPONENT LIFECYCLE HOOK
  created: function() {
    // Create a cache when component/app is created
    this.cachedFormData = this.formDataForComparison();
    
    document.addEventListener('beforeunload', this.handlerClose);
  },
  
  // COMPUTED PROPERTIES
  computed: {
    // Compares cached user data to live data
    hasChanged() {
      return this.cachedFormData !== this.formDataForComparison();
    }
  },
  
  // COMPONENT METHODS
  methods: {
    // Callback handler
    handlerClose: function() {
      if (this.hasChanged) {
        // Logic when change is detected
        // e.g. you can show a confirm() dialog to ask if user wants to proceed
      } else {
        // Logic when no change is detected
      }
    },
    
    // Helper method that generates JSON for string comparison
    formDataForComparison: function() {
      return JSON.stringify({
        firstName: this.firstName,
        lastName: this.lastName
      });
    }
  }
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input type="text" v-model="firstName" />
  <input type="text" v-model="lastName" />
  <br />
  <br />
  <span>Has user changed data? <strong>{{ hasChanged }}</strong></span>
</div>


An alternative method would be simply storing a flag that has a ground state of false, as proposed by the other answer. The flag state is switched to true wheneveran input/change event is detected on the element. However, there are several disadvantages associated with this method:

  1. Even when the user undo his/her changes, it will still marked as changed. This constitutes a false positive.
  2. You will need to either bind watchers to all the v-model members, or bind input/change event listeners to all input elements on the page. If your form is huge, there is a chance that you will forget to do this to an input element.

这篇关于检测浏览器关闭或页面更改 VueJs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆