圖片來源:pixiv 63737968javascript
學習 vue 過程當中的筆記,未完更新中 ... 完整【示例代碼】請去個人 GitHub 倉庫 pero-vue 查看php
更新於 2017.12.24
首發於夏味的博客: xiaweiss.comcss
注意本筆記使用的版本爲當時的最新穩定版html
首先須要安裝 node, 而後使用命令 npm install 依賴名稱
來安裝vue
import()
時才須要)項目根目錄下,建立 webpack.config.js
配置文件java
const path = require('path'); //node 內置模塊
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 用於在 html 頁面裏自動插入資源引用的標籤
const webpack = require('webpack'); //使用 webpack 內置的插件時,須要引入 webpack
module.exports = {
entry: {
index: './src/index.js' // 入口文件
// bbb: './src/bbb.js' // 能夠多個入口文件
},
output: {
path: path.resolve('./dist'), // 輸出路徑,必須是絕對路徑.path.resolve是nodeJS模塊方法,把相對路徑轉爲絕對路徑
// 或者使用語法__dirname +'/dist' 或 path.join(__dirname,'dist')
// __dirname 表示當前模塊的目錄的絕對路徑(並不是全局變量,等價於path.dirname(__filename))
// path.join用於處理鏈接路徑時,統一不一樣系統路徑符\和/問題。
// publicPath: '/assets/', // 發佈路徑,填寫此項後,打包後文件路徑再也不是相對路徑,而是基於服務器根目錄的路徑,
filename: 'js/[name].js', // [name] 表示塊的名稱,輸出文件名,能夠包含路徑
chunkFilename: 'js/[name].js' //webpack 分割後的文件,[id] 表示塊的編號。[name] 表示塊的名稱,沒有名稱時會自動使用編號
},
resolve: {
alias: {
vue$: 'vue/dist/vue.esm.js' // 默認是運行時構建,這裏使用了template,必須用運行+編譯時構建
}
},
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }, //使用 babel 對 js 轉譯
{
test: /\.vue$/,
exclude: /node_modules/,
loader: 'babel-loader!vue-loader'
},
// 先使用 vue-loader對 vue 文件轉譯
{ test: /\.css$/, loader: 'style-loader!css-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 輸出文件名,能夠包含路徑
template: 'src/index.html', // 模板文件位置
inject: 'body', //插入位置,也能夠寫 head
hash: true, // 在文件名後面加 hash 值,默認false
chunks: ['index'] // 表示插入的塊,對應 webpack 入口文件中的 index,不寫會插入全部的入口文件
}),
new webpack.HotModuleReplacementPlugin() //若是 devServer 的配置項裏 hot:true ,則須要配置此項
],
externals: {
vue: 'Vue' //打包時排除 vue,vue內容不會被寫入js。
//注意左邊的 vue 是模塊名,右邊的 Vue 是不使用構建工具時的標準變量名,必須是Vue,與import的變量名無關
},
devServer: {
contentBase: './dist/', //表示靜態資源(非webpack編譯產生)文件的目錄位置,
//這個目錄的資源會被放到一樣當成服務器根目錄去
//遇到同名文件,webpack編譯後產生的文件優先級更高
compress: true, //是否壓縮
port: 9000, //端口號
host: '0.0.0.0', //默認是localhost,若是想被外部訪問,這樣設置
historyApiFallback: true, //當使用 history 模式路由時,設置爲true,404頁面會被重定向到主頁,
hot: true // 熱替換,能夠在不刷新頁面的狀況下更新修改後數據,也能夠配置在package.json 的 scripts 裏,加 --hot參數
}
};
複製代碼
項目根目錄下,建立 .babelrc
配置文件node
babel-preset-env
至關於 es2015 ,es2016 ,es2017 及最新版本webpack
{
"presets": ["env"]
}
複製代碼
package.json 文件裏添加配置ios
{
// ...其餘參數
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server"
}
}
複製代碼
而後使用 npm run dev
來啓動 server 使用 npm run build
來打包輸出git
這裏的 build 是本身起的。寫爲 "build": "webpack -p"
, 打包後時壓縮代碼
熱替換指,在不刷新頁面的狀態下,把修改後的結果更新到頁面上
有兩種配置方式
package.json 文件裏添加配置
{
"scripts": {
"dev": "webpack-dev-server --hot"
}
}
複製代碼
webpack.config.js 文件裏添加配置
const webpack = require('webpack');
module.exports = {
// 其餘配置...
plugins: [
// 其餘配置...
new webpack.HotModuleReplacementPlugin()
],
devServer: {
// 其餘配置...
hot: true
}
};
複製代碼
package.json 文件裏依然是 "dev": "webpack-dev-server"
<div id="app">
{{ name }}
</div>
複製代碼
import Vue from 'vue';
let param = {
el: '#app',
data: {
name: 'hello vue'
}
//注意這裏的 data 也可使用這種語法
//data() {
// return {name:'hello vue'}
//}
};
new Vue(param);
複製代碼
<div class="container">
<my-name></my-name>
</div>
複製代碼
import Vue from 'vue';
// 這是一個組件
let meName = {
template: '<div>{{name}}</div>', // 組件的模板,渲染後會替換掉 <my-name></my-name>
data() {
return {
name: 'xiawei'
}; // 組件中 data 必須是函數,數據 return 出去,不能夠寫爲 data:{name:'xiawei'}
}
};
new Vue({
el: '.container',
components: {
'my-name': meName
}
});
複製代碼
爲了方便,可使用 vue 文件 來封裝組件,能夠認爲一個 vue 文件是一個組件,子組件繼續使用其餘 vue 文件 引入。
index.js
import Vue from 'vue';
import myname from './components/myname.vue';
new Vue({
el: '.container',
components: {
'my-name': myname
}
});
複製代碼
myname.vue
<template>
<div>
{{name}}
</div>
</template>
<script> export default { data() { return { name: 'xiawei' }; } }; </script>
<style lang="css" scoped> </style>
複製代碼
template 裏,必須用一個 div 或者一個其餘標籤,包裹住全部的 html 標籤
默認 lang="css" 能夠省略,須要使用 sass 時,能夠寫 lang="scss" 等
scoped 是 vue 提供的屬性 表示這裏的樣式只能在本組件內生效
<myname value="xiawei"></myname>
複製代碼
<template>
<div>
{{value}}
</div>
</template>
<script> export default { props:['value'] }; </script>
複製代碼
能夠經過 $parent
訪問父組件,$children
訪問子組件
user-login 有三個子組件,部分代碼以下
<template>
<div id="user">
<h2>User Login</h2>
<form>
<user-name></user-name>
<user-pass></user-pass>
<user-submit></user-submit>
</form>
</div>
</template>
複製代碼
這時在 user-submit 組件
<template>
<div>
<button v-on:click="test">submit</button>
<!-- v-on:click="test" 表示點擊事件時,觸發 test 函數 -->
</div>
</template>
<script> export default { methods: { test() { this.$parent.$children[0] //訪問 user-name 組件 this.$parent.$children[1] //訪問 user-pass 組件 //獲取 user-name 組件 data 中 username 的值 this.$parent.$children[0].username } } }; </script>
複製代碼
要區分子組件是第幾個,並不方便,可使用 ref
來解決這個問題
相關代碼修改成如下便可
<user-name ref="uname"></user-name>
<user-pass ref="upass"></user-pass>
複製代碼
//獲取 user-name 組件 data 中 username 的值
this.$parent.$refs.uname.username;
複製代碼
父組件 user-login.vue 裏,給子組件 user-name 設置自定義事件 updateUserName
這個事件是綁定在 user-name 組件上的,在 組件對象 .$listeners
裏能夠查看到,能夠用 組件對象 .$emit
來觸發
$emit 觸發時,參數 1 是事件名,後幾個參數能夠傳給事件對象(相似 jQuery 的trigger 方法)
<template>
<user-name ref="uname" v-on:updateUserName="setUserName"></user-name>
</template>
<script> import username from './user/user-name.vue'; export default { data() { return { username: '' }; }, components: { 'user-name': username }, methods: { setUserName(uname) { this.username = uname; } } }; </script>
複製代碼
子組件 user-name.vue,當輸入框內容改變,觸發 change
事件
而後執行了 $emit
來觸發 updateUserName
事件,this.username
做爲參數傳給了updateUserName
事件
<template>
<input type="text" v-model="username" v-on:change="userNameChange">
</template>
<script> export default { data() { return { username: '' }; }, methods: { userNameChange() { this.$emit('updateUserName', this.username); } } }; </script>
複製代碼
v-if 主要用於渲染模板,下面代碼
當變量 isadmin
爲 true 時,只顯示 Admin Login
反之,只顯示User Login
注意,程序依據 isadmin == true
的結果來判斷
<template>
<h2 v-if="isadmin">Admin Login</h2>
<h2 v-else>User Login</h2>
</template>
複製代碼
在 index.js 添加下面代碼
當瀏覽器路徑 hash 部分(#
號及其後面的部分)變化時,會觸發 hashchange
事件
判斷 hash 的值,各類值走本身的業務邏輯,就能夠切換頁面、改變數據,這就是路由原理
window.onhashchange = function() {
if (window.location.hash === '#admin') {
myvue.$children[0].$data.isadmin = true;
} else {
myvue.$children[0].$data.isadmin = false;
}
};
複製代碼
相關須要掌握的還有 v-for
,參見官方文檔
計算屬性和 data 裏的普通屬性調用時相同的,但定義時不一樣
計算屬性使用函數定義,return 的值,就是計算屬性的值
當計算屬性內的其餘變量的值發生變化時,函數就會執行,運算獲得新的值
因此計算屬性的值是依賴其餘變量的,它沒有初始值,不能夠在 data 裏聲明
下面的例子,經過計算屬性比對輸入的值來篩選 fav.class2
filter 數組方法 返回經過篩選條件的新數組,當 return true
時符合條件被選入。
indexOf 字符串方法 返回符合條件的字符串序號,若是找不到時,會返回數字 -1
,能夠用來匹配字符串相似的方法,還有 indexOf 數組方法
<template>
<input type="text" v-model="inputText" class="form-control">
<table v-if="isShow()" class="table">
<thead>
<tr>
<th>
type 1
</th>
<th>
type 2
</th>
</tr>
</thead>
<tbody>
<tr v-for="fav in getFavs">
<td>{{ fav.class1 }}</td>
<td>{{ fav.class2 }}</td>
</tr>
</tbody>
</table>
</template>
<script> export default { data() { return { favs: [ { class1: 'web', class2: 'js' }, { class1: 'pro', class2: 'java' } ], inputText: '' }; }, methods: { isShow() { return !(this.inputText == ''); } }, computed: { getFavs() { return this.favs.filter(abc => { return abc.class2.indexOf(this.inputText) >= 0; }); } } }; </script>
複製代碼
vue 2.x 的過濾器方法,與 vue 1.x 語法不一樣,並不適合和 v-for
配合使用,計算屬性配合過濾方法來實現。
上節的例子,更復雜一點,數組的狀況 ( 和上面重複的部分沒寫出來,完整代碼請查看github)
getFavs
決定展現第幾條數據,filterClass2
負責對展現出來的數據篩選
<template>
<tr v-for="fav in getFavs">
<td>{{ fav.class1 }}</td>
<td><a v-for="code in filterClass2(fav.class2)">{{ code }} </a></td>
</tr>
</template>
<script> export default { data() { return { favs: [ { class1: 'web', class2: ['js', 'html', 'css', 'jssdk'] }, { class1: 'pro', class2: ['java'] } ] }; }, methods: { filterClass2(class2) { return class2.filter(v => { return v.indexOf(this.inputText) >= 0; }); } }, computed: { getFavs() { return this.favs.filter(abc => { return abc.class2.filter(code => { return code.indexOf(this.inputText) >= 0; }).length > 0; }); } } }; </script>
複製代碼
首先 npm 安裝依賴官方的路由插件 vue-router
index.html
<div class="container">
<page-nav></page-nav>
<router-view></router-view>
</div>
複製代碼
index.js 文件
import Vue from 'vue';
import VueRouter from 'vue-router'; // 引入插件
Vue.use(VueRouter); // 使用插件
import pagenav from './components/page-nav.vue';
import newslist from './components/news-list.vue';
import userlogin from './components/user-login.vue';
const routerConfig = new VueRouter({
routes: [
{ path: '/news', component: newslist },
{ path: '/login', component: userlogin }
]
});
// 全局註冊公共組件(也能夠像原先註冊子組件的方式來作)
Vue.component('page-nav', pagenav);
let myvue = new Vue({
el: '.container',
router: routerConfig
// 路由中引入過子組件了,因此此處不須要再引入子組件
// components: {
// 'page-nav': pagenav,
// 'user-login': userlogin
// }
});
複製代碼
page-nav.vue 的部分代碼
推薦使用 router-link
語法做爲切換按鈕,它默認會渲染成 a
標籤也可使用 a 標籤來作
當某個 router-link
被點擊選中時,vue 會給它的 html 標籤添加上 class router-link-active
能夠經過給 .router-link-active
寫 css 樣式, 來給選中的 router-link
添加樣式
<template>
<ul class="nav navbar-nav">
<li><router-link to="/login">login</router-link></li>
<li><a href="#/news">News</a></li>
</ul>
</template>
複製代碼
引入
import axios from 'axios';
複製代碼
如需全局引入,能夠再加上下面這句,組件內調用時使用 this.$axios
便可
Vue.prototype.$axios = axios;
複製代碼
get 請求
axios
.get('http://localhost:8000/test.php', {
params: {
ID: 12345
}
})
.then(response => {
alert(response.data);
});
複製代碼
post 請求參數 axios 默認轉爲 json 格式
axios
.post('http://localhost:8000/test.php', { name: 'xiawei', age: 20 })
.then(response => {
alert(response.data);
});
複製代碼
鍵值對方式(php 用 $_POST
能夠取到值)
axios.post('http://localhost:8000/test.php', 'name=xiawei&age=20');
複製代碼
也可使用 node 內置模塊來轉換格式
import querystring from 'querystring';
axios.post(
'http://localhost:8000/test.php',
querystring.stringifyname({ name: 'xiawei', age: 20 })
);
複製代碼
這部分的 php 代碼,是放置在項目根目錄的 test.php 文件
<?php
//指定容許其餘域名訪問
header('Access-Control-Allow-Origin:*');
//響應類型
header('Access-Control-Allow-Methods:GET,POST,PUT');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
echo file_get_contents('php://input');//顯示接收到的原始數據
var_export($_POST);
echo 'hello php';
複製代碼
Mac 內置了 php,直接啓動 php 內置服務:到項目根目錄下,Terminal 裏執行下面命令便可
windows 下載 php 後,把 php 目錄添加到系統環境變量 PATH 裏後,一樣執行下面命令
php -S 0.0.0.0:8000
複製代碼
在新聞列表頁,點擊標題跳轉到新聞詳細頁,動態加載新聞內容
index.js 部分代碼
import axios from 'axios';
Vue.prototype.$axios = axios;
const routerConfig = new VueRouter({
routes: [
{ path: '/', component: newslist },// 設置首頁
{ path: '/news', component: newslist, name: 'newslist' },// 能夠給路由設置別名 name
{ path: '/news/:newsid', component: newsdetail, name: 'newsdetail' },// 若是須要參數,使用冒號的來作佔位符
{ path: '/login', component: userlogin, name: 'userlogin' }
]
});
複製代碼
new-list.vue 部分代碼
<template>
<div class="page-header" v-for="news in newslist">
<h2><router-link :to="{ name: 'newsdetail', params: {newsid: news.newsid} }">{{news.title}}</router-link> <small>{{news.pubtime}}</small></h2>
<!-- 這裏的 newsdetail 以及 params 裏左邊的 newsid 是和路由定義時的相關參數對應 -->
<p>{{news.desc}}</p>
</div>
</template>
複製代碼
news-detail.vue 部分代碼
<template>
<div>
<h2> {{ newstTitle }} <small>{{ newsDate }}</small></h2>
<p>{{ newsContent }}</p>
</div>
</template>
<style> </style>
<script> export default { // 生命週期,組件被建立時執行 created() { this.$axios .get('http://localhost:8000/news.php?newsid='+ this.$route.params.newsid) // 能夠經過全局變量 $route.params 來訪問路由裏的變量獲取到新聞編號101 .then(response => { this.newstTitle = response.data.title; this.newsDate = response.data.pubtime; this.newsContent = response.data.desc; }); } }; </script>
複製代碼
經過全局變量 $route 來訪問路由裏的各類數據
例如 $route.params.newsid
能夠得到路由佔位符 :newsid
處的新聞編號值 101
當項目比較大的時候,可使用異步加載組件的方式來按需加載,而不是一次性加載所有組件。
還能夠配合 webpack 代碼分割功能,把打包後的 js,分割成多個 js 文件,作到按需引用。
以前的引入組件的方式是
import userlogin from './components/user-login.vue';
複製代碼
使用 vue 異步加載的方式引入
var userlogin = function(resolve) {
resolve(require('./components/user-login.vue'));
};
複製代碼
使用 ES2015 語法,而且簡化參數名,能夠寫爲
const userlogin = r => {
r(require('./components/user-login.vue'));
};
複製代碼
結合 webpack 代碼分割功能後
const userlogin = r => {
require.ensure([], () => {
r(require('./components/user-login.vue'));
});
};
複製代碼
若是須要把某幾個組件打包爲一組,給它們的 require.ensure()
(文檔1、文檔2)添加最後一個參數(例如'aaa'
),且值相同
require.ensure([], () => {
r(require('./components/user-login.vue'));
},'aaa');
複製代碼
也可使用 webpack + ES2015 語法來進行代碼分割
import()
(文檔) 是 ES2015 草案的語法,因此使用時須要 babel 轉譯
babel 配置裏須要添加草案語法的轉譯 presets stage-2
,npm 安裝依賴 babel-preset-stage-2
.babel
文件,注意配置的數組裏,presets 解析的順序是從右到左的,先執行 stage-2
{
"presets": ["env", "stage-2"]
}
複製代碼
const userlogin = () => import('./components/user-login.vue');
// 也就是 function() { return import('./components/user-login.vue')};
複製代碼
把某幾個文件打包爲一組時,使用這個語法
const userlogin = () => import(/* webpackChunkName: "aaa" */'./components/user-login.vue');
複製代碼
最後分割後的文件名,能夠在 webpack 配置裏 output 配置項裏添加 chunkFilename
配置項來控制
output: {
filename: 'js/[name].js', // [name] 表示塊的名稱,輸出文件名,能夠包含路徑
chunkFilename: 'js/[name].js'
//webpack 分割後的文件,[id] 表示塊的編號。[name] 表示塊的名稱,沒有名稱時會自動使用編號
},
複製代碼
有時現有的插件並不能知足本身的業務需求,這時須要本身開發插件
在 src 文件夾下新建一個 js 文件,好比命名爲 plugin.js
export default {
install(Vue) {
// 添加實例方法
Vue.prototype.$name = 'xiawei';// 能夠在組件內使用 this.$name 取到值 'xiawei'
// 這裏添加時方法來檢測用戶名是否合法,6~20位合法,不然顯示提示
Vue.prototype.checkUserName = value => {
if (value == '') return true;
return /\w{6,20}/.test(value);
};
// 能夠在組件內使用 this.checkUserName(’‘’)
// 添加全局自定義指令 v-uname
Vue.directive('uname', {
bind() {
console.log('begin');
},
update(el, binding, vnode) {
vnode.context[binding.expression] = !/\w{6,20}/.test(el.value);
}
});
}
};
複製代碼
directive
(文檔) 裏的生命週期裏的三個參數:
關於官方文檔裏,添加全局方法或屬性 Vue.myGlobalMethod
和添加實例方法和屬性 Vue.prototype.$myMethod
兩者區別
全局方法或屬性使用 Vue.名稱
來調用,而實例方法和屬性使用 (實例化後的 Vue 對象).名稱
來調用,也就是組件內的常見 this.名稱
來調用,即便看起來名稱同樣的Vue.aaa
和Vue.prototype.aaa
也是兩個不一樣的變量
具體能夠參見這篇文章:js裏面的實例方法和靜態方法
index.js 內加載插件
import plugin from './plugin.js';
Vue.use(plugin);
複製代碼
user-name.vue 添加 v-uname
和 label 元素
<input type="text" v-model="username" v-uname="showErrorLabel" v-on:change="userNameChange" class="form-control" :placeholder="placeholder">
<label v-if="showErrorLabel" class="label label-danger">Please check your username and try again</label>
複製代碼
上面只是控制變量,並非很方便,能夠經過插件動態插入移除提示框
export default {
install(Vue) {
// 建立變量,定義初始值
Vue.errorLabel = null;
Vue.hasErrorLabel = false;
// 這個全局變量來標記是否插入了 label,給初始值時必須放在 update 外面
// 添加全局自定義指令 v-uname
Vue.directive('uname', {
bind(el) {
let error = Vue.extend({
template:
'<label class="label label-danger">Please check your username and try again</label>'
});
Vue.errorLabel = (new error()).$mount().$el;
// $mount() 方法不填參數時,表示把 vm 實例對象變成一個能夠掛載的狀態,這時就能夠訪問到 $el 獲取到元素了
},
update(el, binding, vnode) {
// 這裏每次 update 是從組建原始的狀態 update 的,因此不會重複插入多個
if (/\w{6,20}/.test(el.value)) {
if (Vue.hasErrorLabel) {
el.parentNode.removeChild(Vue.errorLabel);
Vue.hasErrorLabel = !Vue.hasErrorLabel;
}
} else {
if (!Vue.hasErrorLabel) {
el.parentNode.appendChild(Vue.errorLabel);
Vue.hasErrorLabel = !Vue.hasErrorLabel;
}
}
}
});
}
};
複製代碼
user-name.vue 組件裏,這時不須要寫 label 元素,只須要寫入 v-uname
便可
<input type="text" v-model="username" v-uname v-on:change="userNameChange" class="form-control" :placeholder="placeholder">
複製代碼
上一小節的代碼,當有多個 input 元素時,就會出現其餘元素顯示不正常的狀況,緣由是多個標籤共用了同一個 Vue.hasErrorLabel
因此當插件不只僅處理數據時,還須要獨立的處理 dom 元素時,使用子組件的方式更加合理,它們是互相獨立的
export default {
install(Vue) {
Vue.component('p-username', {
template: `<div> <input class="form-control" type="text" v-model="textValue" /> <label class="label label-danger" v-if="showErrorLabel">Please check your username and try again</label> </div>`,
// 這裏使用了 ES2015 的模板字符串語法
data() {
return {
textValue: ''
};
},
computed: {
showErrorLabel() {
return !(/\w{6,20}/.test(this.textValue) || this.textValue == '');
}
}
});
}
};
複製代碼
其中,爲了方便 template 裏使用了 ES2015 的模板字符串語法(參考文檔)
user-name.vue 文件(不須要寫 input 元素)
<p-username></p-username>
複製代碼
應遵循如下規則
也便是與組件的概念相對應的 store -> data getters -> computed mutations/actions -> methods
npm 安裝依賴 vuex
index.js
import Vuex from 'vuex';
Vue.use(Vuex);
const vuex_store = new Vuex.Store({
state: {
user_name: ''
},
mutations: {
showUserName(state) {
alert(state.user_name);
}
}
});
複製代碼
賦值:user-name.vue 組件中使用
<div class="page-header" v-for="news in $store.state.newslist">
複製代碼
this.$store.state.user_name = this.username;
複製代碼
觸發:user-submit.vue 組件中使用
this.$store.commit('showUserName');
複製代碼
便可完成簡單的輸入用戶名,點提交按鈕後 alert 出用戶名
vuex 裏的計算屬性使用的是 getters
,用法和 組件裏的計算屬性 computed
相似,只是被觸發的時機不一樣
從數據裏展現沒有刪除的新聞展現
index.js
const vuex_store = new Vuex.Store({
state: {
user_name: '',
newslist: []
},
mutations: {
showUserName(state) {
alert(state.user_name);
}
},
getters: {
getNews(state) {
return state.newslist.filter(news => !news.isdeleted);
}
}
});
複製代碼
news-list.vue
<div class="page-header" v-for="news in $store.getters.getNews">
複製代碼
export default {
created() {
if (this.$store.state.newslist.length == 0) {
this.$axios.get('http://localhost:8000/news.php').then(response => {
this.$store.state.newslist = response.data;
});
}
}
};
複製代碼
mutations 是同步執行的,裏面不能放異步執行的東西 actions 裏放異步執行的,異步執行完後,去手動觸發 mutations
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context,param) {
// 異步業務 param -> param2
context.commit('increment',param2);
}
}
})
複製代碼
組件內觸發
this.$store.dispatch('increment',param);
複製代碼
以前寫的 index.js 是這樣
const vuex_store = new Vuex.Store({
state: {
user_name: '',
newslist: []
},
mutations: {
showUserName(state) {
alert(state.user_name);
}
},
getters: {
getNews(state) {
return state.newslist.filter(news => !news.isdeleted);
}
}
});
複製代碼
按模塊分離後
index.js
import news_module from './store/news.js';
import users_module from './store/users.js';
const vuex_store = new Vuex.Store({
modules: {
news: news_module,
users: users_module
}
});
複製代碼
news.js
export default {
state: {
newslist: []
},
getters: {
getNews(state) {
return state.newslist.filter(news => !news.isdeleted);
}
}
}
複製代碼
users.js
export default {
state: {
user_name: ''
},
mutations: {
showUserName(state) {
alert(state.user_name);
}
}
}
複製代碼
分離後,注意相關模塊裏的 this.$store.state
按業務模塊名分別改成 this.$store.state.news
、this.$store.state.users
注意不一樣業務模塊裏,getters 裏函數重名了會報錯, mutations 裏函數重名了會兩邊都執行