Vuejs 组件

组件的基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- 3、使用组件,必须在Vue挂载实例中使用 -->
  <!-- 全局组件可以在任意Vue挂载实例中使用 -->
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
</div>

<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' })
</script>

</body>
</html>

注册局部组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- 3、使用组件,必须在Vue挂载实例中使用 -->
  <cpn></cpn>
  <cpn></cpn>
</div>

<div id="app2">
<!-- 局部组件在其他Vue挂载中无法使用 -->
  <cpn></cpn>
</div>

<script>
  // 1、创建组件构造器对象
  const cpnC = Vue.extend({
    // 代表自定义组件模板
    template: `
      <div>
        <h2>我是标题</h2>
        <p>我是内容1</p>
        <p>我是内容2</p>
      </div>
    `
  });

  const app = new Vue({ 
    el: '#app',
    
    // 局部组件
    // 2、注册组件
    components: {
      cpn:cpnC
    }
    });

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

</body>
</html>

父组件与子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- 使用组件 -->
  <cpn2></cpn2>
</div>

<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',
    components: {
      cpn2: cpnC2
    }
  })
</script>

</body>
</html>

注册组件语法糖

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- 使用组件 -->
  <global-tag></global-tag>
  <localtag></localtag>
</div>

<script>
  // 组件语法糖
  // 全局组件
  Vue.component('global-tag', {
    template: `
      <div>
        <h2>我是全局组件标题</h2>
        <p>我是内容。。。。。。</p>
      </div>
    `
  })

  // root组件
  const app = new Vue({
    el: '#app',
    components: {
      // 局部组件语法糖
      localtag: {
        template: `
          <div>
            <h2>我是局部组件标题</h2>
            <p>我是内容。。。。。。</p>
          </div>
        `
      }
    }
  })
</script>

</body>
</html>

组件模板分离的写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- 使用组件 -->
  <global-tag></global-tag>
  <localtag></localtag>
</div>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++ -->

<!-- 1.模板分离写法一: script标签,要注意类型 -->
<script type='text/x-template' id='cpn'>
  <div>
    <h2>我是全局组件标题</h2>
    <p>我是内容。。。。。。</p>
  </div>
</script>

<!-- 2.模板分离写法一: template标签 -->
<template id='cpn2'>
  <div>
    <h2>我是局部组件标题</h2>
    <p>我是内容。。。。。。</p>
  </div>
</template>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

<script>
  // 组件语法糖
  // 全局组件
  Vue.component('global-tag', {
    template: '#cpn'
  })

  // root组件
  const app = new Vue({
    el: '#app',
    components: {
      // 局部组件语法糖
      localtag: {
        template: '#cpn2'
      }
    }
  })
</script>

</body>
</html>

组件中数据存放

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- 使用组件 -->
  <global-tag></global-tag>
  <localtag></localtag>
</div>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++ -->

<!-- 组件模板分离 -->
<template id='cpn'>
  <div>
    <!-- 组件中数据存放 -->
    <h2>{{title}}</h2>
    <p>{{content}}</p>
  </div>
</template>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

<script>
  // 全局组件
  Vue.component('global-tag', {
    template: '#cpn',
    data() {
      return {
        title: "我是全局组件标题。。。",
        content: "我是全局组件的内容。。。。。。"
      }
    }
  })

  // root组件
  const app = new Vue({
    el: '#app',
    // 局部组件
    components: { 
      // 组件名
      localtag: {
        // 绑定的模板
        template: '#cpn',
        // 组件数据
        // data属性必须是一个函数,而且这个函数返回一个对象,对象内部保存着数据
        data() {
          return {
            title: '我是局部组件标题。。。',
            content: "我是局部组件的内容。。。。。。"
          }
        }
      }
    }
  })
</script>

</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- -----------使用组件----------------- -->
  <global-tag></global-tag>
  <global-tag></global-tag>
  <global-tag></global-tag>
</div>
<!-- ===================================== -->

