Vue组件化理解与使用

一 Vue组件化

应用会被抽象成一棵组件树

1. 组件使用的三个步骤

  1. 创建组件构造器 Vue.extend()
  2. 注册组件 Vue.component()
  3. 使用组件

2. 全局组件(多个Vue实例中可用)

//组件必须放在Vue实例中才能识别
<div id="app">
    <my-cp></my-cp>
</div>
<div id="app1">
    <my-cp></my-cp>
</div>
<script src="vue.js"></script>
<script>
    const cp = Vue.extend({
        //使用`` 方便换行
        template:`
        <div>
          <h1>组件</h1>
        </div> `
    })
    Vue.component('my-cp',cp);

    const app=new Vue({
        el:'#app'
    })
     const app1=new Vue({
        el:'#app1'
    })
</script>

3. 局部组件(只在自身Vue实例可用)

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

<script src="vue.js"></script>
<script>
    const cp = Vue.extend({
        //使用`` 方便换行
        template:`
        <div>
          <h1>组件</h1>
        </div> `
    })
    const app=new Vue({
        el:'#app',
        components: {
            'my-cp':cp,
        },
    })
</script>

4. 父子组件(组件中复用组件)

<script>
    const cp = Vue.extend({//子组件
        //使用`` 方便换行
        template:`
        <div>
          <h1>组件</h1>
        </div> `
    })
    const cp2 = Vue.extend({//父组件
        //使用`` 方便换行
        template:`
        <div>
          <h1>组件</h1>
          <cp1></cp1>
        </div> `,
        components:{
        	'cp1':cp
        }
    })
</script>

5. 语法糖注册组件

<script>
//全局组件
    Vue.component('ap',{
        template:`
        <div>
          <h1>组件</h1>
        </div> `
    })
    const app=new Vue({
        el:'#app',
        components: {
        //局部组件
            'cp':{
             	template:`
		        <div>
		          <h1>组件</h1>
		          <cp1></cp1>
		        </div> `
		     }
        }
    })
</script>

6. 模板分离

<div id="app">
   <cp></cp>
</div>
//一种
<script type="text/x-template" id="cpn">
  <h1>模板噢</h1>
</script>
//二种
<template id="cpn">
  <h1>模板噢</h1>
</template>

<script src="vue.js"></script>
<script>
    Vue.component('cp',{
        template: '#cpn'
    })
</script>    

7. 组件数据存放

  1. 组件不能访问Vue实例中的数据
  2. 本组件的数据放在组件内
  3. 数据不能是个对象,得是个函数(防止使用模板数据共用)
<template id="cpn">
  <h1>模板噢{{title}}</h1>
</template>

<script src="vue.js"></script>
<script>
    Vue.component('cp',{
        template: '#cpn',
        data(){
        	return {
        		title:'abc'
        	}
        }
    })
</script> 

8. 父子组件通信-父传子

<div id="app">
//*********要在这绑定*************
   <cpn :cmsg="msg" :cmovies="movies"></cpn>
</div>

<template id="cpn">
	<div>//得用div包裹
		<h1>看看数据{{cmovies}}</h1>
	</div>
</template>

<script src="vue.js"></script>
<script>
   /*两种写法 放里面放外面都行
   const cpn= {
      template: '#cpn',
          //props: ['cmsg','cmovies'],
          //对象写法
          props:{
          	//1.类型限制
          	//cmovies:Array,
          	//cmsg:String
          	//2. 提供默认值
          	cmsg:{
          		type:String,
          		default:'abc',
          		required:true,//必要参数
          	}
          	cmovies:{
          		default(){
          			return []
          		}
          	}
          }
          data(){
        return{}
      },
      methods:{}
    }
    */
  
    const app=new Vue({
        el:'#app',
        data:{
          msg:'你好',
          movies:['海王','海贼王']
        },
        components: {
            cpn: {
              template: '#cpn',
              props: ['cmsg','cmovies'],
              data(){
                return{}
              },
              methods:{}
            }
        },
    })
</script>

9. 父子组件通信-子传父

<div id="app">
   <cpn @iclick="cpnClick"></cpn>
</div>

<template id="cpn">
  <div>
    <button v-for="item in categories"
            @click="btnClick(item)">
      {{item.name}}
    </button>
  </div>
</template>

