vue组件(prop+$emit()+slot)

164 阅读1分钟

全局组件:
Vue.component

Vue.component('my-component-name', {  // ... 选项 ... })

<div id="app"> <component-a></component-a> <component-b></component-b> <component-c></component-c> </div>
Vue.component('component-a', { /* ... */ })     
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ }) 
new Vue({ el: '#app' })

在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。

**局部组件: **

components

new Vue({  
el: '#app',
components: { 
     'component-a': ComponentA,
     'component-b': ComponentB 
 } 
   })

对于 components 对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象。注意局部注册的组件在其子组件中不可用

prop

HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名)

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="./js/vue.js"></script>
</head>

<body>
    <div id="app">
      <!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="传值"></blog-post>
    </div>
    <script>
       Vue.component('blog-post', {
        // 在 JavaScript 中是 camelCase 的
           props: ['postTitle'],
        template: '<h3>{{ postTitle }}</h3>'
})
        let vm = new Vue({
            el: "#app",
            data: {
               
            }
        })
    </script>
</body>

<html>

效果:

image.png
$emit()子组件向父组件传值:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="./js/vue.js"></script>
</head>

<body>
    <div id="app">
            <p>{{ val }}</p>
            <btn v-on:dj="djval"></btn><br/>
            <btn v-on:dj="djval"></btn>
          </div>
   
    <script>
   Vue.component('btn', {
  template: '<div><button v-on:click="jian">-</button>{{ counter }}<button v-on:click="jia">+</button></div>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
  jian:function(){
      this.counter-=1
      this.$emit('dj',1)
  },
  jia:function(){
    this.counter += 1
     this.$emit('dj',2)
  }


  },
})
new Vue({
  el: '#app',
  data: {
    val: 0
  },
  methods: {
    djval: function (v) {
        if(v==1){
            this.val -= 1
        }else{
            this.val += 1
        }
      
    }
  }
})
    </script>
</body>

<html>

效果:

image.png

slot插槽:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="./js/vue.js"></script>
</head>
<style>
    .zt-slot{
        font-size: 26px;
        color: red;
    }
    span{
        color: black;
    }
</style>
<body>
    <div id="app">
        <zt-slot>
            slot插入:
          </zt-slot>
    </div>
    <script>
        Vue.component('zt-slot', {
  template: `
    <div class="zt-slot">
    <slot></slot>
    
    <span>插入内容!</span>
    </div>
  `
})
        let vm = new Vue({
            el: "#app",
            data: {
               
            }
        })
    </script>
</body>

<html>

效果:

image.png