vue状态管理演进

栏目: 编程语言 · 发布时间: 5年前

内容简介:在vue中涉及到比较复杂的数据流转、交互,我们一般都会考虑用vux来进行数据的状态管理。经常使用,时常想它是怎么实现的,尝试简易实现一下。遗憾的是这不能正常工作,这是为什么?因为Vue使用数据方法来触发其“响应式反应”。如果不将数据传递给data,Vue将无法跟踪值更改并更新我们的组件以作为响应,更新视图。修改一下。注意

在vue中涉及到比较复杂的数据流转、交互,我们一般都会考虑用vux来进行数据的状态管理。经常使用,时常想它是怎么实现的,尝试简易实现一下。

  • 以选举日为例,一般的组件写法
<template>
  <div>
    <h1>Election day!</h1>
    <button @click="voteForRed">Vote for :red_circle:</button>
    <button @click="voteForBlue">Vote for :large_blue_circle:</button>

    <h2>Results</h2>
    <results :red="red" :blue="blue" />
    <total-votes :total="red + blue" />
  </div>
</template>

<script>
const TotalVotes = {
  props: ['total'],
  render (h) {
    return h('div', `Total votes: ${this.total}`)
  }
}
const Results = {
  props: ['red', 'blue'],
  render (h) {
    return h('div', `Red: ${this.red} - Blue: ${this.blue}`)
  }
}
export default {
  components: { TotalVotes, Results, },
  data: () => ({ red: 0, blue: 0 }),
  methods: {
    voteForRed () { this.red++ },
    voteForBlue () { this.blue++ },
  }
}
</script>
复制代码
vue状态管理演进
  • 隔离状态 让我们创建一个state对象,并从那里管理我们的整转态。
const state = {
  red: 0,
  blue: 0,
}

const TotalVotes = {
  render: h => h('div', `Total votes: ${state.red + state.blue}`)
}
const Results = {
  render: h => h('div', `Red: ${state.red} - Blue: ${state.blue}`),
}
// ...and, inside our main component,...
methods: {
  voteForRed () { state.red++ },
  voteForBlue () { state.blue++ },
},
复制代码

遗憾的是这不能正常工作,这是为什么?因为Vue使用数据方法来触发其“响应式反应”。如果不将数据传递给data,Vue将无法跟踪值更改并更新我们的组件以作为响应,更新视图。修改一下。

<template>
  <div>
    <h1>Election day!</h1>
    <button @click="voteForRed">Vote for :red_circle:</button>
    <button @click="voteForBlue">Vote for :large_blue_circle:</button>

    <h2>Results</h2>
    <results/>
    <total-votes/>
  </div>
</template>

<script>
const state = {
  red: 0,
  blue: 0,
}
const TotalVotes = {
  data () { return state },
  render (h) {
    return h('div', `Total votes: ${this.red + this.blue}`)
  },
}
const Results = {
  data () { return state },
  render (h) {
    return h('div', `Red: ${this.red} - Blue: ${this.blue}`)
  },
}
export default {
  components: { TotalVotes, Results },
  data () { return state },
  methods: {
    voteForRed () { this.red++ },
    voteForBlue () { this.blue++ },
  },
}
</script>
复制代码

注意

  • 组件TotalVotes、Results的props已经去除

  • 每一个组件在state中注册了state,Vue能够追踪状态变化,因此当我们投票给所有组件时,所有组件都会以适当的值进行重新渲染

  • 渲染函数中删除了箭头函数

  • 上面的实现方式存在缺陷,每个组件都要注册state,耦合性较高,继续改进

  • 创建共享Vue实例以保持响应式(数据变化触发视图更新)

import Vue from 'vue'
const state = new Vue({
  data () {
    return { red: 0, blue: 0 }
  },
  methods: {
    voteForRed () { this.red++ },
    voteForBlue () { this.blue++ },
  },
})
const TotalVotes = {
  render: h => h('div', `Total votes: ${state.red + state.blue}`),
}
const Results = {
  render: h => h('div', `Red: ${state.red} - Blue: ${state.blue}`),
}
export default {
  components: { TotalVotes, Results },
  methods: {
    voteForRed () { state.voteForRed() },
    voteForBlue () { state.voteForBlue() },
  },
}
复制代码

至此实现了简单的状态管理,但我们的解决方案目前无法在项目之间共享。我需要创建一个Vue实例,填充其数据方法,然后注册一些方法来修改状态,继续封装。

  • 封装
<!--模板-->
<template>
   <div>
    <h1>Election day!</h1>
    <button @click="voteForRed">Vote for :red_circle:</button>
    <button @click="voteForBlue">Vote for :large_blue_circle:</button>

    <h2>Results</h2>
    <results :red="red" :blue="blue" />
    <total-votes :total="red + blue" />
  </div>
</template>

<!--js-->
<script>
  import Vue from 'vue'

  const createStore = ({state, mutations}) => {
    return new Vue({
      data () {
        return {state}
      },
      methods: {
        commit (mutationName) {
          mutations[mutationName](this.state)
        }
      }
    })
  }

  const store = createStore({
    state: { red: 0, blue: 0 },
    mutations: {
      voteForRed (state) { state.red++ },
      voteForBlue (state) { state.blue++ }
    }
  })

  const TotalVotes = {
    render: h => h('div', `Total votes: ${store.state.red + store.state.blue}`)
  }
  
  const Results = {
    render: h => h('div', `Red: ${store.state.red} - Blue: ${store.state.blue}`)
  }

  export default {
    components: { TotalVotes, Results },
    methods: {
      voteForRed () { store.commit('voteForRed') },
      voteForBlue () { store.commit('voteForBlue') }
    }
  }
</script>  
复制代码

以上所述就是小编给大家介绍的《vue状态管理演进》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

浅薄

浅薄

[美]尼古拉斯·卡尔 / 刘纯毅 / 中信出版社 / 2015-11 / 49.00 元

互联网时代的飞速发展带来了各行各业效率的提升和生活的便利,但卡尔指出,当我们每天在翻看手机上的社交平台,阅读那些看似有趣和有深度的文章时,在我们尽情享受互联网慷慨施舍的过程中,我们正在渐渐丧失深度阅读和深度思考的能力。 互联网鼓励我们蜻蜓点水般地从多种信息来源中广泛采集碎片化的信息,其伦理规范就是工业主义,这是一套速度至上、效率至上的伦理,也是一套产量最优化、消费最优化的伦理——如此说来,互......一起来看看 《浅薄》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具