组件化开发

目录

一、注册组件的基本步骤

创建组件构造器

注册组件

使用组件 

二、全局组件与局部组件

三、父组件与子组件

1、定义

2、通信

四、组件的语法糖

 五、组件模板抽离

六、组件数据存储

七、自制计数器组件 

八、插槽(slot)

1、为什么要使用插槽

2、插槽的使用


一、注册组件的基本步骤

  1. 创建组件构造器

  2. 注册组件

  3. 使用组件 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
 <my-cpn></my-cpn>
 </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    //  1、创建组件构造对象
    const cpnC = Vue.extend({
      template: `
        <div>
          <h2>标题</h2>
          <p>内容1</p>
          <p>内容2</p>
        </div> `
    })
    // 2、注册组件
    Vue.component('my-cpn', cpnC) //(组件的标签名,组件构造对象)

  const app = new Vue({
      el: "#app",
      data: {
        number: 10
      },
      methods: {
      }
    })
  </script>
</body>
</html>

二、全局组件与局部组件

     全局组件:可以在多个Vue的实例下使用

     局部组件 :只能在当前Vue实例下使用

  • 全局组件:在Vue实例外注册
  • 局部组件:在Vue实例里注册
<script>
    //  1、创建组件构造对象
    const cpnC = Vue.extend({
      template: `
        <div>
          <h2>标题</h2>
          <p>内容1</p>
          <p>内容2</p>
        </div> `
    })
    // 2、注册组件(全局组件)
    Vue.component('my-cpn', cpnC) //(组件的标签名,组件构造对象)

  const app = new Vue({
      el: "#app",
      data: {
        number: 10
      },
      // 2、注册组件(局部组件)
      components: {
        cpn: cpnC // cpn使用组件时的标签名:构造器

      }
    })
  </script>

三、父组件与子组件

1、定义

子组件:在父组件的构造对象中注册的组件为该组件的子组件

2、通信

  • 通过props向子组件传递数据
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn v-bind:cnumber="number" :cmovies="movies"></cpn>
 </div>

<template id="cpn">
  <div>
    <p>{{cnumber}}</p>
    <h2>{{cmovies}}</h2>
  </div>
</template>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    const cpn = {
      template: `#cpn`,
      // 1、数组类型
      props: ['cnumber', 'cmovies'],
      // 2、对象类型(可以设置变量类型)
      props: {
        cnumber: Number,
        cmovies: Array
      }
    }

    const app = new Vue({
        el: "#app",
        data: {
          number: 10,
          movies: ["星际穿越", "阿凡达", "大话西游", "实间管理局"]
        },
        components: {
          cpn
        }
      })
  </script>
</body>
</html>
  • 通过事件向父组件发送信息
<!--父子通信,子向父-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn @itemclick="cpnClick"></cpn>
  <h2>{{id}}</h2>
 </div>

<template id="cpn">
  <div>
    <button
      v-for="item in categories"
      @click="btnClick(item)">
      {{item.name}}
    </button>
  </div>
</template>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    // 子组件
    const cpn = {
      template: `#cpn`,
      data() {
        return {
          categories: [
            {id: 'aaa', name: '热门推荐'},
            {id: 'bbb', name: '手机数码'},
            {id: 'ccc', name: '家用家电'},
            {id: 'ddd', name: '电脑办公'}
          ]
        }
      },
      methods: {
        btnClick(item) {
          this.$emit('itemclick', item)
        }
      }
    }
    // 父组件
    const app = new Vue({
        el: "#app",
        data: {
          id: '0'
        },
      methods: {
        cpnClick(item) {
          this.id = item.id
        }
      },
        components: {
          cpn
        }
      })
  </script>
</body>
</html>

四、组件的语法糖

 使用构造方法直接代替注册时的构造对象

Vue.component('my-cpn', {
      template: `
        <div>
          <h2>标题</h2>
          <p>内容1</p>
          <p>内容2</p>
        </div> `
    }) //(组件的标签名,组件构造对象)

 五、组件模板抽离

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn></cpn>
 </div>
<!--1、script标签,注意:类型必须是text/x-template类型-->
<script type="text/x-template" id="cpn">
  <div>
    <h2>标题</h2>
    <p>段落1</p>
    <p>段落2</p>
  </div>
</script>
<!--2、template标签-->
<template id="cpn">
  <div>
    <h2>标题</h2>
    <p>段落1</p>
    <p>段落2</p>
  </div>
</template>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    Vue.component('cpn', {
      template: `#cpn`
    })

  const app = new Vue({
      el: "#app",
      data: {
        number: 10
      },
      methods: {
      }
    })
  </script>
</body>
</html>

六、组件数据存储

 在组件声明注册中使用

data() {       

  return {       

    title:'标题'

  }

}来为组件中的元素赋值

七、自制计数器组件 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <counter></counter>
</div>
<template id="counter">
  <div>
    <button @click="numSub">-</button>
    <span>{{number}}</span>
    <button @click="numAdd">+</button>
  </div>
</template>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    Vue.component('counter', {
      template:  `#counter`,
      data() {
        return {
          number: 0
        }
      },
      methods: {
        numSub() {
          if (this.number > 0) {
            this.number--
          }
        },
        numAdd() {
          this.number++
        }
      }
    })

  const app = new Vue({
      el: "#app",
      data: {

      }
    })
  </script>
</body>
</html>

八、插槽(slot)

组件的插槽

        组件的插槽是为了让我们封装的组件更加具有扩展性

        让使用者可以决定组件内部的一些内容到底展示什么 

1、为什么要使用插槽

类似下图中的导航栏,它们存在一定的共性,因此为了提高复用度,减少开发成本,应将其封装成一个组件;但是这些导航栏又有很多不同之处,例如后三个都有返回键,而第一个没有。因此就需要使用插槽来解决这一问题:完全相同部分封装进组件,不同的地方暴露为插槽。(抽取共性,保留不同)

2、插槽的使用

  • 将自定义的组件插入到插槽中  
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn><button>+</button></cpn>
  <cpn>0</cpn>
  <cpn><button>-</button></cpn>
  <cpn>总计</cpn>
 </div>
<template id="cpn">
  <div>
    <h2>我是组件</h2>
    <p>我是组件,哈哈哈</p>
    <slot></slot>
  </div>
</template>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    const cpn = {
      template: `#cpn`

    }

  const app = new Vue({
      el: "#app",
      data: {
        number: 10
      },
      components: {
        cpn
      }
    })
  </script>
</body>
</html>
  • 插槽也可以设置默认内容(例如京东例子,可以将导航栏左部默认设置为返回btn)
<slot><button>按钮</button></slot>
  • 当有多个插槽时需要为插槽设置名字
<div id="app">
  <cpn><span slot="up">上</span></cpn>
  <cpn></cpn>
  <cpn></cpn>
  <cpn><span slot="down">下</span></cpn>
 </div>
<template id="cpn">
  <div>
    <h2>我是组件</h2>
    <p>我是组件,哈哈哈</p>
    <slot name="up"><button>按钮</button></slot>
    <slot name="down"></slot>
  </div>
</template>
  • 作用域插槽
<div id="app">
  <cpn>
    <template slot-scope="slot">
      <span v-for="item in slot.data">{{item}}-</span>
    </template>
  </cpn>
 </div>

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

components: {
        cpn: {
          template: `#cpn`,
          data() {
            return {
              someMovies: ["星际穿越", "阿凡达", "大话西游", "实间管理局"]
            }
          }
        }
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值