Vuejs组件化开发

01-组件化开发

01-组件化开发的基本使用

组件使用的三个步骤:

  • 创建组件构造器
  • 注册组件
  • 使用组件
<div id="app">
<!--  3 使用组件-->
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
</div>

<script src="../js/vue.js"></script>
<script>
  //1 创建组件构造器对象
  const cpnC = Vue.extend({
     
     
    template: `
      <div>
        <h2>我是标题</h2>
        <p>我是内容</p>
        <p>我是内容 123</p>
      </div>`
  })
  //2 注册组件
  Vue.component('my-cpn',cpnC)
  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!'
    }
  })
</script>

02-全局组件和局部组件

使用Vue.component()进行组件注册,此时注册的为全局组件;

而在Vue中components下注册的则是局部组件;

<!-- 组件的使用 -->
<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

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

  const cpnC = Vue.extend({
     
     
    template:`
      <div>
        <h2>我是标题</h2>
        <p>我是内容 12323456</p>
      </div>
    `
  })
  // 注册组件是全局组件,可以在多个vue实例下面使用
  Vue.component('cpn',cpnC)

  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!'
    },
    components:{
     
     
      // 局部组件的注册
      cpn: cpnC  //cpn 使用组件的标签名   cpnC 组件构造器
    }
  })
</script>

03-父组件和子组件

