Vue学习----第三天_组件化开发【6.3】

一、认识组件化
1、什么是组件化

在这里插入图片描述

2.Vue组件化思想

在这里插入图片描述

二、注册组件
1.注册组件的基本步骤

在这里插入图片描述
代码如下:

<div id='app'>
    <my-cpn></my-cpn>
  </div>

  <script src='./js/vue.js'></script>
  <script>
    // 1.创建组件构造器对象
    const cpnC = Vue.extend({
      // 字符串语法 tab键上面
      template: `
      <div>
        <h2>标题</h2>
        <p>内容</p>
        <p>结尾</p>
      </div>
      `
    })
    // 2.注册组件
    Vue.component('my-cpn', cpnC)

    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      }
    })
  </script>

效果如下:
在这里插入图片描述

2.注册组件步骤解析

在这里插入图片描述
在这里插入图片描述

三、组件其他补充
1.全局组件和局部组件

在这里插入图片描述
代码如下:

<div id='app'>
    <my-cpn></my-cpn>
    <my-all></my-all>
  </div>

  <script src='./js/vue.js'></script>
  <script>

    const cpn = Vue.extend({
      template: `
      <div>
        <h2>头部</h2>
        <h2>尾部</h2>
      </div>
      `
    })
    // 1.全局组件:意味着可以在多个Vue的实例下面使用
    Vue.component('my-cpn', cpn)

    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      // 2.局部注册组件
      components: {
        'my-all': cpn
      }
    })
  </script>

效果如下:
在这里插入图片描述

2.父组件和子组件

在这里插入图片描述
代码如下:

  <div id='app'>
    <!-- <cpn1></cpn1> -->
    <cpn2></cpn2>
  </div>

  <script src='./js/vue.js'></script>
  <script>

    // 1.创建第一个组件 子组件
    const cpnc1 = Vue.extend({
      template: `
      <div>
        <h2>标题</h2>
        <h2>内容</h2>
      </div>
      `
    })
    // 2.创建第二个组件 父组件
    const cpnc2 = Vue.extend({
      template: `
      <div>
        <h2>标题2</h2>
        <h2>内容2</h2>
        <cpn1></cpn1>
      </div>
      `,
      components: {
        cpn1: cpnc1
      }
    })

    // root组件
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      components: {
        cpn2: cpnc2,
      }
    })
  </script>

效果如下:
在这里插入图片描述

3.注册组件语法糖

在这里插入图片描述
代码如下:

  <div id='app'>
    <cpn1></cpn1>
    <cpn2></cpn2>
  </div>

  <script src='./js/vue.js'></script>
  <script>
    // 1.全局组件注册的语法糖
    Vue.component('cpn1', {
      template: `
      <div>
        <h2>标题</h2>
        <h2>内容</h2>
      </div>
      `
    })

    // 2.局部组件注册的语法糖
    const cpn2 = {
      template: `
      <div>
        <h2>标题2</h2>
        <h2>内容2</h2>
      </div>
      `
    }

    const app = new Vue({
      el: '#app',
      data: {},
      components: {
        'cpn2': cpn2
      }
    })
  </script>

效果如下:
在这里插入图片描述

4.模板分离写法

在这里插入图片描述
代码如下:

  <div id='app'>
    <cpn></cpn>
    <cpn2></cpn2>
  </div>

  <!-- 1.通过script标签,注意:类型必须为text/x-template -->
  <script type="text/x-template" id="cpn">
    <div>
      <h2>标题</h2>
      <p>内容</p>
    </div>
  </script>

  <!-- 2.template标签 -->
  <template id="cpn2">
    <div>
      <h2>标题cpn2</h2>
      <p>内容cpn2</p>
    </div>
  </template>

  <script src='./js/vue.js'></script>
  <script>
    // 注册全局组件
    Vue.component('cpn', {
      template: '#cpn'
    })
    Vue.component('cpn2', {
      template: '#cpn2'
    })

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

效果如下:
在这里插入图片描述

四、组件数据存放
1.组件可以访问Vue实例数据吗?

在这里插入图片描述

2.组件数据存放

在这里插入图片描述

3.为什么组件中data是一个函数?

在这里插入图片描述

