Vue v-if 使用间隔时不影响 Dom

Posted

技术标签:

【中文标题】Vue v-if 使用间隔时不影响 Dom【英文标题】:Vue v-if not affect to Dom when using interval 【发布时间】:2019-12-04 03:53:23 【问题描述】:

我正在尝试使用 setInterval 进行轮询并使用 Vue 有条件地渲染一些元素。但它不起作用,所以我将我的数据设置为true,但在 DOM 上什么也没发生。

P.S:我使用 Vue.js 和 CDN,所以我的应用不是用 VueCLI 创建的。

这是我的 html

<div id="app">
  <div class="container">
    <h1 v-if="showtext">
      text
    </h1>
  </div>
</div>

这是我的脚本。当以状态 200 响应时,我的数据将切换为 true。我可以在控制台上看到它,但我的文本没有在 DOM 上呈现。

var app = new Vue(
  el: "#app",
  data: 
    polling: null,
    showtext: false
  ,
  methods: 
    pollData() 
      this.polling = setInterval(() => 
        axios(
          method: "get",
          url: "https://jsonplaceholder.typicode.com/comments"
        ).then(function(response) 
          console.log(response);
          if (response.status == 200) 
            this.showtext = true
          
          console.log(this.showtext)
        );
      , 7000);
    
  ,
  beforeDestroy() 
    clearInterval(this.polling);
  ,
  created() 
    this.pollData();
  ,
);

【问题讨论】:

我打赌 this 在 axios 回调中是错误的。只需登录this 并查看。正如你所拥有的那样,你无法真正判断这是否是问题所在,因为你只检查你设置的内容,而不是它所附加的内容...... 【参考方案1】:

为什么我的文本没有被渲染?

因为您在控制台上看到的this.showtext 不是您的$data 对象上的那个...它是一个全局变量window.showtext,因为thisthen 的出价是window

解决方案:

您必须将您的 vue 实例 this 绑定到您的 then

您可以使用:

then((response) => ) (which binds this implicitly)

或:

then((function(response)  ... ).bind(this) )

【讨论】:

【参考方案2】:

您应该使用箭头函数来访问 vue 实例范围:

 then((response)=>  ...

或将this 分配给一个全局变量,如下所示(这适用于旧浏览器):

    var that=this; ///<------ 
  axios(
                method: "get",
                url: "https://jsonplaceholder.typicode.com/comments"
              ).then(function(response) 
                console.log(response);
                if (response.status == 200) 
                  that.showtext = true
                
                console.log(that.showtext)
              );

完整运行示例:

Vue.config.devtools = false;
Vue.config.productionTip = false;

     var app = new Vue(
        el: "#app",
        data() 
          return
          polling: null,
          showtext:false
          
        ,
        methods: 
          pollData() 
            this.polling = setInterval(() => 
              axios(
                method: "get",
                url: "https://jsonplaceholder.typicode.com/comments"
              ).then((response)=> 
               
                if (response.status == 200) 
                  this.showtext = true
                
                console.log(this.showtext)
              );
            , 4000);
          
        ,
        beforeDestroy() 
          clearInterval(this.polling);
        ,
        created() 
          this.pollData();
        ,
      );
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script src="https://unpkg.com/vue-axios@2.1.4/dist/vue-axios.min.js"></script>
<div id="app">
      <div class="container">
      test:
        <h1 v-if="showtext">
          text
        </h1>
      </div>
    </div>

【讨论】:

【参考方案3】:
// You have lost context in this function, use arrow function instead
.then(function(response) 
  console.log(response);
  if (response.status == 200) 
    this.showtext = true
  
  console.log(this.showtext)
);

类似这样的:

.then(response => 
  console.log(response);
  if (response.status == 200) 
    this.showtext = true
  
  console.log(this.showtext)
);

【讨论】:

谢谢它的工作。你能告诉我箭头函数有什么技巧吗?和箭头功能也可以在旧浏览器中使用? 箭头函数在词法上绑定它们的上下文,所以this实际上是指原始上下文。 在您的情况下,您丢失了指向 Vue 实例的 this,但使用箭头函数您可以保存该上下文以访问 showtext 属性。

以上是关于Vue v-if 使用间隔时不影响 Dom的主要内容,如果未能解决你的问题,请参考以下文章

VUE性能优化总结

Vue的组件,过滤器,自定义指令以及v-if

vue 控制元素的显示和隐藏

vue中的v-if与v-show

[Vue] Conditionally Render DOM Elements in Vue.js (v-if v-else v-show)

vue -- v-if & v-show