Web前端之路1024

Vue中props源码处理

2022-08-12  本文已影响0人  圆梦人生

源码片断

/**
 * @author: SM
 * Vue中props处理
 */
// 是否包含-连接
var camelizeRE = /-(\w)/g;
// 按照-分割并且首个字符转换成大写,并返回驼峰后的结果
var camelize = cached(function (str) {
    return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })
});

// Object toString方法
var _toString = Object.prototype.toString;
// value对应的值
function toRawType (value) {
    return _toString.call(value).slice(8, -1)
}
/**
 * 判断是否对象
 * @param {*} obj 
 * @returns 
 */
function isPlainObject (obj) {
    return _toString.call(obj) === '[object Object]'
}
/**
 * 缓存对象
 */
function cached (fn) {
    // 创建空对象
    var cache = Object.create(null);
    //
    return (function cachedFn (str) {
        // props中每个key
        var hit = cache[str];
        // 如果缓存存在返回缓存中对应的key,如果没有返回处理驼峰后的值
        // 只所以用缓存是为了不重复调用fn处理
        return hit || (cache[str] = fn(str))
    })
}

/**
 * Ensure all props option syntax are normalized into the
 * Object-based format.
 */
function normalizeProps (options, vm) {
    // 获取props对象
    var props = options.props;
    // 如果没有定义props则退出
    if (!props) { return }
    // 接受处理后的options
    var res = {};
    var i, val, name;
    // 如果是数组
    if (Array.isArray(props)) {
        i = props.length;
        while (i--) {
            val = props[i];
            // 数组中每项值必须是字符串
            if (typeof val === 'string') {
                // 处理成驼峰返回
                name = camelize(val);
                res[name] = { type: null };
            } else {
                // 使用数组语法时,props必须是字符串
                console.log('props must be strings when using array syntax.');
            }
        }
    } else if (isPlainObject(props)) { // 如果是对象,vue中props大多以对象方式定义
        for (var key in props) {
            // 获取value
            val = props[key];
            // 获取转换后的key
            name = camelize(key);
            // 如果value是对象定义直接原样返回,否则返回value对应的类型
            res[name] = isPlainObject(val) ? val : { type: val };
        }
    } else { // 什么都不是,给出警告,并且输出原始类型(要么数组、要么对象)
        console.log(
            "Invalid value for option \"props\": expected an Array or an Object, " +
            "but got " + (toRawType(props)) + ".",
            vm
        );
    }
    // 更改props处理后的值
    options.props = res;
}

// 定义props
let data = {
    // 定义props
    props: {
        // 姓名
        name: String,
        // 用户信息
        userInfo: {
            type: Object
        },
        // 年龄
        age: {
            type: Number,
            default: 20
        },
        // 爱好
        hobby: Array,
        // 爱好
        occupation: {
            type: Array,
            default:()=>{return ['CEO', 'CTO' ]}
        },
        // 
        'last-user-name': String
    }
}
// 1、对象调用方法处理
normalizeProps(data, this);
console.log('option ===', data);


// 2、数组处理
let data2 = {
    // 定义props
    props: ['tData', 'list', 'my-component']
}
normalizeProps(data2, this);
console.log('option2 ===', data2);
上一篇下一篇

猜你喜欢

热点阅读