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



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

PS:我正在使用带有 CDN 的 Vue.js,所以我的应用程序不是使用 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();
  },
});

你应该使用箭头函数,比如为了访问 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>

// 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.showtext不是$data对象上的那个......这是一个球状变量window.showtext因为竞标then thiswindow

溶液:

你必须将你的 Vue 实例this绑定到你的then

您可以使用:

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

或:

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

最新更新