淺談vuex

1.最初,對於兩個組件,vmA,vmB,兩個組件狀態沒有交集,當想通過改變div2裏的input時,也改變div1的內容,怎麼做?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>狀態共享</title>
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="div1" style="background-color: #ccc;">
  {{ message }}
</div>
<hr />
<div id="div2" style="background-color: #CDDC39;">
  {{ message }}
  <br/>
  <input type="text" v-model="message" name="">
</div>
<script>

const vmA = new Vue({
    el:'#div1',
    data: {
        message:'div1的內容'
    }
});
const vmB = new Vue({
    el:'#div2',
    data: {
        message:'div2的內容'
    }
});
</script>
</body>
</html>

2.可以通過一個全局的變量sourceOfTruth,來讓兩個組件共享一個狀態,這樣改變div2裏的input時,也改變div1的內容,但是這樣組件就只有共享的狀態,這是不好的,那怎麼辦?

參考:https://cn.vuejs.org/v2/guide/state-management.html#%E7%AE%80%E5%8D%95%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86%E8%B5%B7%E6%AD%A5%E4%BD%BF%E7%94%A8

<body>
<div id="div1" style="background-color: #ccc;">
  {{ message1 }}
  <br />
  {{ message2 }}
</div>
<hr />
<div id="div2" style="background-color: #CDDC39;">
  {{ message2 }}
  <!-- {{ message3 }} -->
  <br/>
  <input type="text" v-model="message2" name="">
</div>
<script>
const sourceOfTruth = {
    message1:'共享的內容1',
    message2:'共享的內容2'
}
const vmA = new Vue({
    el:'#div1',
    data: sourceOfTruth
});
const vmB = new Vue({
    el:'#div2',
    data: sourceOfTruth
});
</script>
</body>

3.可以讓需要共享的狀態放在全局的變量sourceOfTruth裏,組件內保留私有的(無須共享的狀態),此處我們把sourceOfTruth改叫做store,並且組件要改變共享狀態裏的值,是通過觸發store裏的setMessageAction方法來實現的

<body>
<div id="div1" style="background-color: #ccc;">
  {{ sharedState.message2 }}
  <br />
  {{ privateState.message3 }}
  <br />
  {{ privateState.message4 }}
  <button @click="clearMessageAction">清除sharedState.message2</button>
</div>
<hr />
<div id="div2" style="background-color: #CDDC39;">
  {{ sharedState.message2 }}
  <br />
  {{ privateState.message3 }}
  <br/>
  <input type="text" v-model="sharedState.message2" name="">
</div>
<script>
var store = {
    debug: true,
    state: {
        message1:'共享的內容1',
        message2:'共享的內容2'
    },
    setMessageAction (newValue) {
        if (this.debug) console.log('setMessageAction triggered with', newValue)
        this.state.message2 = newValue
    },
    clearMessageAction () {
        if (this.debug) console.log('clearMessageAction triggered')
        this.state.message2 = ''
    }
}
var vmA = new Vue({
    el:'#div1',
    data: {
        privateState: {
            message4:'div1私有的內容'
        },
        sharedState: store.state
    },
    methods: {
        clearMessageAction: store.clearMessageAction.bind(store)
    }
})

var vmB = new Vue({
    el:'#div2',
    data: {
        privateState: {
            message3:'div2私有的內容'
        },
        sharedState: store.state
    }
})
</script>

4.組件要改變共享狀態裏的值,是通過(dispatch)觸發store裏的setMessageAction方法(action)來實現,這樣可以讓每次改變共享狀態的值可以追蹤。store純粹只是一種約定俗成的叫法,可以取其他的名稱。

現在整個實現共享狀態的方式已經浮在水面,其實這一整套思想叫做flux

 

 

5.vuex其實是flux思想的vue版的實現

6.用vuex改造上面的代碼如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>狀態共享</title>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
</head>
<body>
<div id="div1" style="background-color: #ccc;">
  {{ sharedState.message1 }}
  <br />
  {{ sharedState.message2 }}
  <br />
  {{ privateState.message3 }}
  <br />
  {{ privateState.message4 }}
  <button @click="clearMessageAction">清除sharedState.message2</button>
</div>
<hr />
<div id="div2" style="background-color: #CDDC39;">
  {{ sharedState.message2 }}
  <br />
  {{ privateState.message3 }}
  <br/>
  <input type="text" v-model="sharedState.message2" name="">
</div>
<script>
var store = new Vuex.Store({
    strict: true,
    state: {
        message1:'共享的內容1',
        message2:'共享的內容2'
    },
    mutations: {
        setMessageAction (state, newValue) {
            console.log('setMessageAction triggered with', newValue)
            state.message2 = newValue
        },
        clearMessageAction (state) {
            console.log('clearMessageAction triggered')
            state.message2 = ''
        }
    }
});
var vmA = new Vue({
    el:'#div1',
    data: {
        privateState: {
            message4:'div1的內容'
        },
        sharedState: store.state
    },
    methods: {
        clearMessageAction: () => {
            store.commit('clearMessageAction')
        }
    }
})

var vmB = new Vue({
    el:'#div2',
    data: {
        privateState: {
            message3:'div2的內容'
        },
        sharedState: store.state
    }
})
</script>
</body>
</html>

剩下vuex的用法和api就參考 https://vuex.vuejs.org/zh/

 

Reference:

https://blog.csdn.net/u010644262/article/details/79443567

https://vuex.vuejs.org/zh/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章