组件化开发

组件的使用分为三个步骤

  1. 创建组件构造器
    调用Vue.extend()方法创建组件构造器
  2. 注册组件
    调用Vue.component()方法注册组件
  3. 使用组件
    在Vue实例的作用范围内使用组件

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    {{message}}
    <!--使用组件-->
    <my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
  //1.创建组件构造器对象
  const cnpC = 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: {
      message: '你好啊'
    }
  })
</script>
</body>
</html>

全局组件和局部组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
</head>
<body>
<div id="app">
    {{message}}
    <!--使用组件-->
    <my-cpn></my-cpn>
</div>
<div id="app2">
    <my-cpn></my-cpn>
</div>
<script src="js/vue.js"></script>
<script>
    //1.创建组件构造器对象
    const cpnC = Vue.extend({
        template: `
        <div>
          <h2>我是标题</h2>
          <p>我是内容1</p>
          <p>我是内容2</p>
        </div>`
    })
    //2.注册组件(全局组件,意味着可以在多个Vue的实例下面使用)
    Vue.component('my-cpn',cpnC)

    const app = new Vue({
        el: '#app',
        data: {
            message: '你好啊'
        },
        components: {
            //cpn使用组件时的标签名//2.注册组件(局部组件)
            cpn: cpnC
        }
    })
    const app2 = new Vue({
        el: '#app2',
    })
</script>
</body>
</html>

父组件和子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
</head>
<body>
<div id="app">
    {{message}}
    <!--使用组件-->
    <cpn2></cpn2>
</div>

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

    const app = new Vue({
        el: '#app',
        data: {
            message: '你好啊'
        },
        components: {
            //cpn使用组件时的标签名  注册组件(局部组件)
            cpn2: cpnC2
        }
    })
</script>
</body>
</html>

语法糖格式

语法糖注册全局组件

//2.注册组件(全局组件,意味着可以在多个Vue的实例下面使用)
    Vue.component('my-cpn', {
        template: `
        <div>
          <h2>我是标题</h2>
          <p>我是内容1</p>
          <p>我是内容2</p>
        </div>
        `
    })

语法糖注册局部组件

const app = new Vue({
        el: '#app',
        data: {
            message: '你好啊'
        },
        components: {
            'cpn2': {
                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="js/vue.js"></script>
<script>
    //2.注册组件(全局组件,意味着可以在多个Vue的实例下面使用)
    Vue.component('cpn', {
        template: `#cpn`
    })

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

组件数据存放问题

<!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>{{title}}</h2>
        <p>我是内容1</p>
        <p>我是内容2</p>
    </div>
</template>
<script src="js/vue.js"></script>
<script>
    //2.注册组件(全局组件,意味着可以在多个Vue的实例下面使用)
    Vue.component('cpn', {
        template: '#cpn',
        data() {
            return {
                title: 'abc'
            }
        }
    })

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

父子组件的通信

通过props向子组件传递
通过事件向父组件发送消息

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

<div id="app">
  <cpn :cmessage="message" :cmovies="movies"></cpn>
</div>
<template id="cpn">
  <div>
    <h2>{{cmovies}}</h2>
    <p>{{cmessage}}</p>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    // props: ['cmovies', 'cmessage'],
    props: {
      // 提供一些默认值和类型限制,以及必传值
      cmessage: {
        type: String,
        default: 'bbbb',
        required: true
      },
      // 当类型是对象或者数组时,默认值必须是一个函数
      cmovies: {
        type: Array,
        default() {
          return []
        }
      }
    },
    data() {
      return{}
    }
  }

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

</body>
</html>

props数据验证所支持的数据类型
在这里插入图片描述
当我们又自定义构造函数时,验证也支持自定义的类型
在这里插入图片描述
props的驼峰表示写法
在这里插入图片描述

子传父

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

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

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    data() {
      return{
        apps: [
          {id:'1',name:'学习强国'},
          {id:'2',name:'淘宝'},
          {id:'3',name:'知乎'},
          {id:'4',name:'抖音'}
        ]
      }
    },
    methods: {
      btnClick(item) {
        //发射事件
        this.$emit('btn-click',item)
      }
    }
  }

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

</body>
</html>

父子间通信结合双向绑定

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

<div id="app">
  <cpn :mesage1="message1"
       :mesage2="message2"
       @msg1change="msg1Change"
       @msg2change="msg2Change">
  </cpn>
</div>
<template id="cpn">
  <div>
    <h1>props:{{mesage1}}</h1>
    <h2>data:{{dmesage1}}</h2>
    <input type="text" :value="dmesage1" @input="msg1Input">
    <h1>props:{{mesage2}}</h1>
    <h2>data:{{dmesage2}}</h2>
    <input type="text" :value="dmesage2" @input="msg2Input">

  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    props: {
      mesage1: Number,
      mesage2: Number
    },
    data() {
      return{
        dmesage1:this.mesage1,
        dmesage2:this.mesage2
      }
    },
    methods: {
      msg1Input(event){
        // 将input中的value赋值到dnumber中
        this.dmesage1 = event.target.value;
        // 为了让父组件可以修改值,发出一个事件
        this.$emit('msg1change',this.dmesage1)

        // // 同时修改dmesage2的值
        // this.dmesage2 = this.dmesage1 * 100;
        // this.$emit('msg2change',this.dmesage2)
      },
      msg2Input(event){
        this.dmesage2 = event.target.value;
        this.$emit('msg2change',this.dmesage2)
        // // 同时修改dmesage1的值
        // this.dmesage1 = this.dmesage2 * 100;
        // this.$emit('msg1change',this.dmesage1)
      }
    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      message1: 1,
      message2: 2
    },
    components: {
      cpn
    },
    methods: {
      msg1Change(value){
        this.message1 = parseInt(value)
      },
      msg2Change(value){
        this.message2 = parseInt(value)
      }
    }
  })
