vue 非父子组件之间实现数据传递 vuex

我们知道父子组件直接的数据传递通过标签属性行间 将数据挂在到了标签上

子组件中通过props特性验证来获取来自父组件的数据 进行渲染

在非父子组件中也借用这样的原理  原理图如下

第一种  子传父   父传子

特点 : 传值要经过父组件 不断寻找各组件之间的从属关系   操作复杂 适合一层 父子兄弟组件传递

代码如下:

//子组件1传值到父组件
<template>
    <div>
<!--        第一种方法属性传递-->
        <input type="text" v-model="val" @change="add">请输入
    </div>
</template>
<script>
    export default {
        data() {
            return {
                val: ""
            }
        },
        methods: {
            add() {
                //第一中方法
                 this.$emit('test',this.val);
                你在这里触发那个事件 在需要的页面就监听谁
                this.val = "";
            }
        },
    }
</script>
//父组件
<template>
    <div>
<!--        父组件-->
        <add-student @test="test"></add-student>
        <student-list :list="list"></student-list>
    </div>
</template>
<script>
    import addStudent from '@/components/learn/addStudent.vue';
    import studentList from '@/components/learn/studentList';
    export default {
        data() {
            return {
                list:[]
            }
        },
        methods: {
            test(name) {
                this.list.push(name);
                console.log(this.list)
            }
        },
        components:{
            addStudent,
            studentList
        }
    }
</script>

<style scoped>

</style>
//子组件2接受数据
<template>
    <div>
        <span>你的数据</span>
        <ul>
            <li v-for="(item,index) in list">
                {{list[index]}}
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        //属性传值需要props
         props: {
             list: {
                 type: Array,
        
             },
         },
         第二种事件总线
        data() {
            return {
                list: []
            }
        }
    }
</script>

<style scoped>

</style>

事件总线    在整个vue对象的原型上添加一个新的vue实例(对象)该对象为所有vue组件所有

特点: 当每个组件获取数据时 需要在生命周期函数create()函数中注册来自原型上的自定义事件,当组件多时 需要监听的事件太多  适合少量的组件使用(不同层之间也可以)

代码如下

//main.js
Vue.prototype.state = new Vue();
//实例对象原型上添加新的vue对象  为所有vue组件共有  兄弟子组件可以直接使用 不用经过父组件
子组件1
<template>
    <div>
<!--        第二种事件总线-->
        <input type="text" v-model="val" @change="add">请输入
    </div>
</template>

<script>
    export default {
        data() {
            return {
                val: ""
            }
        },
        methods: {
            add() {
                //你在这里触发那个事件 在需要的页面就监听谁
                // console.log(this,this.state);
                //第二种方式
                this.state.$emit('test1',this.val);
                this.val = "";
            }
        },
    }
</script>

<style scoped>

</style>
//子组件2
<template>
    <div>
        <span>你的数据</span>
        <ul>
            <li v-for="(item,index) in list">
                {{list[index]}}
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        // 第二种事件总线
        data() {
            return {
                list: []
            }
        },
        created() {
            //利用该方法监听自定义事件
            this.state.$on('test1',name => {
                this.list.push(name);
                console.log(this.list)
            })
        }
    }
</script>

<style scoped>

</style>

---------------------------------------------------------------------------------------------------------------

vuex部分

第三种 vuex公共数据池  state

vuex 作为一个公共数据池里面的数据供任意组件使用使用规则

注意

1、各个组件获取数据池中数据方法 this.$store.state.xxx 

2、因为涉及数据变化 建议在子组件中使用计算属性来接收数据 (接收数据的三种方式)

        //第一种
        computed: {
            age() {
                return this.$store.state.age;
            }
        },
        //第二种
        computed:mapState(['name','age','look']),
        //第三种
        computed:{
            ...mapState({
                storeName:state => state.name,
                storeName:state => state.name,
                storeName:state => state.name,
            })
        },

3、鉴于计算属性返回数据的繁琐引入了mapState对象

import {mapState} from 'vuex'

该对象用于对来自数据池的数据进行操作

vuex    getters(相当于计算属性)

运用场景如下 当子组件需要的数据要进行加工时 如果使用state中的数据会影响其他组件的数据 此时可以在getters中处理

state相当于data 一般存放固定数据 只有当两个组件的数据变化是同步的时候才可以同时引用data 你变化我也变化

注意:子组件引用时候要区别于state中箭头函数形式 直接填写变量名你就行了

其次getters还可以添加参数如下所示 ,无论是state getters本质上都是对象 可以一对象形式访问各个池中的数据

import {mapGetters} from 'vuex'

vuex  store中
    getters: {
        newList (state,getters) {
            console.log(state);
            console.log(getters);
            console.log(getters.caonima);
            return  'hao'
        },
        caonima() {
            return 'nima'
        }
    },
//组件中
computed:{
            ...mapState({
                stdList:state => state.stdList,
                storeName:state => state.name,
                storeAge:state => state.age,
            }),
            ...mapGetters({
                newList:'newList'
            })
        },

vuex 之  mutations

到此为止不仅仅利用vuex进行数据处理 到这里开始使用方法函数

同步事件处理

注意  当在非严格模式下可以在mutations之外进行state数据池中数据改动 但是es5严格模式下报错 

语法规则:对于mutations参数而言 第一个参数为vuex对象本身 从第二个参数开始为自定义参数

多个参数传递要以对象模式进行接收时也是对象模式 mutations中的方法相当于一个自定义事件 需要用户主动触发

触发语法:      this.$store.commit('add',1);

异步事件处理 actions异步更改state数据

在mutations中处理同步事件而言可以处理利用commit方法触发,但是如果mutations中含有异步事件就会报错 不再是同一个作用域 例如定时器

利用actions可以解决这个问题 该函数内部通过定义方法来处理异步事件 原理就是在actions模块中异步触发mutations模块中的方法,在需要的地方不再利用commit触发mutations中的方法而是触发actions里面方法

触发规则  this.$store.dispatch('meess',1);

具体代码如下

vuex

发布了56 篇原创文章 · 获赞 1 · 访问量 1186

猜你喜欢

转载自blog.csdn.net/qq_40819861/article/details/102744261