一、父子传值
1. props传递单个参数
· 父组件
<template>
<div class="app-container">
<Pagination :page="currentPage" @changePage="listenPageChange"/>
</div>
</template>
<script>
import Pagination from './components/pagination';
export default {
components:{
Pagination
},
methods:{
listenPageChange(data){
console.log(data);
}
},
data() {
return {
currentPage:1
}
};
</script>
·子组件
<template>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page"
:page-sizes="[100, 200, 300, 400]"
:page-size="100"
layout="total, sizes, prev, pager, next, jumper"
:total="400"
></el-pagination>
</template>
<script>
export default {
props: ["page"],
methods: {
handleSizeChange(val) {
this.pageOption.pageSize = val;
this.listenOptionChange(this.pageOption);
},
handleCurrentChange(val) {
this.pageOption.page = val;
this.listenOptionChange(this.pageOption);
},
listenOptionChange(datas) {
this.$emit("changePage", datas);
}
}
};
</script>
2. props传递对象
·父组件
<template>
<div class="p-5">
<Pagination :pageOption="pageOptions" />
</div>
</template>
<script>
import Pagination from './components/pagination';
export default {
data () {
return {
pageOptions:{
page:1,
pageSize:10,
pageSizes:[10,20,30,40],
total:40
}
};
},
components: {
Pagination
}
}
</script>
· 子组件
<template>
<div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="propOptions.page"
:page-sizes="propOptions.pageSizes"
:page-size="propOptions.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="propOptions.total"
></el-pagination>
</div>
</template>
<script>
export default {
props: ["page-option"],
data() {
return {
propOptions:this.pageOption
};
},
methods: {
handleSizeChange(val) {
this.propOptions.pageSize=val;
},
handleCurrentChange(val) {
this.propOptions.page=val;
}
}
};
</script>
二、兄弟组件传值
1. 借助事件车
· 自定义公用组件bus.js
自定义创建bus.js,兄弟组件共同引用此js,bus.js内容:
import Vue from 'vue';
var VueEvent=new Vue();
export default VueEvent;
· 兄弟组件a
<template>
<div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="propOptions.page"
:page-sizes="propOptions.pageSizes"
:page-size="propOptions.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="propOptions.total"
></el-pagination>
</div>
</template>
<script>
import Bus from './bus.js';
export default {
props: ["page-option"],
data() {
return {
propOptions:this.pageOption
};
},
methods: {
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
Bus.$emit('pageChangeTo',val);
}
}
};
</script>
· 兄弟组件b
<template>
<div>
<el-steps :active="pageOption.page" align-center>
<el-step title="步骤1" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤2" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤3" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤4" description="这是一段很长很长很长的描述性文字"></el-step>
</el-steps>
</div>
</template>
<script>
import Bus from "./bus.js";
export default {
data() {
return {
pageOption: {
page: 1
}
};
},
mounted() {
this.listenPageChange();
},
methods: {
listenPageChange() {
Bus.$on("pageChangeTo", val => {
this.pageOption.page = val;
});
}
}
};
</script>
三、Vuex传值
1. 开始使用vuex,新建一个 sotre文件夹,分开维护 actions mutations getters
2. 在store/index.js文件中新建vuex 的store实例
import Vue from 'vue'
import Vuex from 'vuex'
import * as getters from './getters' // 导入响应的模块,*相当于引入了这个组件下所有导出的事例
import * as actions from './actions'
import * as mutations from './mutations'
Vue.use(Vuex)
// 首先声明一个需要全局维护的状态 state,比如 我这里举例的resturantName
const state = {
resturantName: '飞歌餐馆' // 默认值
// id: xxx 如果还有全局状态也可以在这里添加
// name:xxx
}
// 注册上面引入的各大模块
const store = new Vuex.Store({
state, // 共同维护的一个状态,state里面可以是很多个全局状态
getters, // 获取数据并渲染
actions, // 数据的异步操作
mutations // 处理数据的唯一途径,state的改变或赋值只能在这里
})
export default store // 导出store并在 main.js中引用注册。
3.actions
// 给action注册事件处理函数。当这个函数被触发时候,将状态提交到mutations中处理
export function modifyAName({commit}, name) { // commit 提交;name即为点击后传递过来的参数,此时是 'A餐馆'
return commit ('modifyAName', name)
}
export function modifyBName({commit}, name) {
return commit ('modifyBName', name)
}
// ES6精简写法
// export const modifyAName = ({commit},name) => commit('modifyAName', name)
4.mutations
// 提交 mutations是更改Vuex状态的唯一合法方法
export const modifyAName = (state, name) => { // A组件点击更改餐馆名称为 A餐馆
state.resturantName = name // 把方法传递过来的参数,赋值给state中的resturantName
}
export const modifyBName = (state, name) => { // B组件点击更改餐馆名称为 B餐馆
state.resturantName = name
}
5.getters
// 获取最终的状态信息
export const resturantName = state => state.resturantName
6.在main.js中导入 store实例
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, // 这样就能全局使用vuex了
components: { App },
template: '<App/>'
})
7.在组件A中,定义点击事件,点击 修改 餐馆的名称,并把餐馆的名称在事件中用参数进行传递。
…mapactions 和 …mapgetters都是vuex提供的语法糖,在底层已经封装好了,拿来就能用,简化了很多操作。
其中…mapActions([‘clickAFn’]) 相当于this.$store.dispatch(‘clickAFn’,{参数}),mapActions中只需要指定方法名即可,参数省略。
…mapGetters([‘resturantName’])相当于this.$store.getters.resturantName
<template>
<div class="componentsA">
<P class="title">组件A</P>
<P class="titleName">餐馆名称:{{resturantName}}</P>
<div>
<!-- 点击修改 为 A 餐馆 -->
<button class="btn" @click="modifyAName('A餐馆')">修改为A餐馆</button>
</div>
<div class="marTop">
<button class="btn" @click="trunToB">跳转到B页面</button>
</div>
</div>
</template>
<script>
import {mapActions, mapGetters} from 'vuex'
export default {
name: 'A',
data () {
return {
}
},
methods:{
...mapActions( // 语法糖
['modifyAName'] // 相当于this.$store.dispatch('modifyName'),提交这个方法
),
trunToB () {
this.$router.push({path: '/componentsB'}) // 路由跳转到B
}
},
computed: {
...mapGetters(['resturantName']) // 动态计算属性,相当于this.$store.getters.resturantName
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.title,.titleName{
color: blue;
font-size: 20px;
}
.btn{
width: 160px;
height: 40px;
background-color: blue;
border: none;
outline: none;
color: #ffffff;
border-radius: 4px;
}
.marTop{
margin-top: 20px;
}
</style>
B组件同理
<template>
<div class="componentsB">
<P class="title">组件B</P>
<P class="titleName">餐馆名称:{{resturantName}}</P>
<div>
<!-- 点击修改 为 B 餐馆 -->
<button class="btn" @click="modifyBName('B餐馆')">修改为B餐馆</button>
</div>
<div class="marTop">
<button class="btn" @click="trunToA">跳转到A页面</button>
</div>
</div>
</template>
<script>
import {mapActions, mapGetters} from 'vuex'
export default {
name: 'B',
data () {
return {
}
},
methods:{
...mapActions( // 语法糖
['modifyBName'] // 相当于this.$store.dispatch('modifyName'),提交这个方法
),
trunToA () {
this.$router.push({path: '/componentsA'}) // 路由跳转到A
}
},
computed: {
...mapGetters(['resturantName']) // 动态计算属性,相当于this.$store.getters.resturantName
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.title,.titleName{
color: red;
font-size: 20px;
}
.btn{
width: 160px;
height: 40px;
background-color: red;
border: none;
outline: none;
color: #ffffff;
border-radius: 4px;
}
.marTop{
margin-top: 20px;
}
</style>