【随写蹭流】Vue.js 组件开发 II

第二篇蹭流量的。

如果你不幸看到我这篇杂文,强烈建议仔细阅读官方文档。那是学习 Vue.js 最权威、最全面的资源。直接点目录的参考文献就有链接了。

什么是组件?

在 Vue.js 中,组件是构成使用者介面的独立且可重复使用的程式码区块。。。其他文字见上篇

组件的优势:

可重复使用性: 组件可以在应用程式的不同部分重复使用,减少程式码冗余。
易于维护: 将介面拆分成小组件,使得程式码更易于理解、测试和维护。
提高开发效率: 开发团队可以并行开发不同的组件,提高开发效率。
程式码组织性: 组件化有助于组织和结构化大型应用程式的程式码。

组件的开发流程:

1.建立组件档案:

通常使用单档案组件(.vue 档案),将 template、script 和 style 放在同一个档案中。

<template>
  <div>
    <h1>{
   
   { message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from component!'
    };
  }
};
</script>

<style scoped>
h1 {
  color: blue;
}
</style>

2.注册组件:

在父组件中注册子组件,使其可以在模板中使用。

  • 局部注册: 只在当前组件中可用。
import MyComponent from './MyComponent.vue';

export default {
  components: {
    'my-component': MyComponent
  }
};
  • 全域注册: 在所有组件中都可用。
import MyComponent from './MyComponent.vue';

Vue.component('my-component', MyComponent);

3.使用组件: 在父组件的模板中使用已注册的组件。

<template>
  <div>
    <my-component></my-component>
  </div>
</template>

3.组件之间的沟通:

  • Props(属性): 父组件向子组件传递资料。
// 父组件
<template>
  <my-component :message="parentMessage"></my-component>
</template>

<script>
export default {
  data() {
    return {
      parentMessage: 'Message from parent'
    };
  }
};
</script>

// 子组件
<script>
export default {
  props: ['message']
};
</script>
  • Events(事件): 子组件向父组件发送讯息。
// 子组件
<template>
  <button @click="$emit('my-event', 'Data from child')">Click me</button>
</template>

// 父组件
<template>
  <my-component @my-event="handleMyEvent"></my-component>
</template>

<script>
export default {
  methods: {
    handleMyEvent(data) {
      console.log(data); // 输出:Data from child
    }
  }
};
</script>

进阶应用:

1.Slot(插槽):

插槽允许父组件向子组件传递内容,这使得组件更具弹性。子组件可以定义一个或多个插槽,父组件在使用子组件时,可以将任意内容插入到这些插槽中。

  • 预设插槽: 如果子组件没有定义具名的插槽,则父组件传递的内容会被渲染到预设插槽中。
// 子组件 (MyComponent.vue)
<template>
  <div>
    <slot></slot> </div>
</template>

// 父组件
<template>
  <my-component>
    <p>这是插入到预设插槽的内容。</p>
  </my-component>
</template>
  • 具名插槽: 子组件可以定义多个具名的插槽,父组件可以使用 v-slot 指令(或简写 #)将内容插入到指定的插槽中。
// 子组件 (MyComponent.vue)
<template>
  <div>
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot> </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

// 父组件
<template>
  <my-component>
    <template #header>
      <h1>页面标题</h1>
    </template>
    <p>这是主要内容。</p>
    <template #footer>
      <p>页脚资讯</p>
    </template>
  </my-component>
</template>
  • 作用域插槽: 插槽可以接收来自子组件的资料,这称为作用域插槽。子组件在渲染插槽时,可以将资料作为插槽的属性传递给父组件。
// 子组件 (MyComponent.vue)
<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <slot :item="item">{
   
   { item.name }}</slot>
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, name: '项目一' },
        { id: 2, name: '项目一' }
      ]
    };
  }
};
</script>

// 父组件
<template>
  <my-component>
    <template #default="{ item }">
      <strong>{
   
   { item.name }}</strong> - {
   
   { item.id }}
    </template>
  </my-component>
</template>

2.动态组件:

动态组件允许你根据不同的条件渲染不同的组件。这通常与 <component> 元素和 is 特性一起使用。

<template>
  <div>
    <component :is="currentComponent"></component>
    <button @click="currentComponent = 'ComponentA'">切换到 ComponentA</button>
    <button @click="currentComponent = 'ComponentB'">切换到 ComponentB</button>
  </div>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  components: {
    ComponentA,
    ComponentB
  },
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  }
};
</script>

3.递回组件:

递回组件是指组件自身呼叫自身的组件。这在处理树状结构的资料时非常有用,例如目录树或巢状评论。

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {
   
   { item.name }}
      <tree-view v-if="item.children" :items="item.children"></tree-view>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'tree-view', // 必须命名
  props: {
    items: {
      type: Array,
      required: true
    }
  }
};
</script>

4.Mixins(混入):

混入允许你在多个组件中重复使用相同的程式码。它可以包含任何组件选项,例如 data、methods、computed 和生命周期钩子。

// my-mixin.js
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  },
  created() {
    console.log('Mixin created');
  }
};

// MyComponent.vue
import myMixin from './my-mixin.js';

export default {
  mixins: [myMixin],
  created() {
    console.log('Component created');
  }
};

5.Composition API(组合式 API):

组合式 API 是一种更灵活的组件程式码组织方式,它允许你根据逻辑功能组织程式码,而不是根据组件选项。这使得程式码更易于理解、测试和维护,尤其是在大型组件中。它使用 setup() 函数作为组件逻辑的入口点。

<template>
  <div>
    <p>Count: {
   
   { count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const count = ref(0);

    const increment = () => {
      count.value++;
    };

    onMounted(() => {
      console.log('Component mounted');
    });

    return {
      count,
      increment
    };
  }
};
</script>

主要参考文献

Vue.js 2 官方文档

Vue.js 3 官方文档