无法使用Vue.js从opendweathermap获取天气数据

时间:2018-06-06 20:15:37

标签: javascript jquery json vue.js

我想使用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

3 个答案:

答案 0 :(得分:1)

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>

答案 1 :(得分:0)

看起来像是打败了我,但这里是使用jquery调用的版本

如评论中所述,问题是data.data未定义。因此,在数据内部定义数据,并将result分配给this.data。但是,因为它在函数内部并且范围发生变化,所以您需要使用var that = this存储范围并使用that.data = data来分配结果

DOM:

<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>
        {{d}}
      </p>
    </div>
    <ul class="list-group list-group-flush">
    </ul>

  </div>
</div>

<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

脚本:

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

  },

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

    },
  }
});

这是example fiddle

答案 2 :(得分:0)

我发现了导致这些问题的原因:

  1. 我需要在数据中定义数据,因为我直接在我的html页面中引用数据,但这是可选的。
  2. 原来有一个来自bootstrap的超薄jQuery版本会覆盖min jQuery。 $.getJSON()需要min jQuery。