您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

Vue基础总结(中)(组件)

Vue基础 中

  • 一、组件
    • 1.组件概述
    • 2.vue组件——创建
    • 3.vue组件——全局注册使用
    • 4.vue组件——局部注册使用
    • 5.vue组件——scoped作用
  • 二、组件通信
    • 1.父向子 props
    • 2.子向父
    • 3.跨组件通信 EventBus
  • 三、组件生命周期
  • 四、高级用法 $ nextTick和$refs
  • 五、动态组件、插槽
    • 1.动态组件
    • 2.组件缓存
    • 3.组件插槽
    • 4.具名插槽
    • 5.作用域插槽
  • 六、自定义指令
    • 1.定义方式
    • 2.接值

一、组件

1.组件概述

组件化:封装的思想,把页面上可重用的部分封装为组件,从而方便项目的开发和维护
组件:是可复用的Vue实例,封装标签、样式和JS代码

2.vue组件——创建

每个组件都是一个独立的个体, 代码里体现为一个独立的.vue文件

  • 组件内template只能有一个根标签

  • 组件内data必须是一个函数, 独立作用域

3.vue组件——全局注册使用

全局入口在main.js, 在new Vue之上注册

//main.js引入

import Vue from 'vue'
import 组件对象 from 'vue文件路径'//引入组件文件对象

Vue.component("组件名", 组件对象)// 组件名开头大写驼峰(推荐)

使用如:<PannelC></PannelC>//把这个自定义标签当做组件解析

4.vue组件——局部注册使用

//App.vue中引入, 注册, 使用

import 组件对象 from 'vue文件路径'

export default {
    components: {
        "组件名": 组件对象
    }
}
  • 组件使用总结
    ①(创建)封装html+css+vue到独立的.vue文件中
    ②(引入注册)组件文件 => 得到组件配置对象
    ③(使用)当前页面当做标签使用

5.vue组件——scoped作用

作用:解决多个组件样式名相同,冲突问题

加上scoped属性,即自动给标签添加data-v-hash值属性

二、组件通信

1.父向子 props

例如: App.vue(父) MyProduct.vue(子)

步骤:

  • 创建组件components/MyProductvue - 准备标签
  • 组件内在props定义变量, 用于接收外部传入的值(props属性名建议都小写,因为标签里的属性只能小写/把变量驼峰转成-连接)
  • App.vue中引入注册组件, 使用时, 传入具体数据给组件显示

注意:在vue中需要遵循单向数据流原则:从父到子的数据流向。
props的值不能重新赋值, 对象引用关系属性值改变, 互相影响

2.子向父

步骤

  • 父: @自定义事件名=“父methods函数”
  • 子: this.$emit(“自定义事件名”, 传值) - 执行父methods里函数代码

总结:父自定义事件和方法, 等待子组件触发事件给方法传值

3.跨组件通信 EventBus

在这里插入图片描述

//EventBus/index.js- 定义事件总线bus对象
import Vue from 'vue'
const bus = new Vue()
export default bus

//List.vue注册事件
eventBus.$on('事件名', 函数体)

//Myp.vue
import eventBus from '../EventBus'

eventBus.$emit('事件名',)

总结: 空的Vue对象, 只负责 $on注册事件, $emit触发事件, 一定要确保 $on先执行

三、组件生命周期

  • 生命周期:一组件从创建到销毁的整个过程
  • 生命周期函数(钩子函数):vue 框架内置函数,随着组件的生命周期,自动按次序执行
  • 分类:初始化、挂载、更新、销毁
  • 当页面第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子函数
beforeCreate() {
  // 1. 创建前,在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
  console.log("beforeCreate --- data初始化之前");
  console.log(this.msg); // undefined
},
created() {
  // 2. 创建后,在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer), 属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
  console.log("created ---  data初始化以后");
  console.log(this.msg); // "我是变量"
},
beforeMount() {
  // 3. 挂载前,在挂载开始之前被调用:相关的 render 函数首次被调用。
  console.log("beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前");
  // console.log(document.getElementById("myUl").children[1].innerHTML); // 报错
},
mounted() {
  // 4. 挂载后,el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
  console.log("mounted --- vue的虚拟DOM, 挂载到真实的网页上 ");
  console.log(document.getElementById("myUl").children[1].innerHTML);
},
beforeUpdate() {
  // 5. 更新前,数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
  console.log("beforeUpdate --- 数据更新, 页面更新前");
  // 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
  // console.log(document.getElementById("myUl").children[4].innerHTML); // 报错
},
updated() {
  // 6. 更新后,由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
  console.log("updated --- 数据更新, 页面更新后");
  console.log(document.getElementById("myUl").children[4].innerHTML);
},
activated() {
//keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。
}
deactivated() {
//keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用。
},
beforeDestroy() {
  // 7. 销毁前,实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。
  console.log("beforeDestroy --- 实例销毁之前调用");
},
destroyed() {
  // 8. 销毁后,Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
  // (清空一些本地变量 / 全局变量 / 销毁当前组件的eventBus事件, 引用的全局事件)
  console.log("destroyed --- 销毁完成");
},
errorCaptured() {
//(2.5.0+ 新增)当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
}

