vue组件

目录

一、vue组件概念

二、组件的基础使用

三、组件name属性使用

四、组件通信-父传子

五、修改父传入的数据-自定义事件

六、组件通信-EventBus

七、动态dynamic组件使用

八、组件缓存

九、组件激活和非激活

十、组件插槽

十一、具名插槽

十二、作用域插槽


一、vue组件概念

  • 组件是可复用的Vue实例,封装标签,样式和JS代码
  • 组件化:封装的思想,把页面上“可重用的部分”封装为“组件”,从而方便项目的开发和维护
  • 一个页面,可以拆分成一个个组件,一个组件就是一个整体,每个组件可以有自己独立的结构样式和行为(html,css和js)
  • 每个组件都是一个独立的个体,代码里体现为一个独立的.vue文件

二、组件的基础使用

1.创建组件:封装要复用的标签、样式、JS代码(创建.vue文件)

2.引入组件:(语法:import 组件名 from .vue文件路径)

3.注册组件

全局注册 - main.js中

  • 语法:Vue.component("组件名","组件对象")

局部注册 - 某.vue文件内

4.使用组件

语法:

<组件名></组件名>

代码示例:

(1)全局注册

main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
// 全局注册
// 1. 创建组件 - Demo.vue
// 2. 引入组件 
import Demo from './components/Demo'
// 3. 注册组件 - 全局
Vue.component("Demo", Demo)
new Vue({
  render: h => h(App),
}).$mount('#app')

App.vue
<template>
  <div>
    <!-- 4. 使用组件 -->
    <Demo></Demo>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

(2)局部注册

<template>
  <div>
    <!-- 4. 使用组件 -->
    <Demo></Demo>
  </div>
</template>

<script>
// 局部注册
// 1. 创建组件 - Demo.vue
// 2. 引入组件
import Demo from './components/Demo.vue'
export default {
  // 3. 注册组件
  /* 语法:
    components: {
      "组件名": 组件对象
    }
  */
 components: {
   "Demo": Demo
  }
}
</script>

<style>

</style>

三、组件name属性使用

1.组件定义name属性和值

2.注册组件可用上面name的值

四、组件通信-父传子

  • 父(App.vue)
  • 子(MyProduct.vue)

代码示例:

MyProduct.vue

<template>
  <div class="my-product">
    <!-- (1)定义变量 -->
    <h3>标题:{{title}}</h3>
    <p>价格:{{price}}</p>
    <p>{{info}}</p>
  </div>
</template>

