检测浏览器关闭或页面更改 VueJs [英] Detect browser close or page change VueJs
问题描述
我尝试检测用户何时更改/插入输入,并且他尝试更改/关闭页面以向他发出警告.我做了一些研究,但直到现在我什么也没找到.
<b-表单输入id="名称输入"v-model="名称"></b-form-input></b-form-group>创建(){document.addEventListener('beforeunload', this.handlerClose)},handlerClose:函数处理程序(事件){console.log('改变!!!!');},
更简单的方法是简单地比较所选数据的字符串化 JSON.如果它们是等价的,那么我们就知道数据没有被用户更改/更新/变异.
这是一个简单的设置:
- 创建一个方法,为您要观察更改的用户数据生成 JSON.
- 在创建组件/应用程序时,您缓存创建它的数据并存储/缓存它
- 创建一个计算属性,它只返回用户数据和缓存用户数据的当前状态
- 在 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
.但是,这种方法有几个缺点:
- 即使用户撤消了他/她的更改,它仍然会标记为已更改.这构成了误报.
- 您需要将观察者绑定到所有
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:
- Create a method that generates the JSON for the user data that you want to observe for changes.
- When the compoonent/app is created, you cache the data that it is created with and store/cache it
- Create a computed property that simply returns the current state of the user data and cached user data
- 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:
- Even when the user undo his/her changes, it will still marked as changed. This constitutes a false positive.
- 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屋!