Vue 组件高级基础

131 阅读2分钟

1.ref 引用

ref 用来辅助开发者在不依赖于jQuery 的情况下,获取 DOM元素或组件的引用。

每个vue的组件实例上,都包含一个 $refs 对象,里面存储着对应的DOM元素或组件的引用。默认情况下,组件的 $refs 指向一个空对象

<template>
  <div>
    <h1 ref="myh1">App 组件</h1>
    <hr />
    <button type="button" class="btn-primary" @click="getRefs">
      获取$refs引用
    </button>
  </div>
</template>

<script>
export default {
  name: "MyApp",
  methods: {
    getRefs() {
      console.log(this.$refs);
      this.$refs.myh1.style.color = "red";
    },
  },
};
</script>

使用 ref 引用组件实例

<template>  //子组件Counter
  <div class="counter-container">
    <h3>Counter 组件---{{ count }}</h3>
    <hr />
    <button type="button" class="btn-info" @click="count += 1">+1</button>
  </div>
</template>

<script>
export default {
  name: "MyCount",
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    reset() { //reset()方法通过ref实例 在父组件中引用调用
      this.count = 0;
    },
  },
};
</script>

App 组件

 <template>
  <div>
    <h1 ref="myh1">App 跟组件</h1>
    <hr />
    <button type="button" class="btn-primary" @click="getRefs">
      获取$refs引用
    </button>
    <hr />    //ref 获取当前DOM元素的实例
    <my-counter ref="counterRef"></my-counter> 
  </div>
</template>

<script>
import MyCounter from "./components/Counter.vue";
export default {
  name: "MyApp",
  methods: {
    getRefs() { 
                 //拿到实例本身的方法
      this.$refs.counterRef.reset();
    },
  },
  components: {
    MyCounter,
  },
};
</script>

2.this.$nextTick(cb)方法

组件的 $nextTick(cb) 方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行。通俗的理解是:等组件的 DOM 异步地重新渲染完成后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素。

3.动态组件

动态组件指的是动态切换组件的显示与隐藏。vue提供了一个内置的<component>组件,专门用来实现组件的动态渲染。

<component>是组件的占位符
<component is="要渲染的组件的名称"></component>

通过is属性动态指定要渲染的组件名称

<template>
  <div>
    <h1>App 组件</h1>
    <hr />
    <button type="button" class="btn-primary" @click="comName='MyHome'">首页</button>
    <button type="button" class="btn-primary" @click="comName='MyMovie'">电影</button>

    <!--  <my-home></my-home> //隐藏之前的home和movie组件
    <my-movie></my-movie> -->
    <component :is="comName"></component>// 通过button按钮选择is属性 来切换 
  </div>
</template>

<script>
import MyHome from "./Home.vue";
import MyMovie from "./Movie.vue";
export default {
  name: "MyApp",
  data() {
    return {
      comName: "MyHome",
    };
  },
  components: {
    MyHome,
    MyMovie,
  },
};
</script>

4.keep-alive 保持组件当前状态

默认情况下,切换动态组件时无法保持组件的状态。此时可以使用 vue内置的 <keep-alive>组件保持动态组件的状态。示例代码如下:

   <keep-alive>
      <component :is="comName"></component>
   </keep-alive>

当前组件状态将会被保留保持,不会在组件之间切换时而进行重新渲染

5.插槽 Slot

插槽(Slot) 是 vue 为组件的封装者提供的能力。允许开发者在封装组件时 ,把不确定的、希望由用户指定的部分定义为插槽。

在封装组件时,可以通过<slot>元素定义插槽,从而为用户预留内容占位符。

<template>
  <div>
      <header>
        //为插槽添加name具名 以便区分多个插槽的使用
          <solt name="header"></solt>
      </header>
      <main>
        //默认插槽名称为default
          <solt name="default"></solt>
      </main>
      <footer>
          <solt name="footer"></solt>
      </footer>
  </div>
</template>

为具名插槽提供内容 很多时候需要一种方法来传递多个插槽内容片段,每个片段都针对不同的插槽出口。这就是命名插槽的用武之地。

要传递命名槽,我们需要使用<template>带有指令的元素 v-slot,然后将槽的名称作为参数传递给 v-slot:

<BaseLayout>
  <template v-slot:header>
    <!-- content for the header slot -->
  </template>
</BaseLayout>

v-slot 有专门的速记#,所以<template v-slot:header>可以简写为 <template #header>。可以将其视为“在子组件的 'header' 插槽中呈现此模板片段”

  <template #header>
    <h1>Here might be a page title</h1>
  </template>

为了让 需要的数据 在父级的插槽内容中可用,我们可以将 该对象 作为 元素的一个 attribute 绑定上去:

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

绑定在 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

解构插槽 Prop:可以使用 ES2015 解构来传入具体的插槽 prop,如下:

<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>

6.自定义指令(简)

自定义指令:Vue 允许开发者自定义指令

  1. 私有自定义指令
  2. 全局自定义指令

在每个 vue 组件中,可以在 directives节点下声明私有自定义指令。 全局共享的自定义指令需要通过“单页面应用程序的实例对象”进行声明。