Vue组件

目录

一、组件注册      1、全局注册      2、局部注册

二、data

三、组件动态切换

四、组件传值      1、父组件向子组件传递数据prop      2、父组件向子组件传递方法、子组件向父组件传值

五、插槽slot

六、处理边界情况

组件:为了拆分Vue实例的代码量,以不同的组件划分不同的功能模块。

模块化:代码逻辑的角度,方便代码分层开发,保证每个功能模块的职能单一。
组件化:UI界面的角度,前端的组件化,方便UI组件的重用。

一、组件注册

使用组件时,直接把组件的名称,以HTML标签的形式引入到页面中。

组件名称可以是用短横线分隔或驼峰式,但是HTML标签均使用短横线分隔、字母全小写形式。推荐组件名“必须包含一个连字符”,避免和未来的HTML元素冲突。

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

组件模板对象的template属性是组件要展示的HTML内容,该内容必须有且只能有一个根元素。

1、全局注册

全局注册,在注册之后可以用在任何新创建的Vue根实例的模板中,包括组件在各自内部可以互相使用。

Vue.component('my-component-name', 创建出来的组件模板对象);

(1)Vue.component

Vue.component('myCom',{
  template:'<h3>模板字符串</h3>'
});

(2)组件模板对象+Vue.component

var myCom={
  template:'<h3>模板字符串</h3>'
};
Vue.component('my-com',myCom);

(3)Vue.extend+Vue.component

var com=Vue.extend({
  template:'<h3>模板字符串</h3>'
});
Vue.component('myCom',com);

(4)<template>+Vue.component

<!-- 在被控制的#app外面,使用template元素,定义组件的HTML模板结构,有代码提示和高亮 -->
<template id="tmp">
  <h3>模板字符串</h3>
</template>

Vue.component('myCom',{
  template:'#tmp'
});

(5)<script>+Vue.component

<script id="tmp" type="x-template">
  <h3>模板字符串</h3>
</script>

Vue.component('myCom',{
  template:'#tmp'
});

2、局部注册

局部注册的组件互相之间不可用。

局部注册的形式参考全局注册,对于(2),当组件模板对象的名称和组件名称相同时,可简化写法components:{myCom},表示该属性名和属性值相同。

var vm=new Vue({
  el:'#app',
  components:{
    'component-a':{
      template:"<div><h2>私有组件a</h2><component-sub></component-sub></div>", // 使用子组件
      components:{ // 定义子组件的子组件
        'component-sub':{
          template:"<h3>私有组件a中的子组件c</h3>"
        }
      }
    },
    'component-b':{
      template:"<h2>私有组件b</h2>"
    }
  }
});

二、data

组件是可复用的 Vue 实例,与new Vue接收相同的选项,如data、computed、watch、methods及生命周期钩子等。仅有的例外是像el这样根实例特有的选项。

组件的data和实例的data不同,组件的data必须是一个函数,必须返回一个对象。每个实例可以维护一份被返回对象的独立的拷贝。

Vue.component('mycom',{
  template:'<h3>--{{msg}}--</h3>',
  data:function(){
    return {
      msg:'我是组件中的data数据'
    } 
  }
});
<counter></counter>
<counter></counter>

var obj={count:0}; //此时所有实例共享同一个对象
Vue.component('counter',{
  template:'<div><button @click="increment">+1</button><h3>{{count}}</h3></div>',
  data:function(){
    return obj
  },
  methods:{
    increment(){
      this.count++;
    }
  }
});

三、组件动态切换

1、使用flag标识符结合v-if和v-else切换组件

<div id="app">
  <a href="#" @click.prevent="flag=true">登录</a>
  <a href="#" @click.prevent="flag=false">注册</a>
  <login v-if="flag"></login>
  <register v-else="flag"></register>
</div>

<script>
  Vue.component('login',{
    template:'<h3>登录组件</h3>'
  });
  Vue.component('register',{
    template:'<h3>注册组件</h3>'
  });
  var vm=new Vue({
    el:'#app', 
    data:{
      flag:true
    }
  });
</script>

2、使用is属性来切换不同的子组件,并添加切换动画

Vue提供了<component>加is属性,来展示对应名称的组件。is可以绑定已注册组件的名称,或一个组件的选项对象。

