深入Vue-状态管理


State Management

如何来管理一个公共的数据呢?
我们可以有很多方法

4.1 通过props

<script src="../node_modules/vue/dist/vue.js"></script>

<div id="app">
  <counter :count="count"></counter>
  <counter :count="count"></counter>
  <counter :count="count"></counter>
  <button @click="count++">increment</button>
</div>

<script>
// requirement: a counter component rendered 3 times
// the component takes the current count via props
// and a button that increments all 3 counters at once
new Vue({
  el: '#app',
  data: {
    count: 0
  },
  components: {
    Counter: {
      props: {
        count: Number
      },
      template: `<div>{{ count }}</div>`
    }
  }
})
</script>

4.2 通过共享一个对象

<script src="../node_modules/vue/dist/vue.js"></script>

<div id="app">
  <counter></counter>
  <counter></counter>
  <counter></counter>
  <button @click="inc">increment</button>
</div>

<script>
// create a counter component (that doesn't take any props)
// all instances of it should share the same count state
// and a button that increments all counters at the same time

const state = {
  count: 0
}

const Counter = {
  // Convert state into reactive object
  data () {
    return state
  },
  render (h) {
    // Proxy the object
    return h('div', this.count)
  }
}

new Vue({
  el: '#app',
  components: {
    Counter
  },
  methods: {
    inc () {
      state.count++
    }
  }
})
</script>

4.3 通过共享一个store实例

<script src="../node_modules/vue/dist/vue.js"></script>

<div id="app">
    <counter></counter>
    <counter></counter>
    <counter></counter>
    <button @click="inc">increment</button>
</div>

<script>
    // copy and modify the first exercise to use a Vue instance as
    // a shared store instead.
    const state = new Vue({
        data: {
            count: 0
        },
        methods: {
            inc() {
                this.count++;
            }
        }
    });

    const Counter = {
        render: h => h("div", state.count)
    };

    new Vue({
        el: "#app",
        components: {
            Counter
        },
        methods: {
            inc() {
                state.inc();
            }
        }
    });
</script>

实现一个createStore(类似vuex)

<script src="../node_modules/vue/dist/vue.js"></script>

<div id="app">
  <counter></counter>
  <counter></counter>
  <counter></counter>
  <button @click="inc">increment</button>
</div>

<script>
function createStore ({ state, mutations }) {
  return new Vue({
    data: {
      state
    },
    methods: {
      commit (mutation) {
        if (!mutations.hasOwnProperty(mutation)) {
          throw new Error('Unknown mutation')
        }
        mutations[mutation](state)
      }
    }
  })
}

const store = createStore({
  state: { count: 0 },
  mutations: {
    inc (state) {
      state.count++
    }
  }
})

const Counter = {
  render (h) {
    return h('div', store.state.count)
  }
}

new Vue({
  el: '#app',
  components: { Counter },
  methods: {
    inc () {
      store.commit('inc')
    }
  }
})
</script>

封装一个函数

<script src="../node_modules/vue/dist/vue.js"></script>

<div id="app"></div>

<script>
function app ({ el, model, view, actions }) {
  const wrappedActions = {}

  Object.keys(actions).forEach(key => {
    const originalAction = actions[key]
    wrappedActions[key] = () => {
      vm.model = originalAction(vm.model)
    }
  })

  const vm = new Vue({
    el,
    data: {
      model
    },
    render (h) {
      return view(h, this.model, wrappedActions)
    },
    methods: actions
  })
}

// voila
app({
  el: '#app',
  model: {
    count: 0
  },
  actions: {
    inc: ({ count }) => ({ count: count + 1 }),
    dec: ({ count }) => ({ count: count - 1 })
  },
  view: (h, model, actions) => h('div', { attrs: { id: 'app' }}, [
    model.count, ' ',
    h('button', { on: { click: actions.inc }}, '+'),
    h('button', { on: { click: actions.dec }}, '-')
  ])
})
</script>

这样就封装好了,嘿嘿嘿


文章作者: 沐雪
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 沐雪 !
评论
 上一篇
深入Vue-hash路由 深入Vue-hash路由
hash router5.1 basic hash router要求 display foo when url is at #foo display bar when url is at #bar bonus: implement link
2019-04-10 沐雪
下一篇 
深入Vue-RenderFunction 深入Vue-RenderFunction
Render Function3.1 Dynamically Render Tagstemplate =>编译成Render Function => 返回一个新的虚拟DOM => 生成真实的DOM 真实DOM docu
2019-04-10 沐雪
  目录