vue组件传参 +vuex全局数据管理

1 篇文章 0 订阅

组件传参

关于vue传参有三大类型

第一种:父向子传参(props)

父组件向子组件共享数据需要使用自定义属性----props
比如我们有父组件 Father 和 子组件 Son。如果需要父向子传参时,则需要在子组件Son中添加一个props(与data平级)。在props中可以添加自定义属性,属性名自己取。比如fromfather:{default:0, type:Number} 传参时只需要在父组件中使用子组件 这里使用的属性名必须与子组件中props上定义的一样
父组件的数据

        <div class="box">
            <p>这是父组件</p>
            <son :list="list"></son>
        </div>

通过props向子组件传参
子组件

props: {
    //父组件传入的item数据
    list: {
      type: Object, //list类型
      default: function () {
        return {};
      },
    },
  },

第二种:子向父传参($emit)

子组件向父组件共享数据使用自定义事件
在子组件Son的methods中定义一个方法,其中有this.$emit(‘自己定义的方法名’, 要传的数据)

<div class="right" @click="$emit('right-click', $event)">
//$emit的第一个参数即自定义的事件名,第二个参数是事件名对应的参数
第三种:兄弟组件之间传参

非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。
第一步、创建bus.js文件

//导入Vue
import Vue from "vue"
//创建Vue实例
var bus = new Vue();
//导出bus
export default bus

第二步、在要发送数据的组件中导入bus

import bus from "@/utils/bus.js";

第三步、在有接受数据的组件中导入bus并使用bus.$on(注意this)

created() {
    console.log(this.$children);
    bus.$on("msgchange", ($event) => {
      this.msg = $event;
    });
  },

这里需要注意:任意组件只要导入bus就可以随意的发送与监听数据

bus常用的三个方法

bus.$on(eventname,callback)监听事件

bus.$emit(eventname,data)发送事件

bus.$off(eventname)移除事件

还有一种特殊的依赖注入provider和inject(跨层级访问,只读)
provider提供数据,所有子组件都可以通过inject接受数据
inject接受父辈提供的数据

完整代码

<template>
    <div class="nav" :style="{backgroundColor:bg_color,color:text_color}">
        <div class="left" @click="$emit('left-click',$event)">
            <slot name="icon_left"></slot>{{left_text}}
        </div>
        <div class="title">
            <slot name="title"></slot>{{title}}
        </div>
        <div class="right" @click="$emit('right-click',$event)">
            {{right_text}}
            <slot name="icon_right"></slot>
        </div>
        <p :style="{'backgroundColor':myColor}" @click="$parent.outNum++">访问父组件outNum:{{$parent.outNum}}</p>
        <p>来自APP组件:{{myMsg}}</p>
    </div>
</template>
<style lang="scss" scoped>
.nav {
    height: .88rem;
    line-height: .88rem;
    display: flex;
    align-items: center;
    font-size: .2rem;
 
    .title {
        flex: 1;
        text-align: center;
    }
 
    .left,
    .right {
        padding: 0 .3rem;
    }
}
</style>
<script>
import bus from '@/utils/bus.js'
export default {
    created() {
        bus.$on("msgchange", $event => {
            console.log("msgchange");
            this.myMsg = $event
        })
    },
    data() {
        return {
            myColor: '#f30',
            myMsg: ""
        }
    },
    props: {
        //文本颜色
        text_color: {
            type: String, default: "#000"
        },
        bg_color: { type: String, default: '#fff' },
        //标题
        title: { type: String, default: '' },
        left_text: { type: String, default: "" },
        right_text: { type: String, default: "" },
    }
}
</script>

vuex 的概念

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
vuex核心概念:
vuex中有五个状态 State Getter Mutation Action Module
在这里插入图片描述

什么时候我们才使用Vuex呢

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

Vuex的优点

Vuex实现数据全局共享,响应式更新

为什么要把登录转换到vuex中
  1. 登录后成功的数据可以全局共享
  2. 为了重复利用,登录功能 不可能值在登录页面,如:
    首页点击登录弹框按钮
    购物车,跳转前,弹框登录,登录位置会有很多
    如果写在vuex中,只需要在登录的地方调用$stroe.dispatch(“login”,data)就可以
html这是的一个vuex使用,可以看到存储在vuex里的数据,在不同的组件中都可以使用
//登录
<template>
	<div id="">
		<h1>登录</h1>
		<input type="text" v-model="user.name" placeholder="请输入用户名"> <br>
		<input  type="password" v-model="user.password"  placeholder="请输入密码"/> <br>
		<button @click="$store.dispatch('login',user)">登录</button>
		<p>
			<router-link to="/reg">注册</router-link>
		</p>
		<button @click="$notify.show('该做核酸了!','pink')">自定义通知</button>
	</div>
</template>
 
//注册
<template>
	<div>
		<h1>注册</h1>
		<input type="text" v-model="user.name" placeholder="用户名:"> <br>
		<input type="password" v-model="user.password" placeholder="密码:"> <br>
		<button @click="$store.dispatch('reg',user)">注册</button>
	</div>
</template>
为什么要写api/login.js实现登录
  1. 重复利用,登录的api也会调用很多次
  2. 方便集中管理所有的请求地址与请求方式api文件中
  3. 改请求方式与参数可以直接修改api内容就可以,不用具体进入到某个组件
import { Login, Reg } from '@/api/user.js'
import $router from "@/router/index.js"
import Notify from '@/plugin/Notify/index.js'
import Vue from 'vue'
Vue.use(Notify)
export default {
    state: {
        userInfo: {
            name: "wang",
            score: 50
        },
        token: ""//token标识
    },
    mutations: {
        SET_USERINFO(state, data) {
            //更新state的userinfo信息
            state.userInfo = data;
            //本地存储信息
            localStorage.setItem("user", JSON.stringify(data))
        },
        SET_TOKEN(state, data) {
            state.token = data;
            //本地存储信息
            localStorage.setItem("token", data)
        },
 
    },
    actions: {
        //页面退出
        logout(context) {
            context.commit("SET_USERINFO", {})
            context.commit("SET_TOKEN", {})
            // var $route = $router.history.current
            // //获取查询参数
            // var redirect = $route.query.redirect || '/';
            // //实现跳转
            $router.replace('/user')
        },
        //负责登录
        login(context, data) {
            Login(data)
                .then(res => {
                    if (res.data.code === 200) {
                        Notify.success(res.data.msg || "登录成功")
                        alert(res.data.msg)
                        context.commit("SET_USERINFO", res.data.user)
                        context.commit("SET_TOKEN", res.data.token)
                        var $route = $router.history.current
                        //获取查询参数
                        var redirect = $route.query.redirect || '/';
                        //实现跳转
                        $router.replace(redirect)
                    } else {
                        //登录不成功清除用户信息
                        Notify.danger(res.data.msg || "登录失败")
                        // context.commit("SET_USERINFO", {})
                        // context.commit("SET_TOKEN", "")
                        alert(res.data.msg)
                    }
                })
                //失败显示网络失败
                .catch(err => {
                    console.log(err);
                    alert("网络失败")
                })
        },
        reg(context, data) {
            Reg(data)
                .then(res => {
                    if (res.data.code === 0) {
                        alert('注册成功')
                        Notify.success(res.data.msg || "注册成功")
                        $router.push('/login')
                    } else {
                        alert(res.data.msg || "注册失败")
                        Notify.push('/login')
                    }
                })
                .catch((err) => {
                    console.error(err);
                })
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值