<script>
export default {
    // (2)props准备接收
    props:['titile','price','info']
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

App.vue

<template>
  <div>
    <!-- (3)使用变量 -->
    <Product title="好吃的汉堡包" price="20" info="新店开张,全场买一送一!"></Product>
    <Product title="好吃的肯德基" price="50" info="疯狂星期四!"></Product>
    <Product title="好吃的热狗" price="6" info="第二根半价!"></Product>
  </div>
</template>

<script>
// 1. 创建组件(.vue文件)
// 2. 引入组件
import Product from './components/MyProduct.vue'
export default {
  // 3. 注册组件
  components:{
    // Product: Product key和value同名可以简写 Product
    Product
  }
}
</script>

<style>

</style>

五、修改父传入的数据-自定义事件

        从父到子的数据流向,叫做单向数据流。而子组件修改父级传过来的数据,不通知父级,就会造成数据不一致性。且Vue规定props里的变量,本身是只读的,不能修改。那么子组件如何才能修改父组件里的数据呢?

子传父如何实现?

  • 父组件内,给组件@自定义事件="父methods函数"
  • 组件内,恰当时机this.$emit('自定义事件名', 值)

App.vue

<template>
    <div>
        <!-- 
          3.父组件内,绑定自定义事件和事件处理函数
          语法:@自定义事件="父methods函数"
            -->
    <Product v-for="(item,index) in list" :key="index"
    :title="item.title"
    :price="item.price"
    :info="item.info"
    :index="index"
    @subprice="fn"></Product>
    </div>
</template>

<script>
import Product from './components/MyProduct.vue'
export default {
    data(){
        return{
            list:[{title:"好吃的汉堡包",price:20,info:"新店开张,全场买一送一!"},
                  {title:"好吃的肯德基",price:50,info:"新店开张,全场买一送一!"},
                  {title:"好吃的热狗",price:6,info:"新店开张,全场买一送一!"}
            ]
        }
    },
    components: {
        Product
    },
    methods:{
        // 4.事件处理函数
        fn(index, price) {
           this.list[index].price > 1 && (this.list[index].price = (this.list[index].price - price).toFixed(2))
        }
    }
}
</script>

<style>

</style>

MyProduct.vue

<template>
  <div class="my-product">
    <h3>标题:{{title}}</h3>
    <p>价格:{{price}}</p>
    <p>{{info}}</p>
    <p>
      <!-- 1.给砍价按钮绑定点击事件 -->
      <button @click="kanjia">砍价</button>
    </p>
  </div>
</template>

<script>
export default {
    props:['index','title','price','info'],
    methods:{
      kanjia(){
        // 2.this.$emit()规定方法,主动触发父给我绑定的自定义事件,导致父methods里的事件处理函数执行
        this.$emit('subprice',this.index,1)
      }
    }
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

六、组件通信-EventBus

场景:当2个没有引用关系的组件之间需要通信

技术本质:空白Vue对象,只负责$on和$emit

语法:

  • src/EventBus/index.js 创建空白Vue对象并导出
  • 在要接收值的组件:eventBus.$on('事件名', 函数体)
  • 在要传递值的组件:eventBus.$emit('事件名', 值)

传递方:

<script>
// 跨组件传值-传递方
// 1.引入空白vue对象(EventBus)
import eventBus from '../EventBus'
export default {
    methods:{
        // 2.传递方-$emit触发事件,语法:eventBus.$emit('事件名', 值)
        fn(){
            eventBus.$emit('send',this.index, this.price)
        }
    }
}
</script>

接收方:

<script>
// 跨组件传值
// 1.引入空白vue对象(EventBus)
import eventBus from '../EventBus'
export default {
    props:['arr'],
    // 2.接收方-$on监听事件,语法:eventBus.$on('事件名', 函数体)
    created(){
        eventBus.$on('send',(index, price)=> {
           //   函数体
        })
    }
}
</script>

七、动态dynamic组件使用

作用:在同一个挂载点,可以切换展示不同组件

语法:vue的内置componment组件,配合is属性

<component :is="变量"> </component> // 改变is属性的值,为要显示的组件名即可

场景:切换2个组件,互斥的显示或隐藏

代码示例:

App.vue

<template>
  <div>
      <button @click="userNameFn">账号密码填写</button>
      <button @click="userInfoFn">个人信息填写</button>

      <p>下面显示注册组件-动态切换:</p>
      <div style="border: 1px solid red;">
	  <!-- vue内置的组件component,可以动态显示组件 -->
          <component :is="ComName"></component>
      </div>
  </div>
</template>

<script>
// 动态组件 - 切换组件显示
// 场景:同一个挂载点要切换 不同组件 显示
// 1.创建要被切换的组件
// 2.引入到要展示的vue文件内,注册
// 3.变量-承载要显示的组件名
// 4.设置挂载点<component :is="变量"> </component>
// 5.点击按钮-切换comName的值要显示的组件名
import UserName from './demo/UserName.vue'
import UserInfo from './demo/UserInfo.vue'
export default {
    data(){
        return{
           ComName:"UserName"
        }
    },
    methods:{
        userNameFn(){
            this.ComName = "UserName"
        },
        userInfoFn(){
            this.ComName = "UserInfo"
        }
    },
    components:{
        UserName,
        UserInfo
    },
   
}
</script>

<style>

</style>

UserName.vue 

<template>
  <div>
      <div>
          <span>用户名:</span>
          <input type="text">
      </div>
      <div>
          <span>密码:</span>
          <input type="password">
      </div>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

UserInfo.vue

<template>
  <div>
      <div>
          <span>人生格言:</span>
          <input type="text">
      </div>
      <div>
          <span>自我介绍</span>
          <input type="text">
      </div>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

 注意点:

  • 频繁的切换回导致组件频繁创建和销毁,性能会降低。解决方案为:组件缓存

八、组件缓存

作用:不会频繁的创建和销毁组件,页面呈现更快

语法:vue内置的keep-alive组件,包起来要频繁切换的组件

<keep-alive>

<component :is="ComName"></component>

</keep-alive>

九、组件激活和非激活

问题:如何知道组件被切走了,还是切换回来了

方法名:

  • activated:激活时触发
  • deactivated:失去激活状态触发

十、组件插槽

作用:通过slot标签,让组件内可以接收不同的标签结构显示

语法口诀:

  • 组件内使用<slot></solt>占位
  • 使用组件时<Pannel></Pannel>夹着的地方,传入标签替换slot

代码示例:

App.vue

<template>
<div>
    <!-- 2.使用组件,传入具体的标签进行替换到slot位置上 -->
    <SlotDemo>
        <span>组件插槽</span>
    </SlotDemo>
    <UserInfo>
        <input type="text">
    </SlotDemo>
    <SlotDemo>
        <img src="./assets/images.jpg" alt="">
    </SlotDemo>
</div>
</template>

<script>
import SlotDemo from './demo/SlotDemo.vue'
export default {
    components:{
        SlotDemo
    }
}
</script>

<style>

</style>

 Slot.vue

<template>
  <div>
    <!-- 1.组件内使用<slot></slot> 占位 -->
     <slot></slot>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

十一、具名插槽

作用:slot占位,给name属性起名字来区分

场景:一个组件内有2处以上需要外部传入标签的地方

语法:

  • template配合v-slot:名字来分发对应标签

代码示例:

App.vue

<template>
  <div>
      <SlotDemo>
          <!-- 2.使用组件,template配合v-slot:插槽名,夹着传入具体标签-->
          <template v-slot:title>
              <p>组件插槽-具名插槽</p>
          </template>
          <template v-slot:image>
              <img src="./assets/images.jpg" alt="">
          </template>
      </SlotDemo>
  </div>
</template>

<script>

import SlotDemo from './demo/SlotDemo.vue'
export default {
    components:{
        SlotDemo
    }
}
</script>

<style>

</style>

SlotDemo.vue

<template>
    <div>
        <!-- 1.slot占位 - name属性起名字 -->
        <slot name="title"></slot>
        <slot name="image"></slot>
    </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

十二、作用域插槽

作用:使用插槽时,可以使用组件内的变量

语法和口诀:

  • 子组件,在slot上绑定属性和子组件的值
  • 使用组件,传入自定义标签,用template和v-slot='自定义变量名'
  • scope变量名自动绑定slot上所有属性和值

代码示例:

App.vue

<template>
  <div>
      <SlotDemo>
          <!-- 2.使用组件,template配合v-slot="变量名",变量名会收集slot身上属性和值形成对象 -->
          <template v-slot="scope">
              <p>年龄:{{ scope.studentInfo.age }}</p>
          </template>
      </SlotDemo>
  </div>
</template>

<script>

import SlotDemo from './demo/SlotDemo.vue'
export default {
    components:{
        SlotDemo
    }
}
</script>

<style>

</style>

SlotDemo.vue

<template>
    <div>
        姓名:{{student.name}}<br>
        <!-- 1.slot标签,自定义属性和内变量关联 -->
        <!-- 冒号:后面的变量名可以随便起 -->
        <slot :studentInfo="student">
        </slot>
    </div>
</template>

<script>
export default {
    data(){
        return{
            student:{
                name:"张三",
                age:21    
            }
        }
    }
}
</script>

<style>

</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值