The solution of heavy use of vuex and watch in vue

the project relies heavily on vuex and watch, and componentization is very convenient, but the data and state sharing between components has always been very difficult to deal with, so after using vuex, it is heavily dependent, and watch is heavily used. Watch is not recommended in the vue official website, but computed is used instead. However, a suitable method can not be found. Here is an example to show.

a page and b page, there are 5 paragraphs of text in b page. After clicking on the text, the data on page a will be added to the selected data and add up all the time. Similar to

the solution now is to modify the state variable through commit every time you click on the text, and the a page uses watch to listen for changes in the state variable, and if it changes, add new data.

the code uses decorator and typescript

//a
@Watch("content")
  ChangeContent(x: string) {
    if (!x) return;
    this.text += this.content;
  }

//b
 ChooseText(x: string) {
    this.ChangeContent(x);
  }

//state
content:null

//mutation
ChangeContentstatex{
    state.content=x
}

part of the logic of the method is not written, for example, if the same number is selected twice, watch will not be executed. Now I want to know if there is any other way than to use watch to listen for changes and execute the logic. For example, computed. This is only a small part of it, and we will encounter questions like this in the future, what is the design idea of the code. Thank you.

May.20,2022

for your requirements, state should store an array of clicked elements (here you can deduplicate them directly).

then you don't need watch , because all the elements clicked are in state , and the text is returned directly from this array in the calculation attribute.


feels like you don't understand vuex;

After

clipboard.png
basically uses vuex to store data, the watch method will not be used at all.
ide" rel=" nofollow noreferrer "> https://vuex.vuejs.org/zh/guide
you can look at the chestnuts again, maybe there will be a different harvest.


the example mentioned above is a simple parent-child component communication, so it is not necessary to use vuex


if you use vuex, because the state attribute in store is reactive and can be used directly on the page, it is generally not necessary to use watch. For ease of use, mapState or mapGetters is generally used to map the attributes of state to calculated attributes, as shown in the code of component A below.

parent component:

<template>
    <div>
        <component-a></component-a>
        <component-b></component-b>
    </div>
</template>
<script>
    import store from './store.js'
    import ComponentA from './ComponentA.vue'
    import ComponentB from './ComponentB.vue'

    export default {
        data () {
            return {}
        },
        store,
        components: {
            'component-a': ComponentA,
            'component-b': ComponentB
        }
    }
</script>

component A:

<template>
    <div> Count is : {{count}} </div>
</template>

<script>
    import { mapState } from 'vuex'

    export default {
        name: 'ComponentA',
        data () {
            return {}
        },
        computed: mapState([
            'count'
        ])
    }
</script>

component B

<template>
    <div>
        <ul v-for="i in 5">
            <li @click="increment(i)">{{i}}</li>  
        </ul>
    </div>
</template>

<script>
    export default {
        name: 'ComponentB',
        data () {
            return {}
        },
        methods: {
            increment(n) {
                console.log(n)
                this.$store.commit('increment', n)
            }
        }
    }
</script>

<style>
    ul > li {
        width: 100px;
        text-align: center;
        border-bottom: 1px solid gray;
        cursor: pointer;
        list-style: none;
    }
</style>

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
    strict: true,
    state: {
        count: 0
    },
    mutations: {
        increment(state, value) {
            state.count += value;
        }
    }
})

just use getters ide/getters.html" rel=" nofollow noreferrer "> https://vuex.vuejs.org/zh/gui...

Menu