vue学习指南3


2.9 组件

组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素;通过Vue.component()接口将大型应用拆分为各个组件,从而使代码更好具有维护性、复用性以及可读性。

注册组件

<div id="app" >
    <my-component>my-component>
  div>
Vue.component('my-component',{template:'<div>my-componentdiv>'})
var app=new Vue({
  el:'#app',
  data:{
  }
})

解读:

  • 注册行为必须在创建实例之前;
  • component的template接口定义组件的html元素;

局部注册组件

"app" > <my-component> <heading>heading> my-component> div> Vue.component('my-component',{template:'
my-first-component
'}); var Child={ template:'

hello world

' }; var app=new Vue({ el:'#app', components:{ 'my-component':Child } });

解读:

  • 可以定义一个子组件,在实例的components接口中将子组件挂载到父组件上,子组件只在父组件的作用域下有效;

特殊DOM模板将会限制组件的渲染

像这些包含固定样式的元素

      "my-component"> table>

      创建组件的data对象必须是函数

      <div id="app">
         <counter>counter>
         <counter>counter>
         <counter>counter>
        div>
      Vue.component('counter',{
        template:'<button @click="count+=1">{{count}}button>',
        data:function(){
          return {
            count: 0
          };
        }
      });
      var app=new Vue({
        el:'#app',
        data:{
        }
      });

      解读:

      • 在组件当中定义的数据count必须以函数的形式返回;

      使用Props实现父组件向子组件传递数据

      <div id="app">
         <child some-text='hello'>child>
          <br>
          <child v-bind:some-text='message'> child>
        div>
      Vue.component('child',
                    {template:'
      {{someText}} div>',props:['someText'] }); var app=new Vue({ el:'#app', components:{ 'my-component':Child }, data:{ message:'你好' } });

      解读:

      • 组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件;

      • 可以用 v-bind动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件,注意这种绑定方式是单向绑定;

      父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去则使用自定义事件!

      "app">

      {{total}}

      'incrementTotal'> 'incrementTotal'>
      Vue.component('button-counter',{ template:'', data:function(){ return { counter:0 } }, methods:{ increment:function(){ this.counter +=1; this.$emit('increment') } } }) var app = new Vue({ el:'#app', data:{ total:0 }, methods:{ incrementTotal:function(){ this.total += 1; } } })

      解读:

      • 父组件可以通过监听子组件的自定义事件,从而改变父组件的数据;
      • 子组件每点击一次,触发increment函数,该函数在执行过程中通过$emit('increment')发出increment事件;
      • button控件同时监听increment事件,每次发出该事件就改变父组件的total值;

      使用Slots分发内容

      <div id="app">
           <h1>I'm the parent titleh1>
        <my-component>
          <p>This is some original contentp>
          <p>This is some more original contentp>
        my-component>
          <hr>
        div>
      Vue.component('my-component',{
        template:"<div><h2>sssssh2><slot>如果没有分发内容则显示我。slot>div>"
      });
      var app = new Vue({
        el:'#app',
        data:{
        }
      });

      解读:

      • 如果子组件模板一个都不包含,则父组件内容将会被丢弃;
      • 当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身;
      • 只有在宿主元素为空,且没有要插入的内容时才显示备用内容;
      //子组件app-layout模板
      <div class="container">
      <header>
      <slot name="header">slot>
      header>
      <main>
      <slot>slot>
      main>
      <footer>
      <slot name="footer">slot>
      footer>
      div>
      //父组件模板
      <app-layout>
      <h1 slot="header">Here might be a page titleh1>
      
      <p>A paragraph for the main content.p>
      <p>And another one.p>
      
      <p slot="footer">Here's some contact infop>
      app-layout>
      //渲染结果
      <div class="container">
      <header>
      <h1>Here might be a page titleh1>
      header>
      <main>
      <p>A paragraph for the main content.p>
      <p>And another one.p>
      main>
      <footer>
      <p>Here's some contact infop>
      footer>
      div>

      解读:

      • 具名slot相当于给slot设置标识符,只要在父组件的元素上设置
        就可以把该元素插入子组件定义的模板;

      2.10 vue-resource插件

      使用vue-rescource实现前后端的通信
      在vue实例中新增ready对象,当页面完成加载时发出请求

      new Vue({
          el: '#app',
          ready: function() {
              this.$http.get('book.json', function(data) {
                  this.$set('books', data);
              }).error(function(data, status, request) {
                  console.log('fail' + status + "," + request);
              })
            //post方法:this.$http.post(url,postdata,function callback)
          },
          data: {
              ....
              books:''
          },

      解读:

      • 这个$http请求和jquery的ajax还是有点区别,这里的post的data默认不是以form data的形式,而是request payload。解决起来也很简单:在vue实例中添加headers字段:
      • http: { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }