Vue发送请求和Vue组件

359 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

Vue发送请求

在前端开发中,我们经常会使用到jQuery发送ajax请求,但在Vue中,它并不推荐使用jQuery,所以我们可以借助另一种方式实现数据请求—— vue-resource 。

首先需要引入vue-resource.js文件:

<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>

因为vue-resource依赖于Vue.js,所以vue-resource.js文件必须在Vue.js文件之后引入,引入完成后,来尝试发送请求:

<div id="app">
  <input type="button" value="发送GET请求" @click="get">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入vue-resource -->
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>

<script>
  var app = new Vue({
    el: '#app',
    data: {
      msg: 'success'
    },
    methods: {
      get() {
        // 发送GET请求
        this.$http.get('http://localhost:8080/get/info').then(function (result) {
          console.log(result);
        });
      }
    }
  });
</script>

点击该页面上的按钮触发回调函数,通过Vue实例调用 $http.get() 函数即可发送请求,参数为需要请求的url,并通过调用 then 函数来定义请求成功后的回调,执行结果:

要想发送post请求,只需调用 post 函数即可:

<script>
  methods: {
    post() {
      // 发送GET请求
      this.$http.post('http://localhost:8080/post/info', {id:1,name:'abc'}, {emulateJSON:true}).then(function (result) {
        console.log(result);
      });
    }
  }
</script>

其中 {id:1,name:'abc'} 是此次post请求携带的请求参数,而 {emulateJSON:true} 表示以表单形式将请求参数传递给后台服务器,否则服务器将无法处理这些参数,执行结果:

事实上,对于前后端分离的项目,不可避免地会出现跨域问题,这里的get和post请求没有出现问题是因为后台服务器作了跨域处理,若是将跨域处理的逻辑删除,则会:

所以若是想在前端解决跨域问题,则需要发送jsonp请求,实现如下:

<script>
  var app = new Vue({
    methods: {
      jsonp() {
        // 发送GET请求
        this.$http.jsonp('http://localhost:8080/get/info').then(function (result) {
          console.log(result);
        });
      }
    }
  });
</script>

Vue组件

组件的出现,就是为了拆分Vue实例的代码,它能够让我们以不同的组件来划分不同的功能模块,之后需要使用哪个模块,就调用对应的组件即可。

Vue支持三种创建组件的方式,第一种方式如下:

<div id="app">
  <my-component></my-component>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
  var component = Vue.extend({
    template: '<h3>Vue.extend方式创建的组件</h3>' // 指定组件要展示的HTML结构
  });
  Vue.component('myComponent', component);
</script>

这里需要注意的是组件的名称若是驼峰命名,则在使用组件的时候必须将驼峰转为 - 相连。

效果如下:

第二种方式便是直接通过Vue的 component函数创建组件:

<script>
  Vue.component('myComponent', {
    template: '<h3>Vue.extend方式创建的组件</h3>' // 指定组件要展示的HTML结构
  });
</script>

需要清楚的是, template 属性中存放的是组件的HTML内容,但该内容只允许一个根标签的存在,所以若是有多个同级的标签,则需要将它们放在同一个 div下,比如:

template: '<div><h3>Vue.extend方式创建的组件</h3><p>hello</p></div>'

第三种方式要略显麻烦一些:

<div id="app">
  <my-component></my-component>
</div>

<template id="temp">
  <div>
    <h3>template标签方式创建的组件</h3>
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
  Vue.component('myComponent', {
    template: '#temp'
  });
</script>

仍然是通过 component函数创建组件,但在 template 属性中不再是编写HTML内容了,而是设置了一个id,然后在被Vue实例控制的div的同级位置下编写 template 标签,并将id设置为刚才的id,这样做的好处是在 template 标签下编写HTML内容将有代码提示。

\

和过滤器、自定义指令类似,在Vue实例中也有一个 components 属性,它是用来定义只属于当前Vue实例的私有组件的,方式如下:

<div id="app">
  <my-Input></my-Input>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
  var app = new Vue({
    el: '#app',
    data: {
    },
    components: {
      myInput:{
        template:'<h1>这是自定义的私有组件</h1>'
      }
    }
  });
</script>

它当然也支持通过id将HTML内容设置到外部的template标签中:

<div id="app">
  <my-Input></my-Input>
</div>

<template id="temp">
  <div>
    <h1>这是自定义的私有组件</h1>
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
  var app = new Vue({
    el: '#app',
    data: {
    },
    components: {
      myInput:{
        template:'#temp'
      }
    }
  });
</script>

自定义的组件中可以有自己的data和methods属性,但与Vue实例不同的是,在自定义组件中,data必须定义为一个函数,而且必须返回一个对象:

<script>
  Vue.component('myComponent',{
    template:'<h1>自定义组件</h1>',
    data() {
      return {
        msg:'自定义组件中的私有数据'                
      }
    },
  });
</script>

data必须定义为函数且必须返回一个对象的原因在于,倘若自定义的多个组件共享了一个对象值,那么就会出现问题,比如:

<div id="app">
  <my-component></my-component>
  <my-component></my-component>
  <my-component></my-component>
</div>
<template id="temp">
  <div>
    <input type="button" value="+1" @click="add">
    <h3>{{result}}</h3>
  </div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var obj = { result: 0 };
  Vue.component('myComponent', {
    template: '#temp',
    data() {
      return obj;
    },
    methods: {
      add() {
        this.result++;
      }
    },
  });
</script>

效果如下:

此时不管点击哪个按钮,都会影响到其它三个组件的属性值,为此,我们必须将数据以return的形式单独返回出去:

<script>
  Vue.component('myComponent', {
    template: '#temp',
    data() {
      return {
        result: 0
      };
    },
    methods: {
      add() {
        this.result++;
      }
    },
  });
</script>