<div id="app">
  <a href="#" @click.prevent="comName='login'">登录</a>
  <a href="#" @click.prevent="comName='register'">注册</a>
  <component :is="comName"></component>
</div>
<script>
  Vue.component('login',{
    template:'<h3>登录组件</h3>'
  });
  Vue.component('register',{
    template:'<h3>注册组件</h3>'
  });
  var vm=new Vue({
    el:'#app', 
    data:{
      comName:'login'
    }
  });
</script>

使用<transition>实现多个组件之间的过渡。

mode属性指定过渡模式,默认进入和离开同时发生。mode的值有两个:in-out,新元素先进行过渡,完成之后当前元素过渡离开;out-in,当前元素先进行过渡,完成之后新元素过渡进入。

<transition mode="out-in">
  <component :is="comName"></component>
</transition>

四、组件传值

子组件中,默认无法访问到父组件data上的数据和methods中的方法。

1、父组件向子组件传递数据prop

(1)绑定

在父组件中引用子组件时,通过属性绑定(v-bind)的形式给子组件传递数据。

可以绑定静态的值或动态的值。

任何类型的值都可以传给一个prop,包括数字、布尔值、数组、对象、对象的属性等。

HTML中的特性名是大小写不敏感的,驼峰命名的prop名需要使用其等价的短横线分隔命名。如果你使用字符串模板,那么这个限制就不存在了。

<div id="app">
  <sub-com title="My journey with Vue"></sub-com> <!--绑定静态的值-->
</div>

<div id="app">
  <sub-com :fathermsg="msg"></sub-com> <!--绑定动态的值,来自父组件-->
</div>

(2)prop

prop是可以在组件上注册的一些自定义特性。当一个值传递给一个prop特性时,它就变成了该组件实例的一个属性,就可以在该组件中使用该数据。

var vm=new Vue({
  el:'#app',
  data:{
    msg:"Blogging with Vue"
  },
  components:{
    subCom:{
      template:'<h3>这是子组件 "{{fathermsg}}"是来自父组件的数据</h3>',
      props:['fathermsg','title']
    }
  }
});

子组件的data数据是子组件私有的,如子组件通过 Ajax请求回来的数据,都可以放到 data 上,是可读可写的。组件props中的数据,是父组件传递的,都是只读的,无法重新赋值。

2、父组件向子组件传递方法、子组件向父组件传值

(1)绑定

在父组件中引用子组件时,通过事件绑定(v-on)的形式给子组件传递方法。

事件名不存在任何自动化的大小写转换,不存在驼峰和短横线命名的转换。不同于组件和 prop,事件名不会被用作一个JavaScript变量名或属性名;v-on事件监听器在DOM模板中会被自动转换为全小写,因为HTML是大小写不敏感的。推荐始终使用短横线命名的方式。

<div id="app">
  <sub-com @fathershow="show"></sub-com>
</div>

(2)在子组件中触发父组件的事件$emit()

在子组件的HTML中,直接使用$emit();在子组件的方法中,使用this.$emit()。

<template id='subtmp'>
  <button @click="$emit('fathershow','第二个参数');">触发父组件的show方法</button>
</template>

var vm=new Vue({
  el:'#app',
  methods:{
    show(data){
      console.log('父组件的show方法'+data);
    }
  },
  components:{
    subCom:{
      template:'#subtmp'
    }
  }
});

(3)向父组件传值

$emit()的第二个参数及之后的参数,作为父组件事件的参数,向父组件传值。

五、插槽slot

和HTML元素一样,经常需要向一个组件传递内容。Vue自定义的<slot>元素让这变得非常简单,只要在需要的地方加入插槽。

Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Hello!</strong>
      <slot></slot>
    </div>
  `
})

插槽内可以包含任何模板代码,包括HTML、其它组件等。

<alert-box>
  Something good happened.
</alert-box>

<navigation-link url="/profile">
  <!-- 添加一个图标的组件 -->
  <font-awesome-icon name="user"></font-awesome-icon>
  Your Profile
</navigation-link>

六、处理边界情况

(1)获取DOM元素和组件引用

通过ref特性为HTML元素或组件赋予一个ID引用。

使用this.$refs.input可操作该DOM元素,使用this.$refs.mycom可访问该组件实例,使用其中的数据和方法等。

<input ref="input">
<my-com ref="mycom"></my-com>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值