<!-- -----------组件模板----------------- -->
<template id='cpn'>
  <div>
    <h2>当前计数:{{counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>
<!-- ======================================= -->

<script>
  // 全局组件
  Vue.component('global-tag', {
    template: '#cpn',
    data() {
      return {
        counter: 0
      }
    },
    methods: {
        increment(){
          this.counter++
        },
        decrement(){
          this.counter--
        }
    }
  })

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

</body>
</html>

父子组件的通信

父传子props

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id='app'>
  <!-- -----------使用组件----------------- -->
  <soncpn :smessage="message" :smovies='movies'></soncpn>
</div>
<!-- ===================================== -->

<!-- --------------组件模板----------------- -->
<template id='son-temp'>
  <div>
    <h2>{{smessage}}</h2>
    <p>{{smovies}}</p>
    <ul>
      <li v-for="item in smovies">{{item}}</li>
    </ul>
  </div>
</template>
<!-- ======================================= -->

<script>

  // 父传子:props
  const soncpn = {
    template: '#son-temp',
    // 数组写法
    // props: ['smessage', 'smovies'],

    // 对象写法:可以对数据进行类型限制
    // props: {
    //   smessage: String,
    //   smovies: Array
    // },

    // 对象写法:可以对数据提供一些默认值
    props: {
      smessage: {
        type: String,
        default: 'aaaa',
        // 表示必填的字符串
        // required: true
      },
      smovies: {
        // 类型是对象或者数组时,默认值必须是一个函数
        type: Array,
        default(){
          return ['1', '2', '3']
        }
      }
    }
  }

  // root组件
  const app = new Vue({ 
    el: '#app',
    data: {
      message: '电影清单',
      movies: ['如果可以重来', '高中时代', '初中的懵懂'],
    },
    components: {
      soncpn
    },
  })
</script>

</body>
</html>

子传父(自定义事件)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<!-- 父组件模板 -->
<div id='app'>
  <!-- 父组件监听发射过来的自定义事件 -->
  <h2>计数器:{{count}}</h2>
  <soncpn @increment="changeCount" @decrement='changeCount'></soncpn>
</div>
<!-- ===================================== -->

<!-- 子组件模板 -->
<template id='son-temp'>
  <div>
    <button @click='add(count)'>+</button>
    <button @click='sub(count)'>-</button>
  </div>
</template>
<!-- ======================================= -->

<script>
  // 子组件
  const soncpn = {
    template: '#son-temp',
    data() {
      return {
        count: 0
      }
    },
    methods: {
      add(count){
        // console.log(this.count++)
        // 向父组件发射一个自定义事件
        this.count++
        this.$emit('increment', this.count)
      },
      sub(){
        this.count--
        this.$emit('decrement', this.count)
      }
    }
  }

  // 父组件
  const app = new Vue({ 
    el: '#app',
    data: {
      count: 0
    },
    methods: {
      changeCount(count){
        this.count = count
      }
    },
    components: {
      soncpn
    },
  })
</script>

</body>
</html>

父组件访问子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<!-- 父组件模板 -->
<div id='app'>
  <soncpn></soncpn>
  <soncpn></soncpn>
  <soncpn></soncpn>
  <button @click='btnClick'>按钮</button>
</div>
<!-- ===================================== -->

<!-- 子组件模板 -->
<template id='son-temp'>
  <div>我是子组件</div>
</template>
<!-- ======================================= -->

<script>
  // 父组件
  const app = new Vue({ 
    el: '#app',
    data: {
      message: 'hello'
    },
    methods: {
      btnClick(){
        // 1、$children:获取所有子组件
        console.log(this.$children);
        this.$children[0].showMessage();
        console.log(this.$children[0].name)
      }
    },
    // 子组件
    components: {
      soncpn : {
        template: '#son-temp',
        data() {
          return {
            name : 'kuse'
          }
        },
        methods: {
          showMessage(){
            console.log("hi-------kuse")
          }
        }
      }
    },
  })
</script>

</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<!-- 父组件模板 -->
<div id='app'>
  <soncpn ref='aaa'></soncpn>
  <soncpn></soncpn>
  <soncpn></soncpn>
  <button @click='btnClick'>按钮</button>
</div>
<!-- ===================================== -->

<!-- 子组件模板 -->
<template id='son-temp'>
  <div>我是子组件</div>
</template>
<!-- ======================================= -->

<script>
  // 父组件
  const app = new Vue({ 
    el: '#app',
    data: {
      message: 'hello'
    },
    methods: {
      btnClick(){
        // 2、$refs: (获得指定子组件)对象类型,默认是一个空的对象 ref = '对象名'
        console.log(this.$refs);
        console.log(this.$refs.aaa);
        console.log(this.$refs.aaa.name);
        this.$refs.aaa.showMessage();
      }
    },
    // 子组件
    components: {
      soncpn : {
        template: '#son-temp',
        data() {
          return {
            name : 'kuse'
          }
        },
        methods: {
          showMessage(){
            console.log("hi-------kuse")
          }
        }
      }
    },
  })
</script>

</body>
</html>

插槽 slot

基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<!-- 父组件模板 -->
<div id='app'>
  <soncpn></soncpn>

  <soncpn>
    <!-- 插槽放在子组件标签内 -->
    <button>插槽</button>
  </soncpn>

  <soncpn>
    <span style="color:red">我是通过插槽插进来的</span>
  </soncpn>

  <soncpn>
    <!-- 子组件标签内有多个值时,都会替换 -->
    <p style="color:red">我是通过插槽插进来的--</p>
    <p style="color:red">我是通过插槽插进来的--</p>
    <p style="color:red">我是通过插槽插进来的--</p>
  </soncpn>

</div>
<!-- ===================================== -->

<!-- 子组件模板 -->
<template id='son-temp'>
  <div>
    <h1>子组件</h1>
    <div>我是子组件</div>
    <slot>
      <p>插槽的默认内容,当调用子组件没有添加插槽内容时,显示默认内容,如果自定义了插槽,则默认内容会被覆盖</p>
    </slot>
  </div>
</template>
<!-- ======================================= -->

<script>
  // 父组件
  const app = new Vue({ 
    el: '#app',
    data: {
      message: 'hello'
    },
    // 子组件
    components: {
      soncpn : {
        template: '#son-temp',
      },
    }
  })
</script>

</body>
</html>

具名插槽

  • 一个不带 name 的 < slot > 出口会带有隐含的名字“default”
  • 在向具名插槽提供内容的时候,我们可以在一个 < template > 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称
  • 现在 < template > 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 < template > 中的内容都会被视为默认插槽的内容
  • 然而,如果你希望更明确一些,仍然可以在一个 < template > 中包裹默认插槽的内容
  • 注意 v-slot 只能添加在 < template > 上
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<!-- 父组件模板 -->
<div id='app'>
  <soncpn>
    <template v-slot:left>
      <i>---左边---</i>
    </template>

    <template v-slot:default>
      <h1>---标题---</h1>      
    </template>


    <template v-slot:right>
      <b>---右边---</b>
    </template>
  </soncpn>
</div>
<!-- ===================================== -->

<!-- 子组件模板 -->
<template id='son-temp'>
  <div>
    <slot name='left'>
      <p>左边</p>
    </slot>

    <slot>
      <p>中间</p>
    </slot>

    <slot name='right'>
      <p>右边</p>
    </slot>
  </div>
</template>
<!-- ======================================= -->

<script>
  // 父组件
  const app = new Vue({ 
    el: '#app',
    data: {
      message: 'hello'
    },
    // 子组件
    components: {
      soncpn : {
        template: '#son-temp',
      },
    }
  })
</script>

</body>
</html>

插槽作用域

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vuejs</title>
    <script src="js/vue.js"></script>
</head>
<body>

<!-- 父组件模板 -->
<div id='app'>
  <soncpn></soncpn>

  <soncpn>
    <!-- 定义一个引用作用域名,并指向所引用的插槽对象 -->
    <template v-slot:default='slotProps'>
      <!-- 通过上面定义的作用域名来访问插槽原来数据 -->
      <span v-for='item in slotProps.data'>{{item}} ++ </span>
      <hr>
      <span>{{slotProps}}</span>
    </template>
  </soncpn>

</div>
<!-- ===================================== -->

<!-- 子组件模板 -->
<template id='son-temp'>
  <div>
    <!-- 为了codeLang在父级的插槽可用,我们将codeLang绑定到<slot>元素上 -->
    <!-- 绑定在<slot> 元素上的属性称为插槽props-->
    <!-- 这样我们在父级作用域中,我们就可以使用带值的v-slot来定义我们提供插槽props的名字 -->
    <slot :data='codeLang'>
      <ul>
        <li v-for="item in codeLang">{{item}}</li>
      </ul>
    </slot>
  </div>
</template>
<!-- ======================================= -->

<script>
  // 父组件
  const app = new Vue({ 
    el: '#app',
    // 子组件
    components: {
      soncpn : {
        template: '#son-temp',
        data(){
          return {
            codeLang : ['c', 'c++', 'java', 'python', 'js']
          }
        }
      },
    }
  })
</script>

</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值