四、高级用法 $ nextTick和$refs

目标: 利用 ref 和 $refs 可以用于获取 dom 元素, 或者组件实例

//ref定义值
<h1 ref="myH1">1. ref获取原生dom</h1>
//通过$refs.值 来获取dom或组件对象
this.$refs.myH1.innerHTML = "改内容了";

<p ref="a">数字: {{ count }}</p>
//dom是异步更新的, $nextTick可以等待dom更新后触发此方法
this.$nextTick(() => {
    console.log("DOM更新后触发$nextTick函数");
    console.log(this.$refs.a.innerHTML); // 1
})

五、动态组件、插槽

1.动态组件

动态组件:多个组件使用同一个挂载点,并动态切换,这就是动态组件

//vue内置component组件, 配合is属性, 设置要显示的组件名字
<component :is="comName"></component>

2.组件缓存

目标:组件切换会导致组件被频繁销毁和重新创建, 性能不高

补充生命周期:

  • activated - 激活

  • deactivated - 失去激活状态

    判断缓存的组件是出现还是消失

<keep-alive>
    <!-- vue内置的组件component,  -->
    <component :is="comName"></component>
</keep-alive>
  • keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 触发激活和非激活的生命周期方法

3.组件插槽

vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽。
用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容。

步骤:

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

//Pannel.vue
 <slot></slot>
 
 //UserSlot.vue - 使用组件
<Pannel>
 <img src="../assets/mm.gif" alt="" />
 <span>我是文字哦</span>
</Pannel>

import Pannel from "./Pannel";
export default {
  components: {
    Pannel,
  },
};

4.具名插槽

目标:当一个组件内有2处以上需要外部传入标签的地方。
slot的name属性起插槽名, 使用组件时, template配合#插槽名传入具体标签

//Pannel2.vue - 留下具名slot
<div class="container" v-show="isShow">   
	<slot name="one"></slot>    
	<slot name="two"></slot>
</div>

//UseSlot2.vue - v-slot可以简化成#
<Pannel2>
    <template v-slot:one>
		<img src="../assets/mm.gif" alt="" />
    </template>
    <template v-slot:two>
		<span>我是文字哦</span>
    </template>
</Pannel2>

5.作用域插槽

目标: 子组件里值, 在给插槽赋值时在父组件环境下使用
步骤:

  • 创建组件, 准备slot, 在slot上绑定属性和子组件值
  • 使用组件, 传入自定义标签, 用template和v-slot=“自定义变量名”
  • 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置

六、自定义指令

目标:获取标签,扩展额外的功能

1.定义方式

①局部注册和使用

<template>
  <div>
    <input type="text" v-focus />
  </div>
</template>

<script>
export default {
  // 局部注册
  directives: {
    focus: { // 自定义指令名
        inserted(el){ // 固定配置项 - 当指令插入到标签自动触发此函数
            el.focus()
        }
    },
  },
};
</script>

②全局注册

//main.js文件  v-fofo指令
Vue.directive("fofo", {
  inserted(el){//dom插入到页面上执行这个函数
    el.focus()
  }
})

2.接值

//main.js
Vue.directive("color", {
  inserted(el, binding){ // 插入时触发此函数
    el.style.color = binding.value;
  },
  update(el, binding){ // 更新时触发此函数
    el.style.color = binding.value;
  }
})

//Direct.vue
<p v-color="theColor" @click="changeColor">使用v-color指令控制颜色, 点击变蓝</p>

<script>
  data() {
    return {
      theColor: "red",
    };
  },
  methods: {
    changeColor() {
      this.theColor = 'blue';
    },
  },
</script>

分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进