<script src="vue.js"></script>
<script>
   const cpn= {
      template: '#cpn',
      data(){
        return {
         categories: [
           {id:'aaa',name:'热门推荐'},
           {id:'bbb',name:'手机家电'},
           {id:'ccc',name:'电脑办公'}
         ]
        }
      },
      methods: {
        btnClick(item){
          //发射事件
          this.$emit('iclick',item);
        }
      }
   }

    const app=new Vue({
        el:'#app',
        data:{
          msg:'你好',
        },
        components: {
            cpn
        },
        methods:{
         cpnClick(item){
           console.log('cpnClick',item);
         }
        }
    })
</script>

10. 父访子 $children $refs

  1. children(不常用)
<div id="app">
   <cpn></cpn>
  <cpn></cpn>
  <button @click="btnClick">按钮</button>
</div>

<template id="cpn">
  <div>
    子组件
  </div>
</template>

<script src="vue.js"></script>
<script>
    const app=new Vue({
        el:'#app',
        data:{
           msg:'你好',
        },
        methods:{
          btnClick() {
            console.log(this.$children);
            //通过$children获得"子组件"
            //但是如果有
            for(let item of this.$children){
              console.log(item.name);
              item.showMessage();
            }
          }},
        components: {
            cpn:{
              template:'#cpn',
              data(){
                return {
                  name:'子组件name'
                }
              },
              methods:{
                showMessage(){
                  console.log('show');
                }
              }
            }
        },
    })
</script>
  1. refs
<div id="app">
   <cpn></cpn>
   //添加一个ref属性
  <cpn ref="aaa"></cpn>
  <button @click="btnClick">按钮</button>
</div>

<template id="cpn">
  <div>
    子组件
  </div>
</template>

<script src="vue.js"></script>
<script>
    const app=new Vue({
        el:'#app',
        data:{
           msg:'你好',
        },
        methods:{
          btnClick() {
            console.log(this.$refs.aaa.name);
          }
        },
        components: {
            cpn:{
              template:'#cpn',
              data(){
                return {
                  name:'子组件name'
                }
              },
              methods:{
                showMessage(){
                  console.log('show');
                }
              }
            }
        },
    })
</script>

11. 子访父 $parent $root

<div id="app">
   <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h1>子组件</h1>
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script src="vue.js"></script>
<script>
    const app=new Vue({
        el:'#app',
        data:{
           name:'你好',
        },
        components: {
            cpn:{
              template:'#cpn',
              methods:{
                btnClick() {
                  //访问到父组件的name数据
                  console.log(this.$parent.name);
                  //访问到跟组件的name数据 这里跟组件就是父组件
                  console.log(this.$root.name +' 跟');
                }
              }
            }
        },
    })
</script>

12. 插槽 slot

  1. 单插槽
<div id="app">
  <cpn></cpn>
  //指定插槽
  <cpn><span>指定插槽</span></cpn>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h1>这是个子组件</h1>
    //默认插槽
    <slot><button>默认插槽</button></slot>
  </div>
</template>

<script src="vue.js"></script>
<script>
    const app=new Vue({
        el:'#app',
        data:{
           name:'你好',
        },
        components: {
            cpn:{
              template:'#cpn',
            }
        },
    })
</script>
  1. 多插槽
<div id="app">
  <cpn></cpn>
  <cpn><span slot="left">指定插槽</span></cpn>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h1>这是个子组件</h1>
    <slot name="left"><button>左边插槽</button></slot>
    <slot name="middle"><button>中间插槽</button></slot>
    <slot name="right"><button>右边插槽</button></slot>
  </div>
</template>

13. 插槽作用域

<div id="app">
  <cpn></cpn>
  <cpn>
    <template slot-scope="slots">
      <span>{{slots.data.join(' = ')}}</span>
    </template>
  </cpn>
</div>

<template id="cpn">
  <div>
    <slot :data="language">
      <ul>
        <li v-for="item in language">{{item}}</li>
      </ul>
    </slot>
  </div>
</template>

<script src="vue.js"></script>
<script>
    const app=new Vue({
        el:'#app',
        data:{
           name:'w'
        },
        components: {
            cpn:{
              template:'#cpn',
              data(){
                return {
                  language:['js','c++','python','go']
                }
              }
            }
        },
    })
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值