</script>

</body>
</html>

父访问子的属性或方法children- refs

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

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

  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    data() {
      return{
        name:'我是子组件的name'
      }
    },
    methods: {
      showMessage(){
        console.log('showMessage');
      }
    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好'
    },
    components: {
      cpn
    },
    methods: {
      btnClick(){
        // 1、$children
        // console.log(this.$children);
        // for(let c of this.$children){
        //   console.log(c.name);
        //   c.showMessage();
        // }
        //2 $ ref
        console.log(this.$refs.aaa.name);
      }
    }
  })
</script>

</body>
</html>

子访问父组件的属性或方法

p a r e n t 访 问 父 组 件 用 parent访问父组件 用 parent访root访问根组件

插槽

(同一个组件显示不同数据)

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

<div id="app">
  <cpn></cpn>
  <cpn>aaa</cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>
<template id="cpn">
  <div>
    <h1>111</h1>
    <slot><button>按钮</button></slot>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    data() {
      return{
      }
    },
    methods: {
    }
  }

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

</body>
</html>

具名插槽的使用

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

<div id="app">
  <cpn><span slot="center">标题</span></cpn>
  <cpn><button slot="left">1</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 cpn = {
    template: '#cpn',
    data() {
      return{
      }
    },
    methods: {
    }
  }

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

</body>
</html>

什么是编译作用域

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

<div id="app">
  <cpn v-show="isShow"></cpn>
</div>
<template id="cpn">
  <div>
    <span v-show="isShow">左边</span>
    <span>中间</span>
    <span>右边</span>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    data() {
      return{
        isShow: false
      }
    },
    methods: {
    }
  }

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

</body>
</html>

作用域插槽的使用

父组件替换插槽的标签,但是内容由子组件来提供

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

<div id="app">
  <cpn></cpn>
  <cpn>
    <template slot-scope="slot">
      <span>{{slot.data.join(' - ')}}</span>
    </template>
  </cpn>
</div>
<template id="cpn">
  <div>
    <slot :data="pugs">
      <ul>
        <li v-for="i in pugs">{{i}}</li>
      </ul>
    </slot>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    data() {
      return{
        pugs:['java','c++','c#','javascript']
      }
    },
    methods: {
    }
  }

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

</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值