And*_*ers 12 javascript vue.js vuex es6-modules
我有两个模块,我们称它们为core和implementation。如何设置商店以使事物core依赖于所提供的假定商店implementation?
在implementation的商店中,我正在执行以下操作:
import Core from 'core'
export default new Vuex.Store(
new Core().defaultStore
)
Run Code Online (Sandbox Code Playgroud)
这将注册默认状态,变异,动作和获取方法(该设置允许用户implementation扩展/修改由提供的默认存储core)。
core当它尝试访问非Vue JS文件中的getter时,问题就出现在内部动作中。
export default class SomeClassInCore {
exampleMethod() {
// The getters will not be accessible here!
return store.getters.someKey
}
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以实现“主”存储的“运行时”解析?我在考虑是否可以使用某种方式window来访问由仓库创建的Vue实例implementation?
我试图这样做
import store from './store.js'
import Vue from 'vue'
import { CoreVueTools } from 'core'
window.Vue = Vue
window.store = store
Vue.use(CoreVueTools)
new Vue({
el: '#app',
store
})
Run Code Online (Sandbox Code Playgroud)
然后像这样访问它
exampleMethod() {
return window.store.getters.someKey
}
Run Code Online (Sandbox Code Playgroud)
那行得通,但是我对此解决方案并不满意,必须有一种比依赖窗口更好的方法吧?我可以使用其他设计模式吗?
我不确定这是否符合您正在寻找解决方案的方向(因为它不依赖 vuex),如果不是,我希望它至少会是一个有趣的阅读 =)...
我可以使用其他设计模式吗?
您可以尝试一种非常简单(但尚未广为人知)的方法来使用基于减数分裂模式的方法来处理状态管理(主页)。我最近用一个 React 和一个 riot.js 应用程序实现了这个模式,与 redux 和 co 相比,它只需要很少的样板代码就可以工作得非常好(除了作为流提供的东西之外,没有任何依赖项,但你也可以自己实现! )。我还没有机会用 vue 尝试它(在我的待办事项列表中),所以下面的代码只是从存储库中的“设置”示例中快速(并减少)抄袭...
减数分裂模式的基本思想是依靠流来实现反应式循环,并将状态管理代码与视图代码分开。该模式的快速摘要(取自主页):
(x, f) => f(x)。甚至在 SO 片段中也能工作的东西=):
(关键部分请跳至本答案最后)
.row {
padding-bottom: 0.5rem;
}
button {
display: inline-block;
padding: 0 1rem;
color: #555;
text-align: center;
font-size: 0.75rem;
font-weight: 600;
line-height: 1.5rem;
letter-spacing: 1px;
text-transform: uppercase;
text-decoration: none;
white-space: nowrap;
background-color: transparent;
border-radius: 0.25rem;
border: 1px solid #bbb;
cursor: pointer;
box-sizing: border-box;
}
button:hover,
button:focus{
color: #333;
border-color: #888;
outline: 0;
}Run Code Online (Sandbox Code Playgroud)
<div id="app">
<temp />
</div>
<script src="https://cdn.jsdelivr.net/npm/flyd/flyd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script name="store">
// for convenience, let's define an initial state
const initialState = {
temperature: {
value: 22,
unit: "C"
}
};
// $update is a stream of patch functions
// the patch function passed here is doing
// nothing, it takes state and returns is,
// just for consistency...
const update = flyd.stream(state => state);
// define another stream to accumulate patches
// starting from the initial state
const getState = flyd.scan(
(state, patchFn) => patchFn(state),
initialState,
update,
);
// actions are functions that take an input
// and pass an appropriate patch function
// to the update stream
const actions = {
changeTemp: amount => update(state => ({
...state,
temperature: {
...state.temperature,
value: state.temperature.value + amount
}
})),
changeTempUnit: () => update(state => ({
...state,
temperature: {
...state.temperature,
unit: state.temperature.unit === "C" ? "F" : "C",
value: state.temperature.unit === "C"
? Math.round((state.temperature.value * 9) / 5 + 32)
: Math.round(((state.temperature.value - 32) / 9) * 5)
}
}))
};
// define global store by combining actions and getState
const store = {
getState,
actions
};
</script>
<script name="app">
new Vue({
el: "#app",
components: {
'temp': {
data() {
const initial = store.getState();
return {
temperature: initial.temperature.value,
unit: initial.temperature.unit
};
},
mounted() {
store.getState.map(s => {
this.temperature = s.temperature.value;
this.unit = s.temperature.unit;
});
},
methods: {
incTemp() {
store.actions.changeTemp(+1);
},
decTemp() {
store.actions.changeTemp(-1);
},
changeUnit() {
store.actions.changeTempUnit();
}
},
props: [],
template: `
<div class="temp-component">
<div class="row">
<button @click="incTemp">+</button>
<button @click="decTemp">−</button>
<span>The temperature is {{temperature}} °{{unit}}</span>
</div>
<div class="row">
<button @click="changeUnit">Change temperature unit</button>
</div>
</div>
`
}
}
});
</script>Run Code Online (Sandbox Code Playgroud)
该模式绝对独立于框架,因此无论您使用什么框架,商店等的设置都可以保持不变。vue.js 的关键部分是我们如何将商店与 vue/vue-components 连接起来,例如:
data() {
const initial = store.getState();
return {
temperature: initial.temperature.value,
unit: initial.temperature.unit
};
},
mounted() {
store.getState.map(s => {
this.temperature = s.temperature.value;
this.unit = s.temperature.unit;
});
},
Run Code Online (Sandbox Code Playgroud)
首先我们将部分全局状态数据(或整个全局状态)设置为data()组件函数的返回值。然后我们简单地使用getState流的map函数来更新组件状态。.map()是 getState 流的反应函数(此处由 Flyd 提供)。
PS:另请检查上面链接的示例存储库以获取更复杂的示例,包括todo-mvc和realworld(以及更多)...
| 归档时间: |
|
| 查看次数: |
432 次 |
| 最近记录: |