vue组件传值

逐级传递传值的方法:
props,自定义事件( $ emit),$ router.push

跨组件传值的方法:
消息订阅与发布(pubsub),eventBus,vuex

1、props

可以是数组、对象或字符串,用于接收来自父组件的数据
自上而下的数据传递,即父 => 子 => 孙,只能逐级传递

props使用方法:
在父组件中导入子组件

import TableThead from '../components/TableThead'
components:{
            TableThead
        }
 }

在父组件中调用子组件

	//tbHeadArr:当前父组件的数据 
	//tbHeadFun:当前父组件的函数
	//tbHead:变量名
    <TableThead :tbHeadArr="tbHeadArr" :tbHeadFun="tbHeadFun">
               <th slot="tbHeadOper">操作</th>
     </TableThead>

在子组件中通过props得到tbHeadArr得值,并声明类型

<script>
    export default {
        name: "TableThead",
        props:{
            tbHeadArr:{
                type:Array,
                default:[]
            },
            tbHeadFun:{
                type:Function
            }
        }
    }
</script>

在页面中就可以直接使用变量tbHeadArr了

<template>
        <thead>
            <tr @click="tbHeadFun">
                <th v-for="item in tbHeadArr">{{item}}</th>
                <slot name="tbHeadOper"></slot>
            </tr>
        </thead>
</template>

2、自定义事件

可以是数组、对象或字符串,用于传值给父组件
自下而上的数据传递,即孙 => 子 => 父,只能逐级传递

自定义事件使用方法:
在调用子组件的时候,定义一个自定义事件

<!--custom自定义函数名-->
<componentOne :compOneName="indexName" @custom="changeName"></componentOne>

父组件中定义函数changeName,修改相应值

data(){
        return {
            indexName:"lhm"
        }
    },
    methods:{
   		// obj:接受子组件传过来的数据
        changeName(obj){
            console.log(obj.name)
            //修改相应数据
            this.indexName=obj.name
        }
    }

在子组件中定义一个click事件,用于触发自定义事件

<button @click="changeFatherData">改变名字</button>
methods:{
            changeFatherData(){
                //触发自定义函数
              	// {name:'hello'}:欲修改的数据
                this.$emit("custom",{name:'hello'})
            }
        }

3.消息订阅与发布

下载:npm install pubsub-js
订阅消息---------绑定事件监听
发布消息---------触发事件
在组件1订阅消息:

import PubSub from "pubsub-js"        //导入模块
mounted(){
		PubSub.subscribe('函数名', (msg,data)=> {
				//数据操作
		})
}

在组件2发布消息:

 import PubSub from "pubsub-js"       //导入模块
 methods:{
		myFunction(){
			 PubSub.publish('函数名',data)
		}
 }

4.eventBus

可以是数组、对象或字符串,用于传值给其他组件,可跨级传递

eventBus的使用方法
src根目录下新建文件bus.js,作为中转站

import  Vue from "vue"
export  default  new Vue({})

以下例子实现:
通过组件1传值给组件2,且组件1值改变,组件2能跟着改变

组件1:
html代码:

	<div>
            <h3>{{age}}岁</h3>
            <button @click="changeAge">改变年龄</button>
        </div>

js代码:

<script>
	//导入bus:`import bus from "../bus"`
    import bus from "../bus"
    export default {
        name: "componentTwoChild",
        data(){
            return{
           		 //初始值
                age:20
            }
        },
        methods:{
            changeAge(){
                this.age++
                bus.$emit("getGrade",this.age)
            }
        },
        //渲染dom节点的时候调用
        mounted(){
            bus.$emit("getGrade",this.age)
        }
    }
</script>

组件2:
html代码:

	 <div>
            <h3>{{age}}岁</h3>
        </div>

js代码:

<script>
 	//导入bus:`import bus from "../bus"`
    import bus from "../bus"
    export default {
        name: "componentOne",
        data(){
            return{
                age:0
            }
        },    
        beforeCreate(){
            bus.$on("getGrade",(num)=>{
                this.age = num
            })
        }
    }
</script>

5.vuex

可以是数组、对象或字符串,用于传值给其他组件,可跨级传递,它采用集中式存储管理应用的所有组件的状态

vuex的使用
1、在src根目录下新建一个文件夹store
store下新建一个modules文件夹,该文件夹下可以建不同的功能模块,把容器分成几块,把状态和管理规则分类来装,每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