五、父子组件的通信
1.父子组件的通信

在这里插入图片描述

2.父向子传递数据—props
  1. props基本用法
    在这里插入图片描述代码如下:
  <div id='app'>
    <children :movies="movies" :message="message"></children>
  </div>

  <template id="children">
    <div>
      <ul>
        <li :key="index" v-for="(item, index) in movies">{{item}}</li>
      </ul>
      <h2>{{message}}</h2>
    </div>
  </template>
  <script src='./js/vue.js'></script>
  <script>
    // 父传子  props
    const children = {
      props: ['movies', 'message'],
      template: '#children'
    }

    const app = new Vue({
      el: '#app',
      data: {
        message: '你好',
        movies: ['大娃', '二娃', '三娃', '四娃']
      },
      components: {
        children
      }
    })
  </script>
  1. props数据验证
    在这里插入图片描述
    代码如下:
const children = {
  template: '#children',
  // props: ['movies', 'message'],
  props: {
    // 1.类型限制
    // movies: Array,
    // message: String

    // 2.提供一些默认值,没传入时显示
    message: {
      type: String,
      default: 'aaaa',
      // 表示使用时,必须传值,否则报错
      required: true
    },
    movies: {
      type: Array,
      // 类型是对象或者数组时,默认值必须是一个函数
      // 以下两种写法都可以,但是 直接default:[]对vue版本支持不同
      // default: [],
      default() {
        return []
      },
      // 表示使用时,必须传值,否则报错
      required: true
    }
  }
}
  1. props中驼峰标识
    总结:在Vue实例data中定义的数据名若为驼峰命名,则在数据绑定时改为以横线分割的字符串:
    infoMessageinfo-message
    代码图片如下:着重看红色框框中的代码
    在这里插入图片描述
3.子向父传递数据—自定义事件

在这里插入图片描述
在这里插入图片描述
效果如下:
在这里插入图片描述

六、父子组件的访问
1.父子组件的访问方式:$children

在这里插入图片描述
代码如下:

  <div id='app'>
    <cpn ref="aaa"></cpn>
    <cpn></cpn>
    <cpn></cpn>
    <button @click="btnClick">按钮</button>
  </div>

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

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      methods: {
        btnClick() {
          // 1.通过children方式
          console.log(this.$children[0].showMessage)
          console.log(this.$children[0].name)
        }
      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              name: '子组件的name'
            }
          },
          methods: {
            showMessage() {
              console.log('showMessage')
            }
          }
        }
      }
    })
  </script>
2.父子组件的访问方式:$refs ★★★★★

在这里插入图片描述
代码如下:

  <div id='app'>
    <cpn ref="aaa"></cpn>
    <cpn></cpn>
    <cpn></cpn>
    <button @click="btnClick">按钮</button>
  </div>

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

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      methods: {
        btnClick() {
          // 2.通过$refs方式★★★
          // 需要在自定义组件中加上 ref 属性
          console.log(this.$refs.aaa.name)
        }
      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              name: '子组件的name'
            }
          },
          methods: {
            showMessage() {
              console.log('showMessage')
            }
          }
        }
      }
    })
  </script>
3.子访问父-访问方式:$parent或 $root

$parent:用来访问父组件
$root:用来访问根组件
在这里插入图片描述
代码如下:

  <div id='app'>
    <h2>子组件</h2>
    <cpn></cpn>
  </div>

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

  <!-- 孙组件 -->
  <template id="ccpn">
    <div>
      <h2>我是子-孙组件</h2>
      <button @click="btnClick">按钮</button>
    </div>
  </template>

  <script src='./js/vue.js'></script>
  <script>
    // 根组件
    const app = new Vue({
      el: '#app',
      data: {
        message: '根组件'
      },
      // 子组件
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              name: '子组件'
            }
          },
          // 孙组件
          components: {
            ccpn: {
              template: '#ccpn',
              methods: {
                btnClick() {
                  // 1.子访问父$parent
                  console.log(this.$parent)
                  console.log(this.$parent.name)

                  // 2.访问根组件$root
                  console.log(this.$root.message)
                }
              },
            }
          }
        }
      }
    })
  </script>

效果如下:
在这里插入图片描述

