前言
本文主要说明Vue的核心内容---组件间的通信。文中将使用几个栗子来了解,本文示例基于Vue2.0。
- 父子组件间的通信
- 单一事件中心管理组件通信
- 集中式管理数据Vuex
父子组件间的通信---props
使用子组件获取父组件的数据
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="wrap">
<b>我是父组件 ---- </b><span>{{msg}}</span>
<child-com :msgdata='msg'></child-com><!-- 将 prop 绑定到父组件的数据 -->
</div>
<!-- 子组件 -->
<template id="child">
<div>
<b>我是子组件 ---- </b>
<span>{{msgdata}}</span>
</div>
</template>
</body>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
new Vue({
el:'#wrap',
data:{
msg:'我是父组件的数据'
},
components:{
'child-com':{
props:['msgdata'],//声明 props
template:'#child'
}
}
})
</script>
</html>
效果
使用子组件修改父组件的数据
vue不允许子组件直接给父组件的对象赋值,如果需要修改父组件的数据,则需要
父组件每次传一个对象给子组件,使用对象之间引用(对对象中的属性赋值)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="wrap">
<b>我是父组件----</b><span>{{giveData.msg}}</span>
<child-com :msgdata='giveData'></child-com>
</div>
<template id="child">
<div>
<b>我是子组件</b>
<button type="button" name="button" @click='change'>修改数据</button>
<span>{{msgdata.msg}}</span>
</div>
</template>
</body>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
new Vue({
el:'#wrap',
data:{
giveData:{
msg:'我是父组件的数据'
}
},
components:{
'child-com':{
props:['msgdata'],
template:'#child',
methods:{
change(){
this.msgdata.msg = '已修改'
}
}
}
}
})
</script>
</html
效果
点击修改数据按钮
vue
单一事件中心管理组件通信
核心内容
var Event= new Vue();
Event.on(数据名称,function(data){
//data
}.bind(this));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="wrap">
<com-a></com-a>
<com-b></com-b>
<com-c></com-c>
</div>
</body>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
//准备一个空的实例对象
var Event = new Vue();
//定义组件
var A={
template:`<div>
<b>我是A组件 ---- </b><span>{{a}}</span>
<button type="button" name="button" @click='send'>把A数据给C</button>
</div>`,
data(){
return {
a:'我是a数据'
}
},
methods:{
send(){
Event.$emit('a-msg',this.a)
}
}
};
var B={
template:`<div>
<b>我是B组件 ---- </b><span>{{b}}</span>
<button type="button" name="button" @click='send'>把B数据给C</button>
</div>`,
data(){
return {
b:'我是b数据'
}
},
methods:{
send(){
Event.$emit('b-msg',this.b)
}
}
};
var C={
template:`<div>
<p><b>我是C组件</b></p>
<span>接收a组件的数据:{{a}}</span><br/>
<span>接收b组件的数据:{{b}}</span>
</div>`,
data(){
return {
a:'',
b:''
}
},
mounted(){
//接收a组件的数据
Event.$on('a-msg',function(a){
this.a = a;
}.bind(this));
//接收b组件的数据
Event.$on('b-msg',function(b){
this.b = b;
}.bind(this));
}
};
new Vue({
el:'#wrap',
data:{},
components:{
'com-a':A,
'com-b':B,
'com-c':C,
}
})
</script>
</html>
效果
状态管理Vuex
Vuex提供的两个主要方法
- mapActions 管理所有时间(行为)
- mapGetters 获取数据
简单栗子(组建通信少时可以使用,组件通信多请看最后一个栗子)
创建项目(此处不多说明)具体看官网
安装Vuex
npm install vuex -D
目录结构App.vue
<template>
<div id="app">
<b>vuex-domo</b><br /><br />
<input type="button" name="" id="" value="+" @click='increment'/>
<input type="button" name="" id="" value="-" @click='decrement'/>
<input type="button" name="" id="" value="偶数时+" @click='clickOdd'/>
<input type="button" name="" id="" value="点击异步" @click='clickAsync'/>
<p>现在的数字为:{{count}}{{getOdd}}</p>
</div>
</template>
<script>
import {mapGetters,mapActions} from 'vuex'
export default{
computed:mapGetters([//获取数据
'count',
'getOdd'
]),
methods:mapActions([//管理所有事件(行为)
'increment',
'decrement',
'clickOdd',
'clickAsync'
])
}
</script>
<style>
#app {
text-align: center;
}
</style>
main.js
import Vue from 'vue'
import App from './App.vue'
//引入store
import store from './store.js'
new Vue({
store,
el: '#app',
render: h => h(App)
})
新建一个store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
var state={//数据
count:10
};
const mutations={//处理数据(状态)变化
increment(state){
state.count++;
},
decrement(state){
state.count--;
},
};
const actions = {//处理你要干什么(异步请求,判断,流程控制)
increment:({commit})=>{
commit('increment')//提交到mutations
},
decrement:({commit})=>{
commit('decrement')
},
clickOdd:({commit,state})=>{
if(state.count%2==0){
commit('increment')
}
},
clickAsync:({commit})=>{//异步
new Promise((resolve)=>{
setTimeout(function(){
commit('increment');
resolve();
},1000)
})
}
};
const getters={//mapGetters获取到的数据
count(state){
return state.count
},
getOdd(state){
return state.count%2==0?'偶数':'奇数'
}
};
//导出store对象
export default new Vuex.Store({
state,
mutations,
actions,
getters
});
效果Vuex
目录结构(把store单独放在一个文件夹,次项目就是把上面项目的store分开管理)
app.vue
<template>
<div id="app">
<b>vuex-domo</b><br /><br />
<input type="button" name="" id="" value="+" @click='increment'/>
<input type="button" name="" id="" value="-" @click='decrement'/>
<input type="button" name="" id="" value="偶数时+" @click='clickOdd'/>
<input type="button" name="" id="" value="点击异步" @click='clickAsync'/>
<p>现在的数字为:{{count}}{{getOdd}}</p>
</div>
</template>
<script>
import {mapGetters,mapActions} from 'vuex'
export default{
computed:mapGetters([//获取数据
'count',
'getOdd'
]),
methods:mapActions([//管理所有时间(行为)
'increment',
'decrement',
'clickOdd',
'clickAsync'
])
}
</script>
<style>
#app {
text-align: center;
}
</style>
main.js
import Vue from 'vue'
import App from './App.vue'
//引入store文件夹
import store from './store/'
new Vue({
store,
el: '#app',
render: h => h(App)
})
新建store文件夹,并新建以下几个js文件
新建index.js文件(此文件为入口文件)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
import actions from './actions'
import mutations from './mutations'
export default new Vuex.Store({
modules:{
mutations
},
actions
});
新建actions.js(处理异步请求,判断,流程控制等)
import * as types from './types'
export default{
increment:({commit})=>{
commit(types.INCREMENT);
},
decrement:({commit})=>{
commit(types.DECREMENT);
},
clickOdd:({commit,state})=>{
if(state.mutations.count%2==0){
commit(types.INCREMENT);
}
},
clickAsync:({commit})=>{
new Promise((resolve)=>{
setTimeout(function(){
commit(types.INCREMENT);
},1000);
})
}
}
新建mutations.js(处理数据/状态变化)
import * as types from './types'
import getters from './getters'
const state={
count:20
};
const mutations={
[types.INCREMENT](state){
state.count++;
},
[types.DECREMENT](state){
state.count--;
}
};
export default{
state,
mutations,
getters
}
新建getters.js(mapGetters获取到的数据)
export default{
count:(state)=>{
return state.count
},
getOdd:(state)=>{
return state.count%2==0?'偶数':'奇数'
}
}
新建types.js
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
效果注:本文内容参考于智能社,在此感谢!
By:Yimi-珊