Vue-别名-通信-插槽-生命周期-$refs-(keep-alive)-(v-model)-mixin混入

101 阅读3分钟

创建vue的两种方式

vue create cli-demo // 基于webpack打包

npm init vue@latest // 基于vite打包

配置别名(掌握)

image.png

image.png

组件嵌入(重要)

image.png

组件通信(重要)

父传子

props数组类型:

  1. 不能对类型进行验证
  2. 没有默认值
image.png

常用方式:

image.png

重要的原则:对象类型写默认值,需编写default的函数,函数返回默认值

age:{
  type:Number,
  default: () => ({age:100})
},
height:{
  type:String,
  default: () => ['aa','bb']
}

type的类型都可以是哪些: String Number Boolean Array Object Date Function Symbol

子传父

image.png
<script>
export default {
  name: 'AddCounter',
  emits:['add'], // 注册说明
  methods:{
    btnClick(num) {
      this.$emit('add',num)
    }
  }
}
</script>

案例练习

子组件

<template>
  <div class="tab-control">
    <template v-for="(item,index) in titles" :key="item">
      <div class="tab-control-item"
           @click="itemClick(index)"
           :class="{active: index === currentIndex}">
        <span>{{ item }}</span>
      </div>
    </template>
  </div>
</template>

<script>
export default {
  name: "TabControl",
  props: {
    titles: {
      type: Array,
      default: () => {
      }
    }
  },
  data() {
    return {
      currentIndex: 0
    }
  },
  emits:['tabItemClick'],
  methods: {
    itemClick(index) {
      this.currentIndex = index
      this.$emit('tabItemClick',index)
    }
  }
}
</script>

<style scoped>
.tab-control {
  display: flex;
  height: 44px;
  line-height: 44px;
  text-align: center;
}

.tab-control-item {
  flex: 1;
}

.active {
  color: red;
  font-weight: 700;
}
.active span{
  border-bottom: 3px solid red;
  padding: 8px;
}
</style>

父组件

<template>
  <div class="app">
    <TabControl :titles="['衣服','鞋子','包包']" @tab-item-click="tabItemClick"/>

    <h1>{{pageContents[currentIndex]}}</h1>
  </div>
</template>

<script>
import TabControl from "./TabControl.vue";

export default {
  name: 'App',
  components: {TabControl},
  data() {
    return {
      pageContents:['衣服页面','鞋子页面','包包页面'],
      currentIndex:0
    }
  },
  methods:{
    tabItemClick(index){
      this.currentIndex = index
    }
  }
}
</script>

非父子通信 (了解)

  • 全局事件总线 (掌握)

Vue3官方有推荐一些库,例如 mitt 或 tiny-emitter

安装这个库:npm install hy-event-bus

image.png

  • Provide/Inject (了解 )
image.png image.png

插槽Slot(掌握)

默认插槽

image.png

具名插槽

image.png

具名插槽缩写: v-slot: 替换为字符 #

<NavBar>
  <template #left>
    <button>返回</button>
  </template>

  <template #center>
    <span>内容</span>
  </template>

  <template #right>
    <a href="#">登录</a>
  </template>
</NavBar>

作用域插槽(理解)

image.png

  • 插槽是默认插槽default,那么v-slot:default="slotProps"可以简写为v-slot="slotProps"

  • 插槽只有默认插槽时,组件的标签可以被当做插槽的模板来使用

image.png

生命周期 (重要)

beforCreate: 创建组件实例对象

created: template模板编译 ( 发送网络请求、事件监听、this.$wach() )

beforeMount: 挂载到虚拟DOM,根据虚拟DOM生成真实DOM,界面可以看到div

mounted: 数据更新,数据发生改变 ( 获取并使用DOM )

beforeUpdate: 根据最新的数据生成VNode,再生成新的虚拟DOM,根据虚拟DOM生成真实DOM

updated: 更新完成,回调updated

beforeUnmount: 组件不再使用,将之前挂载在虚拟DOM中的VNode从虚拟DOM中移除

unmountd: 移除完毕,将组件实例销毁 ( 取消事件监听、回收操作 )

beforeCreate() {
  console.log('beforeCreate:组件被创建之前');
},
 created() {
   console.log('created: 组件被创建完成');
 },
 beforeMount() {
   console.log('beforeMount: 组件准备被挂载');
 },
 mounted() {
   console.log('mounted: 组件被挂载 虚拟DOM -> 真实DOM');
 },
 beforeUpdate() {
   console.log('beforeUpdate: 数据发生改变,准备更新DOM');
 },
 updated() {
   console.log('updated: 已经更新');
 },
 beforeUnmount() {
   console.log('beforeUnmount: 准备卸载DOM元素(卸载之前)');
 },
 unmounted() {
   console.log('unmounted: DOM元素被卸载完毕');
 }

$refs获取元素或子组件实例 (掌握)

image.png

可以通过$parent来访问父元素

可以通过$root来访问根组件

动态组件案例 (了解)

image.png

keep-alive (理解)

某些情况我们希望继续保持组件的状态,而不是销毁掉,就可以使用一个内置组件:keep-alive

就不会频繁调用 createdunmounted

include可以用逗号分隔字符串、正则表达式或一个数组来表示

image.png

希望监听何时进入、离开了组件;可以使用 activateddeactivated 这两个生命周期钩子函数监听

// keep-alive组件进入活跃状态,监听有没有切换
activated() {
  console.log('activated,回来');
},
deactivated() {
  console.log('deactivated,离开');
}

Webpack的代码分包

组件之间是通过模块化直接依赖的,webpack在打包时会将组件模块打包到一起(比如app.js文件中),随着项目的不断庞大,app.js文件的内容过大,会造成首屏的渲染速度变慢

打包时,对于一些不需要立即使用的组件,可以单独对它们进行拆分成一些小的代码块chunk.js,这些chunk.js会在需要时从服务器加载下来,并且运行代码,显示对应的内容

image.png

对某个组件进行单独打包

import {defineAsyncComponent} from "vue";
const AsyncCategory = defineAsyncComponent(() => import('./views/Category.vue'))

components: {Home, About, Category:AsyncCategory},

组件的v-model (理解)

image.png

mixin 混入 (了解)

如果是data函数的返回值对象

  1. 返回值对象默认情况下会进行合并
  2. data返回值对象的属性发生了冲突,那么会保留组件自身的数据

如果生命周期钩子函数

  1. 生命周期的钩子函数会被合并到数组中,都会被调用

值为对象的选项(methods、components、directives),将被合并为同一个对象

  1. 比如都有methods选项,并且都定义了方法,那么它们都会生效
  2. 但是如果对象的key相同,那么会取组件对象的键值对;

image.png

全局混入

createApp(App).mixin({
    created() {
        console.log('mixin create');
    }
}).mount('#app')