4.非父子组件传值

在这里插入图片描述
代码如下:

  <div id="app">
    <test-tom></test-tom>
    <test-joy></test-joy>
    <button @click='handle'>销毁事件</button>
  </div>
  <script src="../vue.js"></script>
  <script>
    // 提供事件中心
    var hub = new Vue();
    Vue.component('test-tom', {
      data: function () {
        return {
          num: 0
        }
      },
      template: `
        <div>
            <div>tom:{{num}}</div>
            <button @click='handle'>点击</button>
        </div>
      `,
      methods: {
        handle: function () {
          // 触发兄弟组件的事件
          hub.$emit('joy-event', 2);
        }
      },
      mounted: function () {
        //监听事件,钩子函数
        hub.$on('tom-event', (val) => {
          // val是兄弟组件传递过来的
          this.num += val;
        });
      }
    })
    Vue.component('test-joy', {
      data: function () {
        return {
          num: 0
        }
      },
      template: `
        <div>
            <div>joy:{{num}}</div>
            <button @click='handle'>点击</button>
        </div>
      `,
      methods: {
        handle: function () {
          hub.$emit('tom-event', 1);
        }
      },
      mounted: function () {
        //监听事件,钩子函数
        hub.$on('joy-event', (val) => {
          // val是兄弟组件传递过来的
          this.num += val;
        });
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        handle: function () {
          hub.$off('tom-event');
          hub.$off('joy-event');
        }
      }
    })
  </script>
七、插槽slot
1.为什么使用slot

在这里插入图片描述

2.如何封装这类组件

在这里插入图片描述

3.slot基本使用

在这里插入图片描述
代码如下:

  <!-- 1.插槽基本使用,定义slot标签 -->
  <!-- 2.插槽默认值,slot标签内的内容 -->
  <!-- 3.多个值,同时放入组件中进行替换,一起作为替换元素 -->
  <div id='app'>
    <cpn><button>按钮</button></cpn>
    <cpn></cpn>
    <cpn></cpn>
  </div>

  <template id="cpn">
    <div>
      <h2>我是组件</h2>
      <p>我是组件,哈哈哈</p>
      <!-- 如果组件没有内容,默认显示 -->
      <slot><button>默认按钮</button></slot>
    </div>
  </template>

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      components: {
        cpn: {
          template: '#cpn'
        }
      }
    })
  </script>

效果如下:
在这里插入图片描述

4.具名插槽slot

在这里插入图片描述
代码如下:

  <div id='app'>
    <cpn><span slot="center">标题</span></cpn>
    <cpn><button slot="left">返回</button></cpn>
  </div>

  <template id="cpn">
    <div>
      <slot name="left"><span>左边</span></slot>
      <slot name="center"><span>中间</span></slot>
      <slot name="right"><span>右边</span></slot>
    </div>
  </template>

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      components: {
        cpn: {
          template: '#cpn'
        }
      }
    })
  </script>

效果如下:
在这里插入图片描述

5.编译作用域

在这里插入图片描述
代码如下:

  <div id='app'>
    <cpn v-show="isShow"></cpn>
  </div>

  <template id="cpn">
    <div>
      <h2>我是子组件</h2>
      <p>我是内容</p>
      <button v-show="isShow"></button>
    </div>
  </template>

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好',
        isShow: true
      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              isShow: false
            }
          }
        }
      }
    })
  </script>

效果如下:
在这里插入图片描述

6.作用域插槽:准备

在这里插入图片描述

7.作用域插槽:使用

在这里插入图片描述
代码如下:

  <div id='app'>
    <cpn></cpn>
    <cpn>
      <!-- 目的是获取子组件中的数据 -->
      <template slot-scope="slot">
        <!-- <span v-for="item in slot.data">{{item}}、</span> -->
        <span>{{slot.data.join('、')}}</span>
      </template>
    </cpn>
  </div>

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

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好'
      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              pLanguages: ['JavaScript', 'c++', 'python', 'Go', 'Java', 'c#']
            }
          }
        }
      }
    })
  </script>

效果如下:
在这里插入图片描述

内容持续更新中…
lvan学习笔记-文章内容仅个人观点
2020.6.3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值