Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue组件通信 #2

Open
liangfengbo opened this issue Jul 31, 2019 · 0 comments

Comments

@liangfengbo
Copy link
Owner

commented Jul 31, 2019

组件的通信

  • ref:给元素或组件注册引用信息;
  • $parent / $children:访问父 / 子实例

父组件调用子组件的属性和方法

<i-button  ref="btn">Button</i-button>
export default {
  data () {
    return {
      title: 'name'
    }
  },
  methods: {
    getName () {
      console.log(this.name);
    }
  }
}

// 获取 i-button 组件的属性
this.$refs.btn.name
// 调用 i-button 组件的方法
this.$refs.btn.getName();

// $children返回的是一个组件集合
this.$children[0].name
this.$children[0].getName();

$parent子组件调用父组件的属性或方法

this.$parent.num ++;
this.$parent.handleNativeEvent();

ref, $children, $parent弊端:无法在跨级或兄弟间通信

provide / inject通信

链接:provide / inject

在父组件中放入

provide: {
    like: 'i like coding..'
},

子组件使用like属性

inject: ['like'],

console.log(this.like)

使用 Vuex,最主要的目的是跨组件通信、全局数据维护、多人协同开发。需求比如有:用户的登录信息维护、通知信息维护等全局的状态和数据。

$on 和 $emit

$emit 是触发实例自定义的事件,$on是监听它的实例事件的

mounted() {
    this.$on('on-click', function (event) {
        console.log(event);
    })
},
methods: {
    handleEvent(event) {
        this.$emit('on-click', event);
    },
}

$dispatch 和 $broadcast 已废除

findComponents

// 由一个组件,向上找到最近的指定组件
function findComponentUpward (context, componentName) {
    let parent = context.$parent;
    let name = parent.$options.name;

    while (parent && (!name || [componentName].indexOf(name) < 0)) {
        parent = parent.$parent;
        if (parent) name = parent.$options.name;
    }
    return parent;
}
export { findComponentUpward };

// 由一个组件,向上找到所有的指定组件
function findComponentsUpward (context, componentName) {
    let parents = [];
    const parent = context.$parent;

    if (parent) {
        if (parent.$options.name === componentName) parents.push(parent);
        return parents.concat(findComponentsUpward(parent, componentName));
    } else {
        return [];
    }
}
export { findComponentsUpward };

// 由一个组件,向下找到最近的指定组件
function findComponentDownward (context, componentName) {
    const childrens = context.$children;
    let children = null;

    if (childrens.length) {
        for (const child of childrens) {
            const name = child.$options.name;

            if (name === componentName) {
                children = child;
                break;
            } else {
                children = findComponentDownward(child, componentName);
                if (children) break;
            }
        }
    }
    return children;
}
export { findComponentDownward };

// 由一个组件,向下找到所有指定的组件
function findComponentsDownward (context, componentName) {
    return context.$children.reduce((components, child) => {
        if (child.$options.name === componentName) components.push(child);
        const foundChilds = findComponentsDownward(child, componentName);
        return components.concat(foundChilds);
    }, []);
}
export { findComponentsDownward };

// 由一个组件,找到指定组件的兄弟组件
function findBrothersComponents (context, componentName, exceptMe = true) {
    let res = context.$parent.$children.filter(item => {
        return item.$options.name === componentName;
    });
    let index = res.findIndex(item => item._uid === context._uid);
    if (exceptMe) res.splice(index, 1);
    return res;
}
export { findBrothersComponents };

function typeOf(obj) {
    const toString = Object.prototype.toString;
    const map = {
        '[object Boolean]'  : 'boolean',
        '[object Number]'   : 'number',
        '[object String]'   : 'string',
        '[object Function]' : 'function',
        '[object Array]'    : 'array',
        '[object Date]'     : 'date',
        '[object RegExp]'   : 'regExp',
        '[object Undefined]': 'undefined',
        '[object Null]'     : 'null',
        '[object Object]'   : 'object'
    };
    return map[toString.call(obj)];
}
// deepCopy
function deepCopy(data) {
    const t = typeOf(data);
    let o;

    if (t === 'array') {
        o = [];
    } else if ( t === 'object') {
        o = {};
    } else {
        return data;
    }

    if (t === 'array') {
        for (let i = 0; i < data.length; i++) {
            o.push(deepCopy(data[i]));
        }
    } else if ( t === 'object') {
        for (let i in data) {
            o[i] = deepCopy(data[i]);
        }
    }
    return o;
}

export {deepCopy};

vue-component-book, by icarusion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.