閱讀目錄javascript
一:vue傳值方式有哪些?html
二:理解使用Vuexvue
三:webpack4+vue+route+vuex 項目架構java
一:vue傳值方式有哪些?node
在vue項目開發過程當中,常常會使用組件來進行項目開發,那麼在組件中會調用另外一個組件來做爲本身的子組件,那麼咱們如何進行給子組件進行傳值呢?或者說,子組件如何給父組件傳值呢?父子組件數據是如何通訊的呢?
所以vue經常使用的傳值方式有以下幾種:
1. 父傳子
2. 子傳父
3. 非父子傳值webpack
父子組件傳遞數據能夠看以下圖所示git
總結是:父組件向子組件傳遞數據,能夠經過prop屬性向下傳遞數據,子組件向父組件傳遞數據是經過事件給父組件發送消息。github
下面咱們看以下父子組件的demo。在看demo以前,咱們看下項目目錄的結構以下:web
### 目錄結構以下: demo1 # 工程名 | |--- dist # 打包後生成的目錄文件 | |--- node_modules # 全部的依賴包 | |--- app | | |---index | | | |-- views # 存放全部vue頁面文件 | | | | |-- parent.vue # 父組件 | | | | |-- child.vue # 子組件 | | | | |-- index.vue | | | |-- components # 存放vue公用的組件 | | | |-- js # 存放js文件的 | | | |-- app.js # vue入口配置文件 | | | |-- router.js # 路由配置文件 | |--- views | | |-- index.html # html文件 | |--- webpack.config.js # webpack配置文件 | |--- .gitignore | |--- README.md | |--- package.json | |--- .babelrc # babel轉碼文件
1. 父組件向子組件傳值demo以下:ajax
app/index/views/parent.vue 代碼以下:
<template> <div> <div> <label>父組件:</label> <input type='text' v-model = 'name' /> <br /> <!-- 引入子組件 --> <child :inputName="name"></child> </div> </div> </template> <script type="text/javascript"> import child from './child'; export default { data() { return { name: '' } }, components: { child: child } } </script>
app/index/views/child.vue 代碼以下:
<template> <div> <label>子組件:</label> <span>{{inputName}}</span> </div> </template> <script type="text/javascript"> export default { // 接收父組件的值 props: { inputName: String, required: true } } </script>
app/index/views/index.vue 代碼以下:
<style lang="stylus"> </style> <template> <div id="app"> <header> <router-link to="/parent" tag='li'>parent</router-link> </header> <!-- 對應組件的內容渲染到router-view中 --> <router-view></router-view> </div> </template> <script type="text/javascript"> export default { data() { return { } } } </script>
app/index/router.js 代碼以下:
import Vue from 'vue'; import VueRouter from 'vue-router'; // 告訴 vue 使用 vueRouter Vue.use(VueRouter); const routes = [ { path: '/parent', name: 'parent', component: resolve => require(['./views/parent'], resolve) }, { path: '*', // 其餘沒有的頁面都重定向到 home頁面去 redirect: '/parent' } ] var router = new VueRouter({ base: '/app/index', // 配置單頁應用的基路徑 routes: routes }); export default router;
所以頁面運行效果以下圖所示:
2. 子組件向父組件傳值方式demo以下:
app/index/views/parent.vue 代碼改爲以下:
<template> <div> <div> <label>父組件:</label> <span style="color:red;">{{name}}</span> <br /> <!-- 引入子組件 定義一個方法來監聽子組件的狀態值 --> <child @childChange="childChangeFunc"></child> </div> </div> </template> <script type="text/javascript"> import child from './child'; export default { data() { return { name: '' } }, methods: { childChangeFunc(value) { // value 就是子組件傳遞過來的值 this.name = value; } }, components: { child: child } } </script>
app/index/views/child.vue 代碼改爲以下:
<template> <div> <label>子組件:</label> <span>{{childValue}}</span> <!-- 子組件事件傳值 --> <input type='button' value='點擊觸發' @click="childClick" /> </div> </template> <script type="text/javascript"> export default { data() { return { childValue: '我是子組件的數據' } }, methods: { childClick() { // 子組件觸發事件 this.$emit('childChange', this.childValue); } } } </script>
運行以下:
麼有觸發點擊以前的效果圖以下:
點擊觸發按鈕後,效果圖以下:
3. 非父子組件進行傳值
非父子組件之間傳值,須要定義個公共的實列文件來做爲中間倉庫來傳值的。好比定義一個叫 bus.js 文件。
所謂中間倉庫就是建立一個事件中心,至關於中轉站,可使用它來傳遞事件和接收事件的。
在app/index 下新建一個js文件夾,在文件夾內新建一個bus.js文件,代碼以下:
import Vue from 'vue'; export default new Vue();
在app/index/views/a.vue, 代碼以下:
<template> <div> <label>A組件:</label> <span>{{value}}</span> <input type="button" value="點擊觸發" @click="clickFunc" /> </div> </template> <script type="text/javascript"> // 引入公共的bus import Bus from '../js/bus.js'; export default { data() { return { value: 1 } }, methods: { clickFunc() { Bus.$emit('val', this.value); } } } </script>
在app/index/views/b.vue, 代碼以下:
<template> <div> <label>B組件:</label> <input type='button' value='點擊觸發' @click="getDataFunc" /> <span>{{name}}</span> </div> </template> <script type="text/javascript"> import Bus from '../js/bus.js'; export default { data() { return { name: 0 } }, mounted() { const vm = this; // 使用$on事件來接收參數 Bus.$on('val', (data) => { console.log(data); vm.name = data; }); }, methods: { getDataFunc() { this.name++; } } } </script>
app/index/views/index.vue 代碼改爲以下:
<style lang="stylus"> </style> <template> <div id="app"> <A></A> <B></B> </div> </template> <script type="text/javascript"> import A from './a'; import B from './b'; export default { data() { return { } }, components: { A: A, B: B } } </script>
頁面進來的時候,頁面渲染成以下圖所示
當點擊 A 組件後的點擊觸發後,B組件的值變成了4,以下圖所示:
二:理解使用Vuex
1. 什麼是vuex?
Vuex官網的解釋:Vuex是一個專爲vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
官網的解釋很模糊。其實在vue組件開發中,常常會須要將當前的組件的數據傳遞給其餘的組件,父子組件通訊的話,咱們能夠採用props+emit 這種方式,如上面的demo方式來傳遞數據,可是當通訊雙方不是父子組件甚至根本不存在任何關係的時候,或者說一個狀態須要共享給多個組件的時候,那麼就會很是麻煩,數據維護也至關的很差維護,所以就出現了vuex。它能幫助咱們把公用的狀態抽出來放在vuex的容器中,而後根據必定的規則進行管理。vuex採用了集中式存儲管理全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
2. 怎麼使用vuex?
以下demo使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" src='https://unpkg.com/vue/dist/vue.js'></script> <script type="text/javascript" src='https://unpkg.com/vuex@3.0.1/dist/vuex.js'></script> </head> <body> <div id='app'></div> <script type="text/javascript"> Vue.use(Vuex); // 使用vuex var myStore = new Vuex.Store({ // state是存儲狀態 定義應用狀態全局的數據結構 state: { name: 'kongzhi', todoLists: [] }, /* mutations是提交狀態修改,也就是set、get中的set,這是vuex中惟一修改state的方式,可是不支持異步操做。 每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler) 第一個參數默認是state,外部調用方式爲:store.commit('SET_AGE', 30). */ mutations: { // 新增list ADDLIST(state, item) { state.todoLists.push(item); }, // 刪除list中的項 DELLIST(state, index) { state.todoLists.splice(index, 1); }, // 設置 錯誤提示信息 SETERROR(state, msg) { state.message = msg; } }, /* getters是從state中派生出狀態的。也就是set、get中的get,它有兩個可選的參數,state和getters, 分別能夠獲取state中的變量和其餘的getters。外部調用的方式:store.getters.todoCount() */ getters: { todoCount(state) { return state.todoLists.length; } }, /* 和上面的mutations相似,可是actions支持異步操做的,外部調用方式爲:store.dispatch('nameAction') 常見的使用是:從服務器端獲取數據,在數據獲取完成後會調用 store.commit()來更改Store中的狀態。 Action函數接收一個與store實列具備相同方法和屬性的context對象,所以咱們可使用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters來獲取state和getters */ actions: { addList(context, item) { if (item) { context.commit('ADDLIST', item); context.commit('SETERROR', ''); } else { context.commit('SETERROR', '添加失敗'); } }, delList(context, index) { context.commit('DELLIST', index); context.commit('SETERROR', '刪除成功'); } }, /* modules 對象容許將單一的Store拆分爲多個Store的同時保存在單一的狀態樹中。 */ modules: { } }); new Vue({ el: '#app', data: { name: 'init name' }, store: myStore, mounted: function() { console.log(this); } }) </script> </body> </html>
如上代碼,new Vuex.store({}) 含義是建立一個Vuex實列。store是vuex的一個核心方法,字面含義爲 '倉庫'的意思。實列化完成後,須要注入到vue實列中,它有五個核心的選項,state、mutations、getters、actions和modules。以下圖所示:
3. vuex中如何獲取state的數據呢?
下面咱們來註冊一個組件,那麼在組件內部中的computed來獲取state的數據(computed是實時響應的)。以下代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" src='https://unpkg.com/vue/dist/vue.js'></script> <script type="text/javascript" src='https://unpkg.com/vuex@3.0.1/dist/vuex.js'></script> </head> <body> <div id='app'> <xxx></xxx> </div> <script type="text/javascript"> Vue.use(Vuex); // 使用vuex var myStore = new Vuex.Store({ // state是存儲狀態 定義應用狀態全局的數據結構 state: { name: 'kongzhi', todoLists: [] }, /* mutations是提交狀態修改,也就是set、get中的set,這是vuex中惟一修改state的方式,可是不支持異步操做。 每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler) 第一個參數默認是state,外部調用方式爲:store.commit('SET_AGE', 30). */ mutations: { // 新增list ADDLIST(state, item) { state.todoLists.push(item); }, // 刪除list中的項 DELLIST(state, index) { state.todoLists.splice(index, 1); }, // 設置 錯誤提示信息 SETERROR(state, msg) { state.message = msg; } }, /* getters是從state中派生出狀態的。也就是set、get中的get,它有兩個可選的參數,state和getters, 分別能夠獲取state中的變量和其餘的getters。外部調用的方式:store.getters.todoCount() */ getters: { todoCount(state) { return state.todoLists.length; } }, /* 和上面的mutations相似,可是actions支持異步操做的,外部調用方式爲:store.dispatch('nameAction') 常見的使用是:從服務器端獲取數據,在數據獲取完成後會調用 store.commit()來更改Store中的狀態。 Action函數接收一個與store實列具備相同方法和屬性的context對象,所以咱們可使用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters來獲取state和getters */ actions: { addList(context, item) { if (item) { context.commit('ADDLIST', item); context.commit('SETERROR', ''); } else { context.commit('SETERROR', '添加失敗'); } }, delList(context, index) { context.commit('DELLIST', index); context.commit('SETERROR', '刪除成功'); } }, /* modules 對象容許將單一的Store拆分爲多個Store的同時保存在單一的狀態樹中。 */ modules: { } }); // 註冊vue組件 xxx Vue.component('xxx', { template: "<div>{{name}}</div>", computed: { name: function() { console.log(this.$store.state); return this.$store.state.name; } }, mounted: function() { console.log(this); } }); new Vue({ el: '#app', data: { name: 'init name' }, store: myStore, mounted: function() { console.log(this); } }) </script> </body> </html>
運行效果以下圖所示:
4. 如何對state的數據進行篩選和過濾。
有時候,咱們須要對state的數據進行刷選和過濾操做,好比後臺請求回來的數據,咱們須要進行數據過濾操做,getters就能夠了。具體代碼能夠看以下demo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" src='https://unpkg.com/vue/dist/vue.js'></script> <script type="text/javascript" src='https://unpkg.com/vuex@3.0.1/dist/vuex.js'></script> </head> <body> <div id='app'> <xxx></xxx> </div> <script type="text/javascript"> Vue.use(Vuex); // 使用vuex var myStore = new Vuex.Store({ // state是存儲狀態 定義應用狀態全局的數據結構 state: { name: 'kongzhi', todoLists: [] }, /* mutations是提交狀態修改,也就是set、get中的set,這是vuex中惟一修改state的方式,可是不支持異步操做。 每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler) 第一個參數默認是state,外部調用方式爲:store.commit('SET_AGE', 30). */ mutations: { // 新增list ADDLIST(state, item) { state.todoLists.push(item); }, // 刪除list中的項 DELLIST(state, index) { state.todoLists.splice(index, 1); }, // 設置 錯誤提示信息 SETERROR(state, msg) { state.message = msg; } }, /* getters是從state中派生出狀態的。也就是set、get中的get,它有兩個可選的參數,state和getters, 分別能夠獲取state中的變量和其餘的getters。外部調用的方式:store.getters.todoCount() */ getters: { todoCount(state) { return state.todoLists.length; } }, /* 和上面的mutations相似,可是actions支持異步操做的,外部調用方式爲:store.dispatch('nameAction') 常見的使用是:從服務器端獲取數據,在數據獲取完成後會調用 store.commit()來更改Store中的狀態。 Action函數接收一個與store實列具備相同方法和屬性的context對象,所以咱們可使用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters來獲取state和getters */ actions: { addList(context, item) { if (item) { context.commit('ADDLIST', item); context.commit('SETERROR', ''); } else { context.commit('SETERROR', '添加失敗'); } }, delList(context, index) { context.commit('DELLIST', index); context.commit('SETERROR', '刪除成功'); } }, /* modules 對象容許將單一的Store拆分爲多個Store的同時保存在單一的狀態樹中。 */ modules: { } }); // 註冊vue組件 xxx Vue.component('xxx', { template: "<div>{{name}}, 總數:{{todoCount}}</div>", computed: { name: function() { console.log(this.$store.state); return this.$store.state.name; }, todoCount: function() { return this.$store.getters.todoCount; } }, mounted: function() { console.log(this); }, }); new Vue({ el: '#app', data: { name: 'init name' }, store: myStore, mounted: function() { console.log(this); } }) </script> </body> </html>
運行效果 以下圖所示
5. mutations操做來改變state數據
如上是如何獲取state的數據了,那麼如今咱們使用mutations來改變state的數據了,在Vuex中,改變狀態state的惟一方式是經過提交commit的一個mutations,mutations下的對應函數接收第一個參數state,第二個參數爲payload(載荷),payload通常是一個對象,用來記錄開發時使用該函數的一些信息。mutations是處理同步的請求。不能處理異步請求的。看以下demo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" src='https://unpkg.com/vue/dist/vue.js'></script> <script type="text/javascript" src='https://unpkg.com/vuex@3.0.1/dist/vuex.js'></script> </head> <body> <div id='app'> <xxx></xxx> </div> <script type="text/javascript"> Vue.use(Vuex); // 使用vuex var myStore = new Vuex.Store({ // state是存儲狀態 定義應用狀態全局的數據結構 state: { name: 'kongzhi', todoLists: [] }, /* mutations是提交狀態修改,也就是set、get中的set,這是vuex中惟一修改state的方式,可是不支持異步操做。 每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler) 第一個參數默認是state,外部調用方式爲:store.commit('SET_AGE', 30). */ mutations: { // 新增list ADDLIST(state, item) { console.log(state.todoLists); state.todoLists.push(item); }, // 刪除list中的項 DELLIST(state, index) { state.todoLists.splice(index, 1); }, // 設置 錯誤提示信息 SETERROR(state, msg) { state.message = msg; } }, /* getters是從state中派生出狀態的。也就是set、get中的get,它有兩個可選的參數,state和getters, 分別能夠獲取state中的變量和其餘的getters。外部調用的方式:store.getters.todoCount() */ getters: { todoCount(state) { return state.todoLists.length; } }, /* 和上面的mutations相似,可是actions支持異步操做的,外部調用方式爲:store.dispatch('nameAction') 常見的使用是:從服務器端獲取數據,在數據獲取完成後會調用 store.commit()來更改Store中的狀態。 Action函數接收一個與store實列具備相同方法和屬性的context對象,所以咱們可使用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters來獲取state和getters */ actions: { addList(context, item) { if (item) { context.commit('ADDLIST', item); context.commit('SETERROR', ''); } else { context.commit('SETERROR', '添加失敗'); } }, delList(context, index) { context.commit('DELLIST', index); context.commit('SETERROR', '刪除成功'); } }, /* modules 對象容許將單一的Store拆分爲多個Store的同時保存在單一的狀態樹中。 */ modules: { } }); // 註冊vue組件 xxx Vue.component('xxx', { template: "<div>{{name}}, 總數:{{todoCount}} <span @click='addList'>點擊改變總數</span></div>", computed: { name: function() { return this.$store.state.name; }, todoCount: function() { return this.$store.getters.todoCount; } }, mounted: function() { console.log(this); }, data: function() { return { count: 0 } }, methods: { addList: function() { var count = this.count++; this.$store.commit('ADDLIST', count); } } }); new Vue({ el: '#app', data: { name: 'init name' }, store: myStore, mounted: function() { console.log(this); } }) </script> </body> </html>
如上代碼,在組件xxx中的template添加代碼 <span @click='addList'>點擊改變總數</span>,每次點擊的時候,會調用自身內部的addList的函數,而後count自增1,而後會繼續調用 this.$store.commit('ADDLIST', count); 來提交 commit的一個mutations,所以state.todoLists.push(item);會增長一項數據後,在組件xxx內部經過 todoCount 能夠實時獲取到數據的改變狀態。
6. actions操做mutations異步來改變state數據
actions能夠異步操做,actions提交mutations,經過mutations來提交數據的變動。它是異步修改state的狀態的。
外部調用方式是 this.$store.dispatch('nameAsyn');
下面咱們看以下demo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" src='https://unpkg.com/vue/dist/vue.js'></script> <script type="text/javascript" src='https://unpkg.com/vuex@3.0.1/dist/vuex.js'></script> </head> <body> <div id='app'> <xxx></xxx> </div> <script type="text/javascript"> Vue.use(Vuex); // 使用vuex var myStore = new Vuex.Store({ // state是存儲狀態 定義應用狀態全局的數據結構 state: { name: 'kongzhi', todoLists: [], // 添加count字段 count: 1 }, /* mutations是提交狀態修改,也就是set、get中的set,這是vuex中惟一修改state的方式,可是不支持異步操做。 每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler) 第一個參數默認是state,外部調用方式爲:store.commit('SET_AGE', 30). */ mutations: { // 新增list ADDLIST(state, item) { console.log(state.todoLists); state.todoLists.push(item); }, // 刪除list中的項 DELLIST(state, index) { state.todoLists.splice(index, 1); }, // 設置 錯誤提示信息 SETERROR(state, msg) { state.message = msg; }, // 異步操做count COUNTASYNC(state, param) { console.log(state.count += param); } }, /* getters是從state中派生出狀態的。也就是set、get中的get,它有兩個可選的參數,state和getters, 分別能夠獲取state中的變量和其餘的getters。外部調用的方式:store.getters.todoCount() */ getters: { todoCount(state) { return state.todoLists.length; } }, /* 和上面的mutations相似,可是actions支持異步操做的,外部調用方式爲:store.dispatch('nameAction') 常見的使用是:從服務器端獲取數據,在數據獲取完成後會調用 store.commit()來更改Store中的狀態。 Action函數接收一個與store實列具備相同方法和屬性的context對象,所以咱們可使用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters來獲取state和getters */ actions: { addList(context, item) { if (item) { context.commit('ADDLIST', item); context.commit('SETERROR', ''); } else { context.commit('SETERROR', '添加失敗'); } }, delList(context, index) { context.commit('DELLIST', index); context.commit('SETERROR', '刪除成功'); }, // 設置延時來演示一下異步提交 addFunc(context, value) { console.log(context); setTimeout(function(){ // 異步提交 actions操做Mutations context.commit('COUNTASYNC', value); }, 100); } }, /* modules 對象容許將單一的Store拆分爲多個Store的同時保存在單一的狀態樹中。 */ modules: { } }); // 註冊vue組件 xxx Vue.component('xxx', { template: `<div> {{name}}, 總數:{{todoCount}} <span @click='addList'>點擊改變總數</span> <button @click='addFuncAnsyc'>點擊我actions改變數據</button> </div>`, computed: { name: function() { return this.$store.state.name; }, todoCount: function() { return this.$store.getters.todoCount; } }, mounted: function() { console.log(this); }, data: function() { return { count: 0 } }, methods: { addList: function() { var count = this.count++; this.$store.commit('ADDLIST', count); }, addFuncAnsyc: function() { this.$store.dispatch('addFunc', 1); } } }); new Vue({ el: '#app', data: { name: 'init name' }, store: myStore, mounted: function() { console.log(this); } }) </script> </body> </html>
如上代碼,template中新增代碼 <button @click='addFuncAnsyc'>點擊我actions改變數據</button>,點擊後,觸發內部函數 addFuncAnsyc後,會調用 this.$store.dispatch('addFunc', 1);調用來操做actions中的方法,第一個參數對應actions中的方法名,第二個是參數值,在actions中的函數 addFunc 打印出 context, 以下圖所示:
addFunc函數會調用 context.commit('COUNTASYNC', value); 代碼,會找到 mutations中對應的COUNTASYNC,而後會對state數據進行更改。
理解context: context是和 this.$store 具備相同的方法和屬性的對象。咱們能夠經過 context.state 和 context.getters來獲取state和getters。
理解dispatch: 它含有異步操做,含義能夠理解爲 '派發',好比向後臺提交數據,能夠爲 this.$store.dispatch('actions方法名', 值);
三:webpack4+vue+route+vuex 項目架構
如上代碼是基本的demo,可是在項目中,咱們是如何配置的呢?下面再來看看使用store來重構項目,整個目錄架構以下:
### 目錄結構以下: demo1 # 工程名 | |--- dist # 打包後生成的目錄文件 | |--- node_modules # 全部的依賴包 | |--- app | | |---index | | | |-- views # 存放全部vue頁面文件 | | | | |-- parent.vue # 父組件 | | | | |-- child.vue # 子組件 | | | | |-- index.vue | | | |-- components # 存放vue公用的組件 | | | |-- js # 存放js文件的 | | | |-- store # store倉庫 | | | | |--- actions.js | | | | |--- mutations.js | | | | |--- state.js | | | | |--- mutations-types.js | | | | |--- index.js | | | |-- app.js # vue入口配置文件 | | | |-- router.js # 路由配置文件 | |--- views | | |-- index.html # html文件 | |--- webpack.config.js # webpack配置文件 | |--- .gitignore | |--- README.md | |--- package.json | |--- .babelrc # babel轉碼文件
在app/index/views 下新建 testvue.vue, 代碼以下:
<template> <div> {{name}}, 總數:{{todoCount}} <span @click='addList'>點擊改變總數</span> <button @click='addFuncAnsyc'>點擊我actions改變數據</button> </div> </template> <script type="text/javascript"> export default { data() { return { name: '我是空智', count: 1, todoLists: [] } }, created() { }, computed: { todoCount: function() { return this.$store.state.add; } }, methods: { addList() { var count = this.count++; this.$store.commit('ADD', count); }, addFuncAnsyc() { const obj = { }; Promise.all([this.$store.dispatch('commonActionGet', ['getPower:COUNTASYNC', obj])]).then((res) => { }); } } } </script>
模板代碼中 <span @click='addList'>點擊改變總數</span> 點擊一下 觸發 addList 函數,該函數會調用 this.$store.commit('ADD', count); 該方法,commit方法是同步的,它會尋找mutations.js對應的 'ADD'函數.
所以,app/index/store/mutations-types.js 代碼能夠改爲以下:
// 新增list export const ADD = 'ADD'; // 設置錯誤提示 export const SETERROR = 'SETERROR'; // 異步操做count export const COUNTASYNC = 'COUNTASYNC';
app/index/store/mutations.js 代碼改形成以下:
import * as types from './mutations-types'; export default { [types.ADD] (state, payload) { state.add = payload; }, [types.SETERROR] (state, payload) { state.errors = payload; }, [types.COUNTASYNC] (state, payload) { state.counts = payload; } }
app/index/store/state.js 改造代碼以下:
export default { add: 0, errors: '', counts: 0 };
app/index/store/actions.js 改造代碼以下, 封裝了常見的ajax中的get和POST方法:
import * as types from './mutations-types'; import Vue from 'vue'; const ajaxHandle = () => { const buildUrl = (url, params, childParams) => { let str = '?' for (const key in params) { url += str + key + '=' + params[key]; str = '&'; } if (childParams) { return url + '/' + childParams; } return url; }; const ajaxGet = (url, fn) => { let results = null; Vue.http.get(url, { emulateJSON: true, credentials: true }).then((response) => { if (response.ok) { results = response.body; fn && fn(1, results); } else { fn && fn(0, results); } }, (error) => { if (error) { fn && fn(0, results); } }); }; const ajaxGetJSON = (url, fn) => { let results = null; Vue.http.get(url, { credentials: true }).then((response) => { if (response.ok) { results = response.body; fn && fn(1, results); } else { fn && fn(0, results); } }, (error) => { if (error) { fn && fn(0, results); } }); }; const ajaxPost = (url, params, options, fn) => { let results = null; if (typeof options === 'function' && arguments.length <= 3) { fn = options; options = {}; } Vue.http.interceptors.push((request, next) => { request.credentials = true; next(); }); Vue.http.post(url, params, { emulateJSON: true }).then((response) => { if (response.ok) { results = response.body; fn && fn(1, results); } else { fn && fn(0, results); } }, (error) => { if (error) { fn && fn(0, results); } }) }; const ajaxPostJSON = (url, params, options, fn) => { let results = null; if (typeof options === 'function' && arguments.length <= 3) { fn = options; options = {}; } Vue.http.interceptors.push((request, next) => { request.credentials = true; next(); }); Vue.http.post(url, params).then((response) => { if (response.ok) { results = response.body; fn && fn(1, results); } else { fn && fn(0, results); } }, (error) => { if (error) { fn && fn(0, results); } }) }; return { buildUrl: buildUrl, ajaxGet: ajaxGet, ajaxGetJSON: ajaxGetJSON, ajaxPost: ajaxPost, ajaxPostJSON: ajaxPostJSON } }; const ah = ajaxHandle(); const prefix = '//xxx.abc.com'; const apiObj = { API_GET_POWER: prefix + '/xxxx/yyy', // 獲取用戶信息 }; const apiFuncObj = { getPower: 'API_GET_POWER', // 獲取用戶信息 }; export default { commonActionPost ({ commit }, payload) { let url = apiObj[apiFuncObj[payload[0].split(':')[0]]]; const mutationsName = payload[0].split(':')[1]; const params = payload[1] ? payload[1] : {}; return new Promise((reslove, reject) => { ah.ajaxPost(url, params, (state, results) => { if (state) { reslove(results); } else { reject(); } if (mutationsName) { commit(mutationsName, results); } }); }); }, commonActionPostJSON({ commit }, payload) { let url = apiObj[apiFuncObj[payload[0].split(':')[0]]]; const mutationsName = payload[0].split(':')[1]; const params = payload[1] ? payload[1] : {}; return new Promise((reslove, reject) => { ah.ajaxPostJSON(url, params, (state, results) => { if (state) { reslove(results); } else { reject(); } if (mutationsName) { commit(mutationsName, results); } }); }); }, commonActionGet ({ commit }, payload) { let url = apiObj[apiFuncObj[payload[0].split(':')[0]]]; const mutationsName = payload[0].split(':')[1]; const params = payload[1] ? payload[1] : {}; const childParams = payload[2] ? payload[2] : ''; url = ah.buildUrl(url, params, childParams); return new Promise((reslove, reject) => { ah.ajaxGet(url, (state, results) => { if (state) { reslove(results); } else { reject(); } if (mutationsName) { commit(mutationsName, results); } }); }); }, commonActionGetJSON ({ commit }, payload) { let url = apiObj[apiFuncObj[payload[0].split(':')[0]]]; const mutationsName = payload[0].split(':')[1]; const params = payload[1] ? payload[1] : {}; url = ah.buildUrl(url, params); return new Promise((reslove, reject) => { ah.ajaxGetJSON(url, (state, results) => { if (state) { reslove(results); } else { reject(); } if (mutationsName) { commit(mutationsName, results); } }); }); } }
app/index/store/index.js 改造代碼以下
import Vue from 'vue'; import Vuex from 'vuex'; import state from './state'; import mutations from './mutations'; import actions from './actions'; Vue.use(Vuex); Vue.config.devtools = true; export default new Vuex.Store({ state, mutations, actions });
而後在咱們入口文件 app/index/app.js 引入store便可,以下代碼:
import Vue from 'vue'; // 添加store import store from './store/index'; // 暫時先用 vue-resource 演示 import VueResource from 'vue-resource'; import Index from './views/index'; // 引入路由 import router from './router'; // Resource Vue.use(VueResource); new Vue({ el: '#app', router: router, // vue實列添加store store: store, render: h => h(Index) });