Vue基础第六天

132 阅读3分钟

Vue基础第六天

动态组件

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

需求:完成一个注册页面功能,2个按钮点击分别切换两个组件

步骤:

  1. 创建两个组件并引入
  2. 注册并使用组件
  3. 设置一个vue变量等于其中一个组件的名字
  4. 使用vue内置的component标签动态挂载,根据绑定的is属性显示名字对应的组件
<template>
  <div>
    <button @click="componentName = 'UserInfo'">个人信息</button>
    <button @click="componentName = 'UserName'">登录信息</button>
    <!-- vue内置标签component是动态组件挂载点,会根据绑定的is属性显示名字对应的组件 -->
    <!-- 组件缓存  keep-alive 不会销毁组件 -->
    <keep-alive>
      <component :is="componentName" />
    </keep-alive>
  </div>
</template>

<script>
import UserInfo from "@/components/UserInfo.vue";
import UserName from "@/components/UserName.vue";
export default {
  data() {
    return {
      componentName: "UserInfo",
    };
  },
  components: {
    UserInfo,
    UserName,
  },
};
</script>

<style>
</style>

注意:频繁的切换会导致组件频繁创建和销毁,造成性能不高

如何切换组件:改变is的值,为要显示的组件名即可

组件缓存

频繁的切换会导致组件频繁创建和销毁,造成性能不高

语法:

Vue内置的keep-alive组件 包起来要频繁切换的组件

1653048215105

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

组件激活和非激活

如何知道组件是出现还是消失了

两个新的生命周期方法

方法名:

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

1653048506383

插槽

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

基本使用

使用场景:

  • 封装里的组件数据不确定‘
  • 封装里的组件标签不确定

语法口诀:

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

TopBar组件

<template>
  <div class="topBar">
    <div class="left"></div>
    <div class="right">
      <!-- 插槽占位标签 -->
      <slot/>
    </div>
  </div>
</template>

<script>
export default {

}
</script>

<style lang="less" scoped>
.topBar {
  display: flex;
  justify-content: space-between;
  border: 2px solid salmon;
}
</style>

App.vue

<template>
  <div>
    <!-- 员工页使用, 就要带导入员工新建员工按钮 -->
    <TopBar>
      <button>新增员工</button>
      <button>导入员工</button>
    </TopBar>
    <!-- 工资页面使用需要一个报表按钮 -->
    <TopBar>
      <button>报表</button>
    </TopBar>
  </div>
</template>

<script>
import TopBar from '@/components/TopBar.vue'
export default {
  components: {
    TopBar
  }
}
</script>

<style>

</style>

默认内容

如果外面不给传,想给个默认值显示内容

口诀:slot标签内放置内容,作为默认显示内容

效果:

  • 不给组件传标签,slot内容原地显示
  • 给组件传标签,则slot整体被换掉
<template>
  <div class="topBar">
    <div class="left"></div>
    <div class="right">
      <!-- 插槽占位标签 -->
      <slot>
        <!-- 如果外面没有传入, 默认显示的内容 -->
        欢迎来到我的页面
      </slot>
    </div>
  </div>
</template>

具名插槽

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

语法:

  • slot使用name属性区分名字
  • template配合v-slot:名字来分发对应标签
  • v-slot可以简写为#
    <div class="left">
      <slot name="left"/>
    </div>
    <div class="right">
      <!-- 插槽占位标签 -->
      <slot name="right">
        <!-- 如果外面没有传入, 默认显示的内容 -->
        欢迎来到我的页面
      </slot>
    </div>
    <TopBar>
      <!-- v-slot: 可以被简化成# -->
      <template #left>
        一共 666 位员工
      </template>
      <template #right>
        <button>新增员工</button>
        <button>导入员工</button>
      </template>
    </TopBar>
    <!-- 工资页面使用需要一个报表按钮 -->
    <TopBar>
      <template v-slot:left>
        5月工资报表
      </template>
      <template v-slot:right>
        <button>报表</button>
      </template>
    </TopBar>

作用域插槽

使用插槽时,想使用子组件里面的变量

口诀:

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

子组件

<template>
  <div class="topBar">
    <div class="left">
      <!-- 作用域插槽 语法: :自定义名字="传入的数据" -->
      <slot name="left" :row="num">
        {{ num.first }}
      </slot>
    </div>
    <div class="right">
      <!-- 插槽占位标签         -->

      <slot name="right">
        <!-- 里面的内容是默认值 -->
        欢迎来到我的页面
      </slot>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: {
        first: "一月",
        scoend: "二月",
      },
    };
  },
};
</script>

<style lang="less" scoped>
.topBar {
  display: flex;
  justify-content: space-between;
  border: 2px solid red;
}
</style>

App,vue

<template>
  <div>
    <TopBar>
      <!-- 作用域插槽 语法 v-slot:left="自定义名字" -->
      <!-- 使用 :{{ numm.row.scoend }}  {{自定义名字.子组件自定义名字.参数}} -->
      <template v-slot:left="numm"> {{ numm.row.scoend }} </template>
      <!-- 具名插槽写法  <template v-slot:"自定义的name名字"></template> -->
      <template v-slot:right>
        <button>员工信息</button>
        <button>员工人数</button>
      </template>
    </TopBar>
    <TopBar>
      <template #left> 年度工资人均50万 </template>
      <!-- 简写 -->
      <template #right>
        <button>报表</button>
      </template>
    </TopBar>
    <TopBar />
  </div>
</template>

<script>
import TopBar from "@/components/TopBar.vue";
export default {
  components: {
    TopBar,
  },
};
</script>

<style>
</style>

使用场景:封装一个灵活的表格组件

自定义指令

Vue内置指令不满足要求,自己定义一些指令来使用

注册

全局注册

在main.js文件下注册

1653050145456

局部注册

在使用的页面里注册

1653050181856

基本使用

<template>
  <div>
    <!-- 使用自定义指令, 跟普通vue指令一样, 请千万注意,要加上 v- 前缀 -->
    <input type="text">
    <br>
    <input type="text">
    <br>
    <input v-autofocus type="text">
  </div>
</template>

<script>
export default {
  // 局部指令注册
  // directives: {
    // 指令名字符串: {
        // 配置对象
        // 可以指定使用这个指令的元素, 在不同生命周期执行的函数
        // 在这些钩子函数的形参中, 默认第一个可以获取元素本身, 第二个可以用来传参
        // inserted,
        // update
    // }
  // }
  directives: {
    autofocus: {
      inserted(el) {
        console.log(el, '自动聚焦');
        el.focus()
      }
    }
  }
}
</script>

<style>

</style>