vue 数据传递方式

1、props + $ emit
适用于父子组件子组件使用;
props 接收来自父组件的数据父组件绑定, v-on:事件名 监听事件, 子组件使用 this.$emit(‘事件名’) 派发事件;
缺点:如果组件嵌套的比较深就比较麻烦;

// Parent.vue
<div class="parent">
    <Child :num="num" @addNum="handleAddNumber"></Child>
</div>

<script>
import Child from './Child.vue'
export default {
    
    
    name: 'parent',
    components: {
    
    
        Child
    },
    data() {
    
    
        return {
    
    
            num: 1
        }
    },
    methods: {
    
    
        handleAddNumber(n) {
    
    
            this.num += n
        }
    }
}
</script>


// Child.vue 组件
<div class="child">
    <div @click="increamentNum">{
    
    {
    
    num}}</div>
</div>

<script>
export default {
    
    
    name: 'child',
    methods: {
    
    
        increamentNum() {
    
    
            this.$emit('addNum', 3)
        }
    }
}
</script>

2、.sync 修饰符
当子组件改变一个 prop 时,这个变化也会同步到父组件中的绑定。这个有点类似于 v-model 的功能;
.sync.prop=“newProp” 是 :prop 和 @update:prop=“val => newProp = val” 的语法糖,当 prop 改变时,会触发一个更新事件(this.$emit(‘update:prop’, newValue))

// parent.vue
<div>
 <p>{
    
    {
    
    num}}</p>
 <Child :n.sync="num"></Child>
</div>

export default{
    
    
    name: 'parent',
    data(){
    
    
        return {
    
    
            num: 1111
        }
    }
}

// child.vue
<div>
    <p>{
    
    {
    
    n}}</p>
    <button @click="addN">n + 1</button>
</div>

export default{
    
    
    props: {
    
    
        n: Number
    },
    methods: {
    
    
        addN() {
    
    
            this.n += 1
            this.$emit('update:n', this.n)
        }
    }
}

3、vuex: 状态管理器
优点:响应式、可以实现项目中所有共享状态的管理;
缺点:适用于大型复杂的状态管理,如果太小型就有点多余了;

// main.js 入口文件
import Vue from 'vue'
import App from './App.vue'
import store from './store.js'
new Vue({
    
    
    el: '#app',
    store,
    render: h => h(App)
})

// store.js
import Vuex from 'vuex'
export const store = new Vuex.Store({
    
    
    state: {
    
    
        num: 1,
        userArr: [{
    
    id: 1}, {
    
    id: 2}]
    },
    getters: {
    
    
        a: (state, getters) => {
    
    
            return state.num + 'aaa'
        },
        userId: (state) => (id) => {
    
    
            return state.userArr.find(item.id === id)
        }
    },
    mutions: {
    
    
        ADD_NUM(state, payload) {
    
     // payload 为传递进来的数据 ,可以通过 this.$store.commit('add', {
    
     n: 10 }) 触发该 mutions
            state.num = state.num + payload.n
        }
    },
    actions: {
    
    
        addNum({
    
    commit, dsipatch}, payload) {
    
     // payload 为传递进来的数据 ,可以通过 this.$store.dispatch('addNum') 调用该 action
            commit('ADD_NUM', {
    
     n: 10 })
        }
    },
    modules: {
    
    
        aaa: {
    
    
            state: {
    
    },
            getters: {
    
    },
            mutions: {
    
    },
            actions: {
    
    }
        },
        bb: {
    
    
            state: {
    
    },
            getters: {
    
    },
            mutions: {
    
    },
            actions: {
    
    }
        }
    }

})

4、inject & provide
适用于祖先关系的组件;
在后代组件中增加 inject 属性, 用来接收数据,可以是一个字符串数组,也可以是一个对象;
在祖先组件中使用 provide 属性存放要传递的数据;
优点:祖先组件不需要知道那些后代使用了这些属性,后代组件也不需要知道属性的来源是哪个祖先;
缺点:因为不知道属性的来源是哪里,所以很难进行追踪,后续维护困难;属性是非响应式的;

// 祖先组件
<div>
    <Child></Child>
</div>
export default {
    
    
    name: 'grandParent',
    data() {
    
    
        return {
    
    
            name: 'bob',
            age: 11,
            num: 20
        }
    },
    provide(){
    
    
        return {
    
    
            name: this.name,
            age: this.age,
            n: this.num
        }
    }
}

// 后代组件
<div>
    {
    
    {
    
    name}} {
    
    {
    
    age}} {
    
    {
    
    n}}
</div>
export default{
    
    
    name: 'child',
    inject: ['name', 'age', 'n']
}

5、$ root $ parent $ children $ refs
通过 $ root 访问根实例 new Vue();
通过 $ parent 访问父组件的实例;
通过 $ children 访问 当前组件的直接子组件。注意获取的子组件没有顺序,非响应式;
通过 $ refs 访问 指定 ref 属性的实例: this.$ refs[‘tree’] 可以获取 < 标签名/组件名 ref=“tree” >…</ 标签名/组件名>。$refs 在组件渲染完后可以使用,非响应式;

6、event bus 事件总线(vue1.x 版本用的比较多,现在基本不使用)
使用一个空的 Vue 实例作为事件中心,用来派发和监听事件,实现各个组件(兄弟、父子、祖先、跨级不相干组件)的通信。非响应式

eventBus.js 文件
import Vue from 'vue'
export const eventBus = new Vue()

user.vue 组件
import eventBus from 'eventBus.js'
// 派发事件
eventBus.$emit('close', false)

role.vue 组件
import eventBus from 'eventBus.js'
// 监听事件
eventBus.$on('close', isTrue => {
    
    
    console.log(isTrue)
})

猜你喜欢

转载自blog.csdn.net/qq_37600506/article/details/129669033
今日推荐