Vuex principles, to be able to build wheels to measure the learning effect
Source code link
Github.com/kkxiaojun/k…
background
Unified data state management using VUEX has been available for some time. But other than looking at document pasting and copying apis, I didn’t seem to get much out of it.
For some things to know more about:
How are actions implemented
What about mutations
How is getters implemented
.
So, hurry up, learn to learn, output some handwritten vuEX core code process.
Vuex core API practices
After all, Vuex is a plug-in for VUE.
Refer to vue’s plug-in mechanism
Cn.vuejs.org/v2/guide/pl…
Use (Vuex), which is the mechanism by which Vue installs plug-ins, requires Vuex to expose an install method that passes Vue to install
Without further ado, let’s begin…
Project preparation
Create a basic project with VUe-CLI
The demo, making portal
Github.com/kkxiaojun/k…
1. Vue plug-in implementation
The Vue plug-in exposes the install method. And mount $store on vue. prototype. Then export the install and Store instances
class Store {
constructor() {
this.name = 'dajun'}}function install(Vue) {
Vue.prototype.$store = new Store()
}
export default { Store, install }
Copy the code
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
console.log('store===>', store)
new Vue({
store,
render: h => h(App),
}).$mount('#app')
Copy the code
App.vue
created() {
console.log('this.$store'.this.$store)
},
Copy the code
2. Implementation of Store
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
console.log('store===>', store)
new Vue({
store,
render: h => h(App),
}).$mount('#app')
Copy the code
Looking at main.js,store is passed in via new Vue
How can each component get an instance of $Store?
We need to mount it using mixin on the beforeCreate so that we can get the store passed in via this.$option.
Then distinguish between root and child components
// Vue plugin mechanism
function install (vue) {
Vue = vue
Vue.mixin({
beforeCreate() {
// The root component has store
if (this.$options && this.$options.store) {
this.$store = this.$options.store
} else {
/ / child component
this.$store = this.$parent && this.$parent.$store
}
}
})
}
Copy the code
Here are a few questions:
- Mixins are used to mix the contents of mixins into the initial parameters of Vue
$options
; - Why is it
beforeCreate
? This part, to understand the initialization of the life cycle,created
When,$option
It’s already initialized.
$store.state. Xx = “” $store.state. Xx = “” $store.state. Is that ok? In fact, this assignment is fine, and state is still reactive. So why commit?
- Vuex can record every state change, save state snapshots, and implement operations such as time roaming and rollback.
About global variables
- There’s no record, and two, it’s hard to find
3. state
Single data rendering: simple parameter transfer
class Store {
constructor(options = {}) {
this.state = options.state
}
}
Copy the code
import Vue from 'vue'
import Vuex from './myVuex'
Vue.use(Vuex)
const vuexObj = new Vuex.Store({
state: {
num: 0}})export default vuexObj
Copy the code
Print kan kan, no problem
Considering that state should be reactive, then…
4. The response type
An easy way to do this is to use the reactive form of Vue, new Vue() and pass in reactive data
let Vue
class Store {
constructor(options = {}) {
this.vm = new Vue({
data: {state: options.state
}
})
}
}
// Vue plugin mechanism
let install = function (vue) {
Vue = vue
vue.mixin({
beforeCreate() {
// The root component has store
if (this.$options && this.$options.store) {
vue.prototype.$store = this.$options.store
} else {
/ / child component
vue.prototype.$store = this.$parent && this.$parent.$store
}
}
})
}
export default {
Store,
install
}
Copy the code
5. getter
You can use Object.defineProperty to proxy a getter, get the value of the getter, and perform the function calculation. Finally, mount to $store.getters
defineGetters(options) {
this.getters = {}
let getters = options.getters || {}
Object.keys(getters).forEach(key= >{
Object.defineProperty(this.getters, key, {
get:() = >{
console.log('this.state'.this.state)
return getters[key](this.state)
}
})
})
}
Copy the code
const vuexObj = new Vuex.Store({
state: {
num: 0
},
getters: {
getNum(state) {
return state.num
}
},
})
Copy the code
6. mutation
Just look at the use of mutaion in VUex. You only need to record the function and update the data at commit time
class Store {
constructor(options = {}) {
// Add responsiveness
this.vm = new Vue({
data: {state: options.state
}
})
// mutations
this.defineMutations(options)
}
defineMutations(options) {
this.mutations = {}
let mutations = options.mutations || {}
Object.keys(mutations).forEach(mutationName= >{
this.mutations[mutationName] = (arg) = > {
mutations[mutationName](this.state, arg)
}
})
}
commit = (method, arg) = > {
console.log(`commit:mutations:${method}= = = > `, method)
this.mutations[method](arg)
}
// To access state directly
get state() {
return this.vm.state
}
}
Copy the code
7. action
Action, which is similar to mutation
class Store {
constructor(options = {}) {
// Add responsiveness
this.vm = new Vue({
data: {state: options.state
}
})
// actions
this.defineActions(options)
}
defineActions(opotions) {
this.actions = {}
let actions = opotions.actions
Object.keys(actions).forEach(actionName= > {
this.actions[actionName] =(arg) = > {
// Arrow function, not bound to this. Here this is an instance of $store
actions[actionName](this, arg)
}
})
}
dispatch(method, arg) {
console.log( `dispatch:actions:${method}= = = > `, method)
this.actions[method](arg)
}
commit = (method, arg) = > {
console.log(`commit:mutations:${method}= = = > `, method)
this.mutations[method](arg)
}
// To access state directly
get state() {
return this.vm.state
}
}
Copy the code
Note that {commit} is the deconstruction of this, store instances
The final result
At first glance, it is a bit shabby (even a small wheel is a wheel?).
Of course, there are mapState mapMutations, the realization of the modules. Interested, you can practice it yourself
The demo link
Finally, the demo link is attached
Github.com/kkxiaojun/k…