2、store下新建一个index.js文件

  //导入vue
    import Vue from 'vue'
    //导入vuex
    import Vuex from 'vuex'
     //导入我的vuex模块
    import vueStar from './modules/vueStar'
    Vue.use(Vuex) 
    //公开对象的Store
    export default new Vuex.Store({
    modules:{
        vueStar
    }
})

或者直接动态引入

import { createStore } from 'vuex'
import "es6-promise/auto";

const modulesFiles = require.context("./module", true, /\.js$/);
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
    const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, "$1");
    const value = modulesFiles(modulePath);
    modules[moduleName] = value.default;
    return modules;
}, {});
export default createStore({
    state: {
    },
    mutations: {
    },
    actions: {
    },
    modules
});

3、修改main.js

//导入store
import store from './store/index'
new Vue({
  router,
  //实例使用store
  store,
  render: h => h(App)
}).$mount('#app')

4、store下新建一个modules文件夹,该文件夹下可以建不同的功能模块,把容器分成几块,把状态和管理规则分类来装
顺序依次是:组件1 》actions 》 mutations 》 state 》组件2

本案例先建一个vueStar.js文件

//存放公共的状态
const state={
    classId:"1001",
    login:false
}

 //通过store.dispatch触发,存放如何更改状态,state和mutations的中转站,包含任意异步操作
 //context是与 store 实例具有相同方法和属性的 context 对象,可以通过context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters
const actions={
    setClassId(context,myClassId){
        context.commit("setStateClassId",myClassId)
    },
    login(context,obj){
        context.commit("setLogin",obj)
    }}
    
 // 可以通过store.commit ,或者actiocs中的context.commit 调用mutations中的方法来改变状态,同步函数
const mutations={
    setStateClassId(state,myClassId){
        state.classId=myClassId
    },
    setLogin(state,obj){
        if(obj.name=='lhm'&&obj.pwd==333){
            state.login=true;
        }
    }
}

// 从state中派生出状态,等同于计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
const getters={
    login(state){
        return state.login
    }
}

//公开对象
export default{
    state,
    actions,
    mutations,
    getters

}

5、以下例子实现:
通过vuex作为仓库,存放相应数据,组件1和组件2可以任意调用或修改这些数据

组件1
html代码:

<button @click="changeClassId">修改班级</button>
<button @click="login">登录</button>

js代码:

<script>
    export default {
        name: "indexPage",
        methods:{
            changeClassId(){
            	//调用store中actions对象得setClassId函数,传值
                this.$store.dispatch("setClassId","欲修改得值");
            },
            login(){
                let user={
                   name:"lhm",
                   pwd:333
                }
               //调用store中actions对象得setClassId函数,传值
                this.$store.dispatch("login",user)
            }
        }
    }
</script>

组件2
html代码:

		<div>
            <h3>{{classId}}班</h3>
        </div>
        
        //组件1点击修改班级后,store中该数据改变,但是组件2页面并不会响应,需调用changeClassId函数进行响应,若想要实现直接响应,可调用watch方法
       
        <button @click="changeClassId">改变班级</button>
        <p>我的登录状态{{loginState}}</p>

js代码:

<script>
    export default {
        name: "componentOne",
        data(){
            return{
                classId:""
            }
        },
        computed:{
        	//计算属性,相关数据或属性(store数据)改变时,自动调用
            loginState(){
                return this.$store.getters.login
            }
        },
        methods:{  
            changeClassId(){
           		 //修改页面的数据
                this.classId=this.$store.state.vueStar.classId
            }
        },
        created(){
            this.classId=this.$store.state.vueStar.classId
        },
        watch:{
       		 //监听$store.state.vueStar.classId的改变
            '$store.state.vueStar.classId'(){
                this.classId=this.$store.state.vueStar.classId
            }
        }
    }
</script>

6.$ router.push或$ router.replace

$ router.push:点击路由链接(可以回退到当前路由界面)
$ router.replace:用新路由替换当前路由(不可以回退到当前路由界面)

html代码:

<el-button type="primary"
			plain size="mini"
            @click="renewPay(scope.row)">续借</el-button>									

js代码:

renewPay(obj){
                obj.duzhexingming=this.readerInfo.xingming
                obj.duzhebianhao=this.readerId
                obj.caozuo="续借"
                //传参 obj
                this.$router.push({path:"/library/settleAccounts", query:obj})
            }

router拦截并跳转至另一个组件

{
        path:"/library/settleAccounts",
        name:"settleAccounts",
        component:()=>import('../../views/settleAccounts'),
    }

在另一个组件中使用this.$route.query

<el-col :span="10"><p>图书编号:{{this.$route.query.shujibianhao}}</p></el-col>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值