uni-app 组件开发

核心知识点

组件创建

在 uni-app 中,组件是构建应用界面的基本单位。组件可以提高代码复用性,使应用结构更加清晰。

1. 全局组件

全局组件可以在整个应用中使用,需要在 main.js 中注册:

// main.js
import Vue from 'vue'
import App from './App.vue'
import MyComponent from './components/MyComponent.vue'

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

Vue.config.productionTip = false

App.mpType = 'app'

const app = new Vue({
  ...App
})
app.$mount()

2. 局部组件

局部组件只能在注册它的组件中使用:

<template>
  <view>
    <my-local-component></my-local-component>
  </view>
</template>

<script>
import MyLocalComponent from './components/MyLocalComponent.vue'

export default {
  components: {
    MyLocalComponent
  }
}
</script>

组件通信

组件间的通信是 uni-app 开发中的重要环节,主要有以下几种方式:

1. Props 传值

父组件通过 props 向子组件传递数据:

<!-- 父组件 -->
<template>
  <view>
    <child-component :message="parentMessage"></child-component>
  </view>
</template>

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

<!-- 子组件 -->
<template>
  <view>
    {{ message }}
  </view>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      default: ''
    }
  }
}
</script>

2. 自定义事件

子组件通过触发自定义事件向父组件传递数据:

<!-- 子组件 -->
<template>
  <view>
    <button @click="sendData">发送数据</button>
  </view>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit('custom-event', 'Data from child')
    }
  }
}
</script>

<!-- 父组件 -->
<template>
  <view>
    <child-component @custom-event="handleEvent"></child-component>
  </view>
</template>

<script>
export default {
  methods: {
    handleEvent(data) {
      console.log('Received:', data)
    }
  }
}
</script>

3. Vuex 状态管理

对于复杂的应用,可以使用 Vuex 进行全局状态管理:

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    increment(context) {
      context.commit('increment')
    }
  },
  getters: {
    getCount: state => state.count
  }
})

插槽使用

插槽允许父组件向子组件中插入内容,增强组件的灵活性:

1. 基本插槽

<!-- 子组件 -->
<template>
  <view>
    <slot></slot>
  </view>
</template>

<!-- 父组件 -->
<template>
  <view>
    <child-component>
      <text>插入的内容</text>
    </child-component>
  </view>
</template>

2. 具名插槽

<!-- 子组件 -->
<template>
  <view>
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </view>
</template>

<!-- 父组件 -->
<template>
  <view>
    <child-component>
      <template v-slot:header>
        <text>头部内容</text>
      </template>
      <text>主要内容</text>
      <template v-slot:footer>
        <text>底部内容</text>
      </template>
    </child-component>
  </view>
</template>

3. 作用域插槽

作用域插槽允许子组件向父组件传递数据:

<!-- 子组件 -->
<template>
  <view>
    <slot :user="user"></slot>
  </view>
</template>

<script>
export default {
  data() {
    return {
      user: {
        name: 'John',
        age: 30
      }
    }
  }
}
</script>

<!-- 父组件 -->
<template>
  <view>
    <child-component>
      <template v-slot="{ user }">
        <text>{{ user.name }}, {{ user.age }}岁</text>
      </template>
    </child-component>
  </view>
</template>

实用案例

开发可复用的自定义组件

下面我们来开发一个可复用的卡片组件:

<!-- components/Card.vue -->
<template>
  <view class="card" :class="{ 'card-shadow': shadow }">
    <slot name="header"></slot>
    <slot></slot>
    <slot name="footer"></slot>
  </view>
</template>

<script>
export default {
  props: {
    shadow: {
      type: Boolean,
      default: true
    }
  }
}
</script>

<style scoped>
.card {
  background-color: #fff;
  border-radius: 8px;
  padding: 16px;
  margin: 10px 0;
}

.card-shadow {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
</style>

使用这个卡片组件:

<template>
  <view>
    <card>
      <template v-slot:header>
        <text class="card-title">卡片标题</text>
      </template>
      <text class="card-content">卡片内容</text>
      <template v-slot:footer>
        <button class="card-button">按钮</button>
      </template>
    </card>
  </view>
</template>

<script>
import Card from './components/Card.vue'

export default {
  components: {
    Card
  }
}
</script>

<style scoped>
.card-title {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 10px;
}

.card-content {
  font-size: 14px;
  color: #666;
  margin-bottom: 16px;
}

.card-button {
  background-color: #007aff;
  color: #fff;
  border-radius: 4px;
  padding: 8px 16px;
}
</style>

学习目标

通过本集的学习,你应该能够:

  1. 了解 uni-app 组件的基本概念和分类
  2. 掌握全局组件和局部组件的创建与注册方法
  3. 熟悉组件间通信的多种方式,包括 props、自定义事件和 Vuex
  4. 学会使用插槽(基本插槽、具名插槽、作用域插槽)增强组件灵活性
  5. 能够开发可复用的自定义组件,提高代码复用性和可维护性

小结

组件开发是 uni-app 开发中的重要部分,合理的组件化设计可以使应用结构更加清晰,代码更加可维护。通过本集的学习,你已经掌握了组件创建、通信和插槽使用的核心知识点,并通过实际案例了解了如何开发可复用的自定义组件。在后续的开发中,你可以根据实际需求,灵活运用这些知识,构建更加复杂和功能强大的应用。

« 上一篇 uni-app 页面开发基础 下一篇 » uni-app 样式开发