* Compile props on a root element and return * a props link function. * * @param {Element|DocumentFragment} el * @param {Array} propOptions * @param {Vue} vm * @return {Function} propsLinkFn
(el, propOptions, vm)
| 6008 | */ |
| 6009 | |
| 6010 | function compileProps(el, propOptions, vm) { |
| 6011 | var props = []; |
| 6012 | var names = Object.keys(propOptions); |
| 6013 | var i = names.length; |
| 6014 | var options, name, attr, value, path, parsed, prop; |
| 6015 | while (i--) { |
| 6016 | name = names[i]; |
| 6017 | options = propOptions[name] || empty; |
| 6018 | |
| 6019 | if ('development' !== 'production' && name === '$data') { |
| 6020 | warn('Do not use $data as prop.', vm); |
| 6021 | continue; |
| 6022 | } |
| 6023 | |
| 6024 | // props could contain dashes, which will be |
| 6025 | // interpreted as minus calculations by the parser |
| 6026 | // so we need to camelize the path here |
| 6027 | path = camelize(name); |
| 6028 | if (!identRE$1.test(path)) { |
| 6029 | 'development' !== 'production' && warn('Invalid prop key: "' + name + '". Prop keys ' + 'must be valid identifiers.', vm); |
| 6030 | continue; |
| 6031 | } |
| 6032 | |
| 6033 | prop = { |
| 6034 | name: name, |
| 6035 | path: path, |
| 6036 | options: options, |
| 6037 | mode: propBindingModes.ONE_WAY, |
| 6038 | raw: null |
| 6039 | }; |
| 6040 | |
| 6041 | attr = hyphenate(name); |
| 6042 | // first check dynamic version |
| 6043 | if ((value = getBindAttr(el, attr)) === null) { |
| 6044 | if ((value = getBindAttr(el, attr + '.sync')) !== null) { |
| 6045 | prop.mode = propBindingModes.TWO_WAY; |
| 6046 | } else if ((value = getBindAttr(el, attr + '.once')) !== null) { |
| 6047 | prop.mode = propBindingModes.ONE_TIME; |
| 6048 | } |
| 6049 | } |
| 6050 | if (value !== null) { |
| 6051 | // has dynamic binding! |
| 6052 | prop.raw = value; |
| 6053 | parsed = parseDirective(value); |
| 6054 | value = parsed.expression; |
| 6055 | prop.filters = parsed.filters; |
| 6056 | // check binding type |
| 6057 | if (isLiteral(value) && !parsed.filters) { |
| 6058 | // for expressions containing literal numbers and |
| 6059 | // booleans, there's no need to setup a prop binding, |
| 6060 | // so we can optimize them as a one-time set. |
| 6061 | prop.optimizedLiteral = true; |
| 6062 | } else { |
| 6063 | prop.dynamic = true; |
| 6064 | // check non-settable path for two-way bindings |
| 6065 | if ('development' !== 'production' && prop.mode === propBindingModes.TWO_WAY && !settablePathRE.test(value)) { |
| 6066 | prop.mode = propBindingModes.ONE_WAY; |
| 6067 | warn('Cannot bind two-way prop with non-settable ' + 'parent path: ' + value, vm); |
no test coverage detected