vue.js – VueJS 2对多个组件的辩论

前端之家收集整理的这篇文章主要介绍了vue.js – VueJS 2对多个组件的辩论前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_403_0@
我有一个Vue组件,它使用多个子组件.在这些子组件上,我有一个观察数据变化并处理这些变化的观察者.我想为此实施去抖动.
  1. watch: {
  2. data: {
  3. handler: function () {
  4. this.processData()
  5. },deep: true
  6. }
  7. },methods: {
  8. processData: debounce(function () {
  9. console.log(this.id)
  10. },250),

问题是debounce有效,所以它只在最后一个子组件上执行.

我找到了一个debounce功能解决方案,可以接受额外的id debounceWithId

但问题是,如果我指定此函数如下:

  1. methods: {
  2. processData: debounceWithId(function () {
  3. console.log(this.id)
  4. },250,this.id),

最后一个this.id未定义.

在多个组件中使用去抖动的正确方法是什么,因此该函数会在每个组件上单独触发?

解决方法

首先让我添加一个复制您正在描述的问题的示例.
  1. console.clear()
  2.  
  3. function debounce(func,wait,immediate) {
  4. var timeout;
  5. return function() {
  6. console.log("Called from component ",this._uid)
  7. var context = this,args = arguments;
  8. var later = function() {
  9. timeout = null;
  10. if (!immediate) func.apply(context,args);
  11. };
  12. var callNow = immediate && !timeout;
  13. clearTimeout(timeout);
  14. timeout = setTimeout(later,wait);
  15. if (callNow) func.apply(context,args);
  16. };
  17. };
  18.  
  19. Vue.component("doesntwork",{
  20. props:["value"],template:`<div>Component #{{_uid}} Value: {{innerValue}}</div>`,data(){
  21. return {
  22. innerValue: this.value
  23. }
  24. },watch:{
  25. value(newVal){
  26. this.processData(newVal)
  27. }
  28. },methods:{
  29. processData: debounce(function(newVal){
  30. this.innerValue = newVal
  31. },1000)
  32. },})
  33.  
  34.  
  35. new Vue({
  36. el: "#app",data:{
  37. parentValue: null,}
  38. })
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
  2. <script src="https://unpkg.com/vue@2.4.2"></script>
  3. <div id="app">
  4. Type some text. Wait one second. Only the *last* component is updated.<br>
  5. <input type="text" v-model="parentValue">
  6. <doesntwork :value="parentValue"></doesntwork>
  7. <doesntwork :value="parentValue"></doesntwork>
  8. <doesntwork :value="parentValue"></doesntwork>
  9. </div>

基本上这里发生的是debounced函数是在编译组件时创建的,并且组件的每个实例共享相同的去抖动函数.每种情况的背景都不同,但功能相同.我在生成的debounced函数添加了一个console.log,以便您可以看到所有三个组件共享相同的功能.在这种情况下,该功能正在做它的设计目的;它会在经过一段时间后执行一次,这就是为什么只更新最后一个组件的原因.

要绕过这种行为,您需要为每个组件提供独特的去抖功能.这有两种方法可以做到这一点.

方法

您可以使用占位符的数量初始化processData方法.

  1. methods: {
  2. processData(){}
  3. }

然后,在创建的生命周期事件中,将processData方法更改为debounced方法.

  1. created(){
  2. this.processData = debounce(function(){
  3. console.log(this.id)
  4. },250)
  5. }

这将为每个组件提供独特的去抖功能,并且应该处理只有最后一个组件正常工作的问题.

以下是从上面的示例修改的示例.

  1. console.clear()
  2.  
  3. Vue.component("works",data(){
  4. return {
  5. innerValue: this.value,}
  6. },methods:{
  7. processData() {}
  8. },created(){
  9. this.processData = _.debounce(function(newVal){
  10. this.innerValue = newVal
  11. },1000)
  12. }
  13. })
  14.  
  15. new Vue({
  16. el: "#app",}
  17. })
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
  2. <script src="https://unpkg.com/vue@2.4.2"></script>
  3. <div id="app">
  4. Type some text. Wait one second. <em>All</em> components are updated.<br>
  5. <input type="text" v-model="parentValue">
  6. <works :value="parentValue"></works>
  7. <works :value="parentValue"></works>
  8. <works :value="parentValue"></works>
  9. </div>

方法

感谢@RoyJ的建议.您可以在数据中定义processData方法.通常你不这样做是因为你不经常需要函数的多个副本,这就是组件定义的方法部分存在的原因,但是在这种情况下,你需要为每个组件提供一个独特的函数,你可以在数据函数中定义方法,因为为组件的每个实例调用了数据函数.

  1. data(){
  2. return {
  3. innerValue: this.value,processData: _.debounce(function(newVal){
  4. this.innerValue = newVal
  5. },1000)
  6. }
  7. },

以下是使用该方法的示例.

  1. console.clear()
  2.  
  3. Vue.component("works",processData: _.debounce(function(newVal){
  4. this.innerValue = newVal
  5. },1000)
  6. }
  7. },})
  8.  
  9. new Vue({
  10. el: "#app",}
  11. })
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
  2. <script src="https://unpkg.com/vue@2.4.2"></script>
  3. <div id="app">
  4. Type some text. Wait one second. <em>All</em> components are updated.<br>
  5. <input type="text" v-model="parentValue">
  6. <works :value="parentValue"></works>
  7. <works :value="parentValue"></works>
  8. <works :value="parentValue"></works>
  9. </div>

猜你在找的JavaScript相关文章