<!-- 组件的使用-->
<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>我是内容123456</p>
    </div>
    `
  })
  //创建第二个组件(父组件)
  const cpnC2 = Vue.extend({
     
     
    template:`
    <div>
      <h2>我是标题2</h2>
      <p>我是内容,abcdef</p>
      <cpn1></cpn1>
    </div>
    `,
    components: {
     
     
      //注册组件cpn1为cpn2的子组件
      cpn1: cpnC1
    }
  })
  //root组件
  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!' 
    },
    components:{
     
     
      //注册组件cpn2,cpn1
      cpn2: cpnC2,
      cpn1: cpnC1
    }
  })
</script>

将组件cpn1注册为cpn2的子组件,在cpn2的组件创建时可以使用组件cpn1;

将cpn1和cpn2都在vue中注册,则在组件使用时这两个组件均可使用。

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

组件的语法糖注册方式中将不再使用Vue.extend()来创建组件,而是将注册组件和创建组件都放在Vue.component()下。

<!--组件的使用-->
<div id="app">
  <cpn1></cpn1>
  <cpn2></cpn2>
</div>

<script src="../js/vue.js"></script>
<script>
  // 全局组件(语法糖方式):
  // 1 创建组件构造器
  //2 注册组件
  Vue.component('cpn1',{
     
     
    template:`
    <div>
      <h2>我是标题1</h2>
      <p>我是内容123456</p>
    </div>
    `
  })
  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!'
    },
    components:{
     
     
      'cpn2':{
     
     
        template:`
          <div>
            <h2>我是标题2</h2>
            <p>我是内容123456</p>
          </div>
        `
      }
    }
  })
</script>

05-组件模块的分离写法

在注册时template仅声明id序号,组件模板写在注册外面。

1、通过script标签

<script type="text/x-template" id="cpn">
<div>
  <h2>我是标题</h2>
  <p>我是内容 123456</p>
</div>
</script>

2、通过template标签

扫描二维码关注公众号,回复: 12963073 查看本文章
<template id="cpn">
  <div>
    <h2>我是标题</h2>
    <p>我是内容 12345</p>
  </div>
</template>

完整代码:

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

<!--1 通过script 标签 -->
<script type="text/x-template" id="cpn1">
<div>
  <h2>我是标题</h2>
  <p>我是内容 123456</p>
</div>
</script>

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

<script src="../js/vue.js"></script>
<script>
  // 1 注册一个全局组件
  Vue.component('cpn1',{
     
     
    template:'#cpn1'
  })
  Vue.component('cpn2',{
     
     
    template:'#cpn2'
  })
  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!'
    }
  })
</script>

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

组件中数据存放,需要写在注册组件时,即Vue.component()中,其data是函数,需要返回值。

<script>
// 1 注册一个全局组件
  Vue.component('cpn',{
     
     
    template:'#cpn',
    //组件数据存放
    data(){
     
     
      return {
     
     
        title:'123'
      }
    }
  })
</script>

完整代码:

<!-- 组件使用-->
<div id="app">
  <cpn></cpn>
</div>
<!-- 组件内容-->
<template id="cpn">
  <div>
    <h2>{
   
   {title}}</h2>
    <p>我是内容 12345</p>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  // 1 注册一个全局组件
  Vue.component('cpn',{
     
     
    template:'#cpn',
    //组件数据存放
    data(){
     
     
      return {
     
     
        title:'123'
      }
    }
  })
  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!'
    }
  })
</script>

07-组件通信-父组件向子组件传递参数

通过props向子组件传递数据,props声明在Vue.component()中,是一个对象;

<div id="app">
  <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
  <div>
    <h2>{
   
   {cmessage}}</h2>
    <ul>
      <li v-for="item in cmovies">{
   
   {item}}</li>
    </ul>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  //父传子:props
  const cpn = {
     
     
    template:'#cpn',
    //1 类型的限制
    // props:['cmovies','cmessage'],
    props:{
     
     
      cmovies: {
     
     
        type: Array,
        default(){
     
     
          return []
        }
      },
      cmessage: {
     
     
        type: String,
        default: '123456',
        required: true
      },
    },
    data(){
     
     
      return{
     
     }
    },
    methods:{
     
     
    }
  }
  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!',
      movies:['123','456','789']
    },
    components:{
     
     
      cpn
    }
  })
</script>

08-组件通信-子组件向父组件传递事件

通过事件,子组件向父组件传送信息。

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

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

<script src="../js/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('item-click',item)
      }
    }
  }
  //父组件
  const app = new Vue({
     
     
    el:'#app',
    data:{
     
     
      message:'你好啊!'
    },
    components:{
     
     
      cpn,
    },
    methods: {
     
     
      //父组件接受
      cpnClick(item){
     
     
        console.log('cpnClick',item)
      }
    }
  })
</script>

【界面交互展示】
在这里插入图片描述
数据保存在父组件中,按钮为子组件,点击按钮,监听按钮的事件传到父组件中,父组件接受事件,通过在控制台打印,证明父组件确实接收到了来自子组件的信息。

09-组件访问-父访问子-children-refs

1、使用children进行访问,此访问只能通过下标获取数据;

2、使用refs来访问,通过定义refs来获取数据;

<div id="app">
  <cpn ref="aaa"></cpn>
  <cpn ref="bbb"></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);
        // this.$children[0].showMessage();
        // 2 $refs
        console.log(this.$refs.aaa);
        console.log(this.$refs.bbb)
      }
    },
    components:{
     
     
      cpn:{
     
     
        template:'#cpn',
        methods: {
     
     
          showMessage(){
     
     
            console.log('showMessage');
          }
        }
      },
    }
  })
</script>

10-组件访问-子访问父-parent-root

1、parent访问父组件(上一级);

2、root访问根组件;

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

<template id="cpn">
  <div>
    <h2>我是cpn组件</h2>
    <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',
        components: {
     
     
          ccpn:{
     
     
            template: '#ccpn',
            data(){
     
     
              return {
     
     
                name: '我是子组件cpn的name'
              }
            },
            methods:{
     
     
              btnClick(){
     
     
                //1 访问父组件$parent
                // console.log(this.$parent);
                // console.log(this.$parent.name);

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

02-插槽slot

01-插槽的基本使用

预留插槽,使用时在自定义标签中添加标签来替代预留插槽,若不再添加标签,则预留插槽会显示默认标签;

<div id="app">
  <cpn><button>按钮</button></cpn>
  <cpn><span>哈哈哈</span></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>我是组件</h2>
    <p>我是组件123456</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>

【页面分析】

在这里插入图片描述

02-具名插槽的使用

在slot标签中添加name属性,用来表明替换位置;

<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>

【界面分析】

在这里插入图片描述

03-作用域插槽

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

  <cpn>
    <template slot-scope="slot">
      <span v-for="item in slot.data">{
   
   {item}}-</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++','Java','Python','Go','Swift']
          }
        }
      }
    }
  })
</script>

03-ES6模块化开发

aaa.js

var name = '小明'
var age = 18
var flag = true

function sum(num1,num2) {
    
    
  return num1 + num2
}

if(flag){
    
    
  console.log(sum(20,30))
}
// 导出方式1
export {
    
    
  flag,sum
}
// 导出方式2
export var num1 = 1800
export var height = 1.88

// 导出函数/类
export function mul(num1,num2) {
    
    
  return num1 * num2
}

export class Person {
    
    
  run(){
    
    
    console.log('在奔跑');
  }
}

//export default
//某些情况下,一个模块中包含某个功能,我们并不希望给这个功能命名,而是让导入者可以自己来命名,这个时候就可以使用export default
// const address = '北京市';
// export default address;

export default function (argument) {
    
    
  console.log(argument);
}

bbb.js

import {
    
    sum}from'./aaa.js'
var name = '小红'
var flag = false
console.log(sum(20, 50));

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<script src="aaa.js" type="module"></script>
<script src="bbb.js" type="module"></script>
<script src="mmm.js" type="module"></script>
</body>
</html>

mmm.js

import {
    
    flag,sum} from "./aaa.js";

if(flag){
    
    
  console.log('小明是天才,哈哈哈');
  console.log(sum(20, 30));
}

import {
    
    num1,height} from "./aaa.js";
console.log(num1);
console.log(height);


import {
    
    mul,Person} from "./aaa.js";
console.log(mul(12,23));
p.run();

//导入export default的内容
import addr from './aaa.js'
addr('你好啊!');

//导入全部内容
import * as aaa from './aaa.js'
console.log(aaa.flag);
console.log(aaa.height);

猜你喜欢

转载自blog.csdn.net/gets_s/article/details/113776463