淘宝小程序使用mixins

本文介绍了JavaScript中的mixins机制,它是如何在Extjs4中实现组件复用和公共逻辑的。通过示例展示了如何在淘宝小程序中构造和使用mixins,包括生命周期管理、数据传递及方法调用的过程。

淘宝小程序使用mixins


以下都是前边在学习实践中查阅和总结得到的结论,可能会有差错,如果各位遇到的话还希望大家不吝赐教。

mixins

何为mixins

mixins是Extjs4的新特性,直译就是“混入”,可以复用一些公共逻辑的代码,从而减少代码量。

开发者有时可能会实现多个自定义组件,而这些自定义组件可能会有些公共逻辑要处理,应用提供 mixins 用于解决这种情况。

mixin在javascript里可以看作是一种从别的对象"借用"功能的方法。每一个新定义的对象都有一个 prototype属性,其他的对象就可以从这里"借用"功能。这里的功能可以是一个属性,也可以是一个方法。——cnblogs Mr 布鲁斯

机制

本质上类似于import一个js类,生命周期初始化顺序为 page(onLoad)—> mixins(onInit) —> components(onInit)

构造

与组件的js类似,拥有dataonInitderiveDataFromProps等生命周期、method等。基本上就可以当成component来用啦!

使用示例

官方文档
我自己的测试demo目录结构如下

  • components
    • testComponent
      • testComponent.js/.axml/.acss/.json
    • testComponent2
      • testComponent2.js/.axml/.acss/.json
      • mixinTest.js
    • mixinTest
      • mixinTest.js
  • pages
    • index
      • index.js/.axml/.acss/.json
// mixinTest.js
export default {
  data: {
    mixinData: 'mixinData',
    counter: 3
  },
  onInit(){
    console.log('init');
  }, 
  deriveDataFromProps(nextProps){},
  didMount(){},
  didUpdate(prevProps,prevData){},
  didUnmount(){},
  methods: {
  	onTapHandler() {
      const {counter} = this.data;
      this.setData({
        counter: 1 + counter
      })
      console.log('onTapHandler', this.data.counter);
    },
  },
};
// testComponent.js
import mixinTest from '../mixinTest/mixinTest';
  const initialState = {
  data: {
    isLogin: false,
    componentCounter: 0
  },
};
const defaultProps = {
  props: {
    age: 30,
  },
};
Component({
  mixins: [
    mixinTest,
    initialState,
    defaultProps,
    // methods
  ],
  data: {
    name: 'alipay'
  },
  props: {},
  onInit() {
    console.log('component init')
  },
  methods: {
    componentTap () {
      const {counter, componentCounter} = this.data;
      const {counter:mixinCounter} = mixinTest.data;
      console.log(counter + 1, mixinCounter, componentCounter + 1);
      this.setData({
        counter: counter + 1,
        componentCounter: componentCounter + 1
      })
    }
  },
});

<!-- testComponent -->
<view>
  <test-component2 />
  {{name}}: {{age}}:counter:{{counter}}
  <view onTap="onTapHandler" style="width:100vw;height:40rpx;background:royalblue;">tap place</view>
  <view onTap="componentTap"  style="width:100vw;height:40rpx;background:rosybrown;">component place</view>
</view>

其他js就是在onInit和onLoad里加入了console.log,界面如下
程序界面
运行预览
可以看到,执行初始化的顺序是 onLaunch(app.js) -> onLoad(page/index.js) -> onInit(mixins component) -> onInit (component)
另外,在onTapHandlercomponentTap点击事件中可以看到:

  1. mixin中的变量较为独立,混入后外部更改同个变量名的值并不会影响其模板中的值。
  2. 可以直接调用mixin中的函数,十分方便。
<think>好的,用户现在问的是关于在Uniapp中使用Mixins。我需要先回顾之前的对话历史,确保这次回答和之前的一致,并且补充Mixins的相关内容。之前用户问的是如何通过getCurrentPages设置CSS变量,现在转向Mixins,可能是在寻找代码复用的方法。 首先,Mixins在Vue中确实是一个常用的代码复用机制,但在Uniapp中是否适用?需要确认Uniapp对Vue 2和Vue 3的支持情况。Vue 3推荐使用Composition API替代Mixins,但Uniapp可能还在用Vue 2较多,所以需要说明两种情况。 用户可能的需求是了解Mixins的基本用法,优缺点,以及替代方案。需要结构清晰,分点说明。同时用户可能关心在实际项目中的最佳实践,比如如何避免命名冲突,如何结合Uniapp的特性使用Mixins。 还要注意之前回答中提到的平台差异性和操作方式,虽然Mixins本身不涉及平台差异,但在Uniapp中使用时可能需要考虑组件的生命周期和API调用是否一致。比如,Mixins中的生命周期钩子是否在各个平台都能正确触发。 可能需要举一些实际的例子,比如封装网络请求或分享功能的Mixins,让用户更容易理解。同时要提醒注意事项,比如Mixins的优先级,合并策略,以及过度使用带来的维护问题。 另外,用户之前的问题涉及到CSS变量和动态主题,可能在Mixins的应用场景中,可以考虑如何用Mixins来管理样式或主题相关的逻辑,但需要区分开逻辑复用和样式复用。 总结回答结构:定义、核心作用、使用方式、优缺点、替代方案、Uniapp中的注意事项、示例代码、最佳实践。这样用户能逐步了解Mixins的概念和应用,同时获得实际操作的指导。</think>在Uniapp中使用**Mixins**(混入)是一种高效的代码复用机制,特别适用于跨组件共享逻辑的场景。以下是关于Mixins的完整技术解析和实践指南: --- ### 一、Mixins核心定义 $$ \text{Mixins} = \underset{\text{可复用代码块}}{\underbrace{\{ \text{data, methods, hooks...} \}}} \rightarrow \underset{\text{合并到组件}}{\hookrightarrow} \text{目标组件} $$ #### 技术特性: 1. **代码复用率提升**:减少重复逻辑代码量 2. **非侵入式扩展**:不影响组件原有结构 3. **按需组合**:支持多Mixin叠加使用 --- ### 二、基础使用方式 #### 1. 创建Mixin文件 ```javascript // mixins/networkMixin.js export default { data() { return { loading: false, error: null } }, methods: { async fetchData(url) { this.loading = true try { const res = await uni.request({ url }) return res.data } catch (e) { this.error = e } finally { this.loading = false } } } } ``` #### 2. 组件中引入 ```javascript import networkMixin from '@/mixins/networkMixin' export default { mixins: [networkMixin], methods: { async loadUserData() { const data = await this.fetchData('/api/user') // 使用混入方法 } } } ``` --- ### 三、Uniapp特殊场景适配 #### 1. 生命周期合并策略 ```javascript // mixins/logMixin.js export default { onShow() { console.log('Mixin onShow') }, onLoad() { console.log('Mixin onLoad') } } // 组件将按顺序执行: // 1. Mixin的onLoad // 2. 组件自身的onLoad ``` #### 2. 平台条件混入 ```javascript // mixins/platformMixin.js export default { computed: { isIOS() { // #ifdef APP-PLUS return plus.os.name === 'iOS' // #endif return false } } } ``` --- ### 四、进阶使用模式 #### 1. 动态混入(Vue 2.x) ```javascript // 根据条件加载不同Mixin const dynamicMixins = [] if (needFeatureA) dynamicMixins.push(featureAMixin) if (needFeatureB) dynamicMixins.push(featureBMixin) export default { mixins: dynamicMixins } ``` #### 2. 全局混入(慎用) ```javascript // main.js import Vue from 'vue' import globalMixin from './mixins/global' Vue.mixin(globalMixin) // 影响所有组件 ``` --- ### 五、与Composition API对比 | 特性 | Mixins | Composition API | |---------------------|--------------------------|-------------------------| | 代码组织 | 选项式聚合 | 函数式组合 | | 命名冲突 | 可能发生 | 按需命名 | | 类型推断 | 困难 | 完善 | | 逻辑复用粒度 | 组件级 | 函数级 | | 调试难度 | 较高(需跳转查看) | 较低(逻辑集中) | --- ### 六、最佳实践建议 #### 1. 命名规范策略 ```javascript // 使用前缀避免冲突 export default { methods: { _mixin_uniqueMethod() { /* ... */ } } } ``` #### 2. 明确作用域 ```javascript // 使用Symbol定义私有属性 const PRIVATE_KEY = Symbol('mixinKey') export default { data() { return { [PRIVATE_KEY]: '内部使用' } } } ``` #### 3. 文档注释规范 ```javascript /** * @mixin networkMixin * @desc 网络请求相关逻辑封装 * @prop {Boolean} loading - 请求状态 * @method fetchData - 统一请求方法 */ ``` --- ### 七、典型应用场景 #### 1. 页面埋点系统 ```javascript // mixins/trackMixin.js export default { onShow() { this.$trackPageView(this.$route.path) }, methods: { $trackEvent(eventName, payload) { uni.reportAnalytics(eventName, payload) } } } ``` #### 2. 权限控制模块 ```javascript // mixins/authMixin.js export default { computed: { userRole() { return this.$store.state.user.role } }, methods: { checkPermission(requiredRole) { return this.userRole === requiredRole } } } ``` --- ### 八、调试技巧 #### 1. 查看合并结果 ```javascript mounted() { console.log(this.$options) // 查看最终合并的组件选项 } ``` #### 2. 冲突检测 ```javascript // 在组件中检测方法覆盖 if (this.$options.methods.hasOwnProperty('methodName')) { console.warn('方法被覆盖:', 'methodName') } ``` --- ### 九、替代方案推荐 #### 1. 组合式函数(Vue3) ```javascript // composables/useNetwork.js export function useNetwork() { const loading = ref(false) const fetchData = async (url) => { // 实现逻辑 } return { loading, fetchData } } ``` #### 2. 自定义指令 ```javascript // 适用于DOM操作相关复用 Vue.directive('focus', { inserted: el => el.focus() }) ``` --- ### 十、技术原理图示 $$ \begin{aligned} &\text{Mixin合并过程} \\ &1. \text{数据对象} \rightarrow \text{递归合并} \rightarrow \text{组件优先} \\ &2. \text{钩子函数} \rightarrow \text{合并为数组} \rightarrow \text{依次执行} \\ &3. \text{方法/计算属性} \rightarrow \text{组件覆盖Mixin} \end{aligned} $$ --- **特别提醒**:在Uniapp多端场景下,建议通过`条件编译`处理平台差异: ```javascript methods: { platformMethod() { // #ifdef MP-WEIXIN wx.specialAPI() // #endif // #ifdef H5 document.querySelector(...) // #endif } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值