首页 > 解决方案 > 无法使用 Vue.js 从 opendweathermap 获取天气数据

问题描述

我想用Vue.js创建一个简单的天气预报网站,我刚刚学习了这个框架,之前访问过公共数据。但这一次我被困住了。

我尝试获取数据的方法有两种版本。

var app = new Vue({
  el: "#weather",
  data: {
    city: '',
    weather:[],
    date: new Date().toDateString(),
    greeting:''

  },

  methods: {
  
  //method 1
    getData: function () {
      var city = this.city
        $.getJSON("http://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=metric&lang=en&appid=a495404234abce9b5830b1e8d20e90a6", 
        function (data) {
          console.log(data)
        });

    },
    
   //method 2
    getData: function () {
      $("#search").keypress(function (e) {
        if (e.which == 13) {
          var city = $("#search").val();
          if (city != " ") {
            var url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=metric&lang=en&appid=a495404234abce9b5830b1e8d20e90a6";

            console.log(url);
            
          }
          $.getJSON(url, function (data) {
              this.weather = data.weather;
            console.log(data);
            this.returnGreeting();
            
          })
        }

      })
    },

    

    }

    
  }
});
<div class="container" id="weather">
    <h1>Weather Pro</h1>
    <div class="float-left"><h2>{{date}}</h2></div>
    <div class="float-right" ><h3 id="time"></h3></div>
    <p>{{greeting}}</p>

    <div class="input-group">
        <form>
          <input v-model="city" class='searchbar transparent' id='search' type='text' placeholder='      enter city' />
          
          <input id='button' @click="getData" type="button" value='GO' />
          
        </form>
    </div>

    {{city}}
    <div class="panel">

      <div class="panel-body" v-for="d in data">

        <p>
          {{data}}
        </p>
      </div>
      <ul class="list-group list-group-flush">
        <!-- <li class="list-group-item">{{data.weather[0].main}}</li>
        <li class="list-group-item">{{data.weather[0].description}}</li> -->
        
      </ul>
    
    </div>
  </div>
  
  <!-- vue -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- jQuery library -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

我收到一个错误:

[Vue 警告]:属性或方法“数据”未在实例上定义,但在渲染期间被引用。通过初始化该属性,确保该属性是反应性的,无论是在数据选项中,还是对于基于类的组件。请参阅:https ://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties 。

标签: javascriptjqueryjsonvue.js

解决方案


考虑data成为你的模特。不要data直接在您的视图中引用,而是引用模型上的属性。

所以而不是<div>{{data.city}}</div>使用<div>{{city}}</div>

var app = new Vue({
  el: "#weather",
  data() {
    return {
      city: '',
      weather: [],
      date: new Date().toDateString(),
      greeting: ''
    };
  },
  methods: {
    getData() {
      fetch("http://api.openweathermap.org/data/2.5/weather?q=" + this.city + "&units=metric&lang=en&appid=a495404234abce9b5830b1e8d20e90a6")
        .then(res => res.json())
        .then(data => {
          this.weather = data.weather;
        });
    }
  }
});
<div class="container" id="weather">
  <h1>Weather Pro</h1>
  <div class="float-left">
    <h2>{{date}}</h2>
  </div>
  <div class="float-right">
    <h3 id="time"></h3>
  </div>
  <p>{{greeting}}</p>
  <div class="input-group">
    <form>
      <input v-model="city" class='searchbar transparent' id='search' type='text' placeholder='      enter city' />

      <input id='button' @click="getData" type="button" value='GO' />

    </form>
  </div>

  {{city}}
  <div class="panel">
    <div class="panel-body" v-for="d in weather">
      <p>
        {{d}}
      </p>
    </div>
    <ul class="list-group list-group-flush"></ul>
  </div>
</div>

<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


推荐阅读