Vuejs另辟蹊径2(组件化)

组件化

什么是组件化

在这里插入图片描述

组件化思想

在这里插入图片描述

注册组件步骤

在这里插入图片描述

10-组件化开发

01-组件化的基本使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <!--3.使用组件-->
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>

  <div>
    <div>
      <my-cpn></my-cpn>
    </div>
  </div>
</div>

<my-cpn></my-cpn>

<script src="../js/vue.js"></script>
<script>
  // 1.创建组件构造器对象
  const cpnC = Vue.extend({
     
     
    template: `
      <div>
        <h2>我是标题</h2>
        <p>我是内容, 哈哈哈哈</p>
        <p>我是内容, 呵呵呵呵</p>
      </div>`
  })

  // 2.注册组件
  Vue.component('my-cpn', cpnC)

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

</body>
</html>

注册组件步骤解析

在这里插入图片描述

在这里插入图片描述

02-全局组件和局部组件

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

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

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

<script src="../js/vue.js"></script>
<script>
  // 1.创建组件构造器
  const cpnC = Vue.extend({
     
     
    template: `
      <div>
        <h2>我是标题</h2>
        <p>我是内容,哈哈哈哈啊</p>
      </div>
    `
  })

  // 2.注册组件(全局组件, 意味着可以在多个Vue的实例下面使用)
  // Vue.component('cpn', cpnC)

  // 疑问: 怎么注册的组件才是局部组件了?

  const app = new Vue({
     
     
    el: '#app',
    data: {
     
     
      message: '你好啊'
    },
    components: {
     
     // 相当于Vue.component('cpn', cpnC)
      // cpn使用组件时的标签名
      cpn: cpnC
    }
  })

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

</body>
</html>

03-父组件和子组件

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

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

<script src="../js/vue.js"></script>
<script>
  // 1.创建第一个组件构造器(子组件)
  const cpnC1 = Vue.extend({
     
     
    template: `
      <div>
        <h2>我是标题1</h2>
        <p>我是内容, 哈哈哈哈</p>
      </div>
    `
  })


  // 2.创建第二个组件构造器(父组件)
  const cpnC2 = Vue.extend({
     
     
    template: `
      <div>
        <h2>我是标题2</h2>
        <p>我是内容, 呵呵呵呵</p>
        <cpn1></cpn1>
      </div>
    `,
    components: {
     
     
      cpn1: cpnC1
    }
  })

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

</body>
</html>

04-组件的语法糖注册方式

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

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

<script src="../js/vue.js"></script>
<script>
  // 1.全局组件注册的语法糖
  // 1.创建组件构造器
  // const cpn1 = Vue.extend()

  // 2.注册组件
  Vue.component('cpn1', {
     
     
    template: `
      <div>
        <h2>我是标题1</h2>
        <p>我是内容, 哈哈哈哈</p>
      </div>
    `
  })

  // 2.注册局部组件的语法糖
  const app = new Vue({
     
     
    el: '#app',
    data: {
     
     
      message: '你好啊'
    },
    components: {
     
     
      'cpn2': {
     
     
        template: `
          <div>
            <h2>我是标题2</h2>
            <p>我是内容, 呵呵呵</p>
          </div>
    `
      }
    }
  })
</script>

</body>
</html>

05-组件模板的分离写法

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

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

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

<!--2.template标签-->
<template id="cpn">
  <div>
    <h2>我是标题</h2>
    <p>我是内容,呵呵呵</p>
  </div>
</template>

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

  // 1.注册一个全局组件
  Vue.component('cpn', {
     
     
    template: '#cpn'
  })

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

</body>
</html>

06-组件中的数据存放问题

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

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

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

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

<!--2.template标签-->
<template id="cpn">
  <div>
    <h2>{
   
   {title}}</h2>
    <p>我是内容,呵呵呵</p>
  </div>
</template>

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

  // 1.注册一个全局组件
  Vue.component('cpn', {
     
     
    template: '#cpn',
    data() {
     
     
      return {
     
     
        title: 'abc'
      }
    }
  })

  const app = new Vue({
     
     
    el: '#app',
    data: {
     
     
      message: '你好啊',
      // title: '我是标题'
    }
  })
</script>

</body>
</html>

07-组件中的data为什么是函数

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<!--组件实例对象-->
<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>当前计数: {
   
   {counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  // 1.注册组件
  const obj = {
     
     
    counter: 0
  }
  Vue.component('cpn', {
     
     
    template: '#cpn',
    // data() {
     
     
    //   return {
     
     
    //     counter: 0
    //   }
    // },
    data() {
     
     
      return obj
    },
    methods: {
     
     
      increment() {
     
     
        this.counter++
      },
      decrement() {
     
     
        this.counter--
      }
    }
  })

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

<script>
  // const obj = {
     
     
  //   name: 'why',
  //   age: 18
  // }
  //
  // function abc() {
     
     
  //   return obj
  // }
  //
  // let obj1 = abc()
  // let obj2 = abc()
  // let obj3 = abc()
  //
  // obj1.name = 'kobe'
  // console.log(obj2);
  // console.log(obj3);


</script>

</body>
</html>

08-组件通信-父组件向子组件传递数据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <!--<cpn v-bind:cmovies="movies"></cpn>-->
  <!--<cpn cmovies="movies" cmessage="message"></cpn>-->

  <cpn :cmessage="message" :cmovies="movies"></cpn>
</div>



<template id="cpn">
  <div>
    <ul>
      <li v-for="item in cmovies">{
   
   {item}}</li>
    </ul>
    <h2>{
   
   {cmessage}}</h2>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  // 父传子: props
  const cpn = {
     
     
    template: '#cpn',
    // props: ['cmovies', 'cmessage'],
    props: {
     
     
      // 1.类型限制
      // cmovies: Array,
      // cmessage: String,

      // 2.提供一些默认值, 以及必传值
      cmessage: {
     
     
        type: String,
        default: 'aaaaaaaa',
        required: true//true则表示此属性必传
      },
      // 类型是对象或者数组时, 默认值必须是一个函数
      cmovies: {
     
     
        type: Array,
        default() {
     
     
          return []
        }
      }
    },
    data() {
     
     
      return {
     
     }
    },
    methods: {
     
     

    }
  }

  const app = new Vue({
     
     
    el: '#app',
    data: {
     
     
      message: '你好啊',
      movies: ['海王', '海贼王', '海尔兄弟']
    },
    components: {
     
     
      cpn
    }
  })
</script>

</body>
</html>

09-组件通信-父传子(props中的驼峰标识)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn :c-info="info" :child-my-message="message" v-bind:class></cpn>
</div>

<template id="cpn">
  <div>
    <h2>{
   
   {cInfo}}</h2>
    <h2>{
   
   {childMyMessage}}</h2>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
     
     
    template: '#cpn',
    props: {
     
     
      cInfo: {
     
     
        type: Object,
        default() {
     
     
          return {
     
     }
        }
      },
      childMyMessage: {
     
     
        type: String,
        default: ''
      }
    }
  }

  const app = new Vue({
     
     
    el: '#app',
    data: {
     
     
      info: {
     
     
        name: 'why',
        age: 18,
        height: 1.88
      },
      message: 'aaaaaa'
    },
    components: {
     
     
      cpn
    }
  })
</script>

</body>
</html>

10-组件通信-子传父(自定义事件)

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<!--父组件模板-->
<div id="app">
  <cpn @item-click="cpnClick"></cpn>
</div>

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

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

  // 1.子组件
  const cpn = {
     
     
    template: '#cpn',
    data() {
     
     
      return {
     
     
        categories: [
          {
     
     id: 'aaa', name: '热门推荐'},
          {
     
     id: 'bbb', name: '手机数码'},
          {
     
     id: 'ccc', name: '家用家电'},
          {
     
     id: 'ddd', name: '电脑办公'},
        ]
      }
    },
    methods: {
     
     
      btnClick(item) {
     
     
        // 发射事件: 自定义事件
        this.$emit('item-click', item)
      }
    }
  }

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

</body>
</html>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40649503/article/details/111282236