美文网首页Web前端之路1024
Vue中props源码处理

Vue中props源码处理

作者: 圆梦人生 | 来源:发表于2022-08-12 09:53 被阅读0次
    • props支持对象和数组两种,二选一,否则给出警告
    • props中数组定义必须是字符串,否则给出警告
    • 不管数组还是对象把key转换成驼峰处理,如('my-component'转成myComponent)等
    • 使用缓存对象保存处理后的驼峰结果,不用每次都去调用方法

    源码片断

    /**
     * @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);
    

    相关文章

      网友评论

        本文标题:Vue中props源码处理

        本文链接:https://www.haomeiwen.com/subject/lmexgrtx.html