简体   繁体   English

vuejs - 当我保存文件时,npm run dev webserver 自动刷新工作,但刷新浏览器没有

[英]vuejs - npm run dev webserver auto refresh works when I save a file, but refreshing the browser does not

I'm very new to VueJS but loving the possibilities.我对 VueJS 很陌生,但很喜欢这种可能性。 I started with one of my easier projects (single page php/jquery app) and have been working on converting it to VueJS/Webpack.我从我的一个更简单的项目(单页 php/jquery 应用程序)开始,并一直致力于将其转换为 VueJS/Webpack。 It's basically a table that grabs json data into an array and populates a table and has filter controls.它基本上是一个表格,将 json 数据抓取到一个数组中并填充一个表格并具有过滤器控件。 The drop down controls that filter are populated by unique values from a json field.过滤的下拉控件由 json 字段中的唯一值填充。 That's what I'm currently working on (already got the json call and table working, along with modals that appear when you click on a table row).这就是我目前正在处理的工作(已经让 json 调用和表格工作,以及单击表格行时出现的模式)。

What I'm noticing that is strange, is if I'm working and I save my work in my IDE (vscode) and the localwebserver refreshes my page, I see what is expected in my code to happen.我注意到奇怪的是,如果我正在工作并将我的工作保存在我的 IDE(vscode)中并且本地网络服务器刷新我的页面,我会看到我的代码中预期会发生什么。 However if I click REFRESH in my browser again, nothing works as expected.但是,如果我再次在浏览器中单击 REFRESH,则不会按预期工作。 A good example is in one of my components, I'm building an array to use in my drop down controls.一个很好的例子是在我的一个组件中,我正在构建一个数组以在我的下拉控件中使用。 I'm outputting the array I'm using to populate my drop down using console.log() to make sure it works as I hope, and when I just save the file in vscode, it outputs the data correctly in the browser.我正在输出用于使用console.log()填充下拉列表的数组,以确保它按我希望的那样工作,当我将文件保存在 vscode 中时,它会在浏览器中正确输出数据。 If I immediately refresh my page in browser, it doesn't output the array as it just did, and instead I see [__ob__: Observer] with a length:0 where my array was previously output due to the console.log().如果我立即在浏览器中刷新我的页面,它不会像刚才那样输出数组,而是我看到[__ob__: Observer]length:0 ,由于 console.log(),我的数组以前是输出的。 It also doesn't populate my dropdown.. Is this expected behavior?它也没有填充我的下拉列表。这是预期的行为吗?

Using npm with webpack and (for the first time ever) the built in webserver and compiler.将 npm 与 webpack 和(有史以来第一次)内置的 web 服务器和编译器一起使用。 I'm using the single page approach, App.vue , and I have 3 components in that App.vue .我正在使用单页方法App.vue ,并且该App.vue中有 3 个组件。 I'm filling an array named fans using json data (on my mounted() hook) and passing it as a prop into each component.我正在使用 json 数据(在我的mounted()挂钩上)填充一个名为fans的数组,并将其作为道具传递给每个组件。 Here is my App.vue :这是我的App.vue

<template>
  <div>
      <fan-modals v-bind:fans="fans"></fan-modals>

      <div class="container">
          <filter-controls v-bind:fans="fans"></filter-controls>
          <fans v-bind:fans="fans"></fans>
      </div>  <!-- end #container -->
  </div>
</template>

<script>
  import FilterControls from './components/FilterControls.vue';
  import Fans from './components/Fans.vue';
  import FanModals from './components/FanModals.vue';

  export default {
    name: 'app',
    data: function() {
      return {
        fansUrl: 'example.com',
        fans: []
      }
    },
    components: {
      filterControls: FilterControls,
      fans: Fans,
      fanModals: FanModals
    },
    methods: {
    },
    mounted() {
        var self = this;
        $.getJSON(self.fansUrl, function(data){
            self.fans = data;
        });
    }
}
</script>

The component that is giving me problems output is my FilterControls component, seen here (I left out all other controls for brevity):给我输出问题的组件是我的FilterControls组件,见此处(为简洁起见,我省略了所有其他控件):

<template>

        <div class="row">
            <div class="col-xs-6 col-sm-6 control-wrap">
                <select id='selectVoltage' class='form-control' v-model="voltageArray">
                <option>Voltage</option>
                <option v-for="(voltage, index) in voltageArray" :key="index" v-bind:value="voltage">
                    {{ voltage }}
                </option>
                </select>
            </div>
            <div class="col-xs-6 col-sm-6 control-wrap">
                <select id='selectMaxRPM' class="form-control">
                <option>Max RPM</option>
                </select>
            </div>
        </div>
        </template>

<script>
    export default {
        data: function() {
            return {
                voltageArray: [],
            }
        },
        props: {
            fans: {
                type: Array,
                required: false
            }
        },
        methods: {
            populateControls() {
                var vi = this;
                console.log("populateControls() called ");
                if (vi.fans) {
                    console.log("there are fans ");

                    var voltage = [];

                    $.each(vi.fans, function(index, value) {
                        voltage.push(vi.fans[index].voltage);

                    });

                    vi.voltageArray = $.unique(voltage);

                    console.log(vi.voltageArray);
                }

            }
        },
        mounted() {
            this.populateControls();
        }
    }
</script>

I'm passing the same array I use to populate my table as a prop to the component.我将用于填充表格的相同数组作为组件传递给组件。

When I save my work and it's auto refreshed in the browser it works.当我保存我的工作并在浏览器中自动刷新时,它可以工作。 When I refresh the page in the browser it doesn't.当我在浏览器中刷新页面时,它不会。 I'm baffled.我很困惑。

This is a race condition.这是一个竞争条件。 The timing of the mounting of <filter-controls> and the asynchronous network response from $.getJSON is going to vary. <filter-controls>的安装时间和来自$.getJSON的异步网络响应会有所不同。 In cases where you'd see the expected output, the network response is likely received before <filter-controls> has mounted.如果您看到预期的输出,则可能是在<filter-controls>挂载之前收到网络响应。 The network response can be delayed for various reasons, including poor network connectivity.网络响应可能因各种原因而延迟,包括网络连接不良。

I believe what's happening in your case is that the network response is received after <filter-controls> mounts and logs fans (which is based on the network response).我相信您的情况是在<filter-controls>挂载和记录fans (基于网络响应)之后收到网络响应。 Later you make an edit, webpack-dev-server hot-reloads, and the browser gets the cached network response (no network request) before <filter-controls> mounts.稍后您进行编辑, webpack-dev-server热重新加载,浏览器在<filter-controls>挂载之前获取缓存的网络响应(无网络请求)。

demo of bug错误演示

You can also prove this to yourself in your sandbox by disabling the cache in Chrome's DevTools.您还可以通过在 Chrome 的 DevTools 中禁用缓存来在沙箱中向自己证明这一点。

It's best to remove the assumption that the prop data would be available when the component is mounted.最好删除在安装组件时可以使用道具数据的假设。 Instead, use a watcher to react to prop changes:相反,使用观察者对道具变化做出反应:

export default {
  mounted() {
    // this.populateControls(); // DON'T DO THIS
  }
  watch: {
    fans(value) { // <-- called whenever fans prop changes
      this.populateControls(value);
    }
  },
  methods: {
    populateControls(fans) {
      console.log('new fans', fans);
    }
  }
}

Also note that the v-model of <select> should hold the value of the selected voltage, not the voltageArray , which is used to populate the <option> s.另请注意, <select>v-model应保存所选电压的值,而不是用于填充<option>voltageArray You should add a data variable exclusively for the selected voltage:您应该专门为所选电压添加一个data变量:

<!-- <select v-model="voltageArray">  // DON'T DO THIS -->
<select v-model="selectedVoltage">

demo of fix修复演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM