一个的vuex
import { reactive, provide, inject } from 'vue';
// 定义一个Symbol作为Injection key
const StoreSymbol = Symbol('simple-store');
// 定义Store类
class SimpleStore {
constructor(options) {
// 使用reactive使状态变为响应式
this.state = reactive(options.state);
this.mutations = options.mutations;
}
// 提交mutation来更新状态
commit(mutationKey, payload) {
this.mutations[mutationKey](this.state, payload);
}
}
// 插件的install方法
function install(app, options) {
const store = new SimpleStore(options);
app.provide(StoreSymbol, store); // 使用provide提供store
}
// 自定义hook,供组件使用store
export function useStore() {
return inject(StoreSymbol); // 使用inject获取store
}
// 导出插件
export default { install };
使用
import { createApp } from 'vue';
import App from './App.vue';
import SimpleStorePlugin from './SimpleStore';
const app = createApp(App);
// 使用插件,并定义一些初始状态和mutations
app.use(SimpleStorePlugin, {
state: {
count: 0,
},
mutations: {
increment(state, payload) {
state.count += payload;
}
}
});
app.mount('#app');
vue3自定义插件
vue3的MyButton组件
<template>
<button>{{ label }}</button>
</template>
<script>
export default {
name: 'MyButton',
props: {
label: {
type: String,
default: 'Click Me',
},
},
};
</script>
这里是插件代码
import MyButton from './MyButton.vue';
const MyPlugin = {
install(app, options) {
// 注册组件
app.component('MyButton', MyButton);
// 可选:添加全局方法或属性
app.config.globalProperties.$myPluginMethod = () => {
console.log('This is a global method');
};
// 可选:添加全局自定义指令、混入等
// app.directive('my-directive', {...});
// app.mixin({...});
},
};
export default MyPlugin;
然后使用app.use使用它
import { createApp } from 'vue';
import App from './App.vue';
import MyPlugin from './plugins/MyPlugin';
const app = createApp(App);
// 使用插件,可以传递选项
app.use(MyPlugin, { /* options if needed */ });
app.mount('#app');
vue3中setup下的mixins
// useSharedLogic.js
export function useSharedLogic() {
const sharedData = ref("Initial value");
const sharedMethod = () => {
console.log("This is a shared method.");
};
return { sharedData, sharedMethod };
}
这里就是一个非常好用的mixins的了,因为vue3的setup没有mixins了,只能这样子才可以用了,正常情况下使用mixins
// 定义一个mixin
export const myMixin = {
created() {
this.hello();
},
methods: {
hello() {
console.log('hello from mixin!');
}
}
};
// 使用mixin
import { myMixin } from './mixins/myMixin';
export default {
mixins: [myMixin],
// 组件的其它选项...
};
provide,inject,Symbol这些都是什么。
在Vue 3中,provide
和inject
是Composition API的一部分,用于在组件树中传递数据和方法,无论组件树有多深,而不必一层层手动传递props。这对于深层次的组件嵌套或跨组件通信尤为有用,常见于插件、库或高阶应用架构中。Symbol
则是ES6引入的原始数据类型之一,主要用于创建唯一的标识符。
provide 和 inject
-
provide: 一个组件使用
provide
来定义它想要提供给其所有子孙组件的数据或方法。这可以是响应式的或非响应式的数据,甚至是方法。它接受两个参数:一个key和一个value。key通常是一个字符串或Symbol,用于唯一标识提供的数据;value是实际提供的数据或方法。 -
inject: 子组件使用
inject
来接收来自其父链中某个组件provide
的数据或方法。inject
的参数是provide
时使用的相同的key,这样inject
就可以准确地接收到特定的数据或方法。
这种机制允许数据或方法“跳过”中间组件,直接从提供者传递到消费者,使得组件之间的通信更加灵活。
Symbol
Symbol
是JavaScript的一个基本数据类型,它通过Symbol()
函数调用创建。每次调用Symbol()
都会生成一个唯一的标识符。由于其独一无二的特性,Symbol
常被用作对象属性的键(key),以创建唯一且不会与其他属性冲突的标识符。在Vue 3的provide
和inject
场景中,使用Symbol
作为key可以确保数据的唯一性和隔离性,避免与其他可能相同名称的数据冲突。
例子
import { provide, inject, reactive } from 'vue';
const StoreSymbol = Symbol('store');
const store = reactive({
state: {
count: 0
},
increment() {
this.state.count++;
}
});
export function provideStore() {
provide(StoreSymbol, store);
}
export function useStore() {
const store = inject(StoreSymbol);
if (!store) {
// 处理未找到store的情况
throw new Error('Store not found!');
}
return store;
}