We can use the v-for
instruction based on an array to render a list, there are five use, as follows:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> </head> <body> <script> Vue.config.productionTip=false; Vue.config.devtools=false; </ Script > < div ID = "App" > < P V-for = "Item in items" > {{Item}} </ P > <-! Array format a, rendering results: <p> 11 < / P> <P> 12 is </ P> -> < P V-for = "(Item, index) in items" > {{index}} -> {{Item}} </ P > <! - two array format, rendering results: <P> 0->. 11 </ P> <P> l-> 12 is </ P> -> < P V-for = "Item in the infos" > {{}} Item </ P > <-! Object format a, rendering results: <p> gege </ p > <p> 12 </ p>-> < P V-for = "(Item, Key) in the infos" > {}} {Key: Item {} {} </ P > ! <- object format Second, the rendering results: <p> name: Gege </ P> <P> Age: 12 is </ P> -> < P V-for = "(Item, Key, index) in the infos" > {{}} index: Key {} {}: {{ }} Item </ P > <-! object format three, rendering results: <P> 0: name: Gege </ P> <P>. 1: Age: 12 is </ P> -> </ div > < Script > was app = new Vue ({ data () { return { items: [ 11 ,12 is ], // V-object may be for the infos: {name: ' Gege ' , Age: 12 is } // may be an array } }, EL: ' #app ' }) </ Script > </ body > < / HTML >
Very simple, as long as the background provides an interface, returns an array or object, by v-for front-end can be rendered, we have to format the above third object, for example to talk about the source, as follows:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> </head> <body> <script> Vue.config.productionTip=false; Vue.config.devtools=false; </script> <div id="app"> <p v-for="(item,key,index) in infos">{{index}}:{{key}}:{{item}}</p> </div> <script> var app = new Vue({ data(){return {infos:{name:'gege',age:12}}}, el:'#app' }) </script> </body> </html>
Source code analysis
When parsing template, Vue's processFor () -> parseFor () function depending on the parse out the four variables v-for content saved on the property AST object:
function processFor (EL) { // first row 9367 for instruction processing var exp; IF ((getAndRemoveAttr = exp (EL, 'v-for'))) { // If the v-for acquiring attribute var RES = parseFor (exp ); // call the function to parse the attribute parseFor IF (res) { // if present res Extend (EL, res); // is called extend () added on the object AST } the else { the warn $ 2 ( ( "Invalid V- expression The for: "+ exp) ); } } }
parseFor () for parsing the v-for value, and returns an object, as follows:
function parseFor (exp) { // section 9383 v-for-line parsing attribute exp: v-for value; for example: "(Item, Key, index) in the infos" var inMatch = exp.match (forAliasRE); // with regular matching forAliasRE definition line is equal to 9403: / (? [^] *) \ S + (?: in | of) \ S + ([^] *) /; IF (! inMatch) { return } // if not match, return false var RES = {}; RES. for = inMatch [2] .trim (); // for value, here equal to: the infos var Alias = inMatch [. 1] .trim () Replace (stripParensRE, ''. ); // removing brackets around this time is equal alias: Item, Key, index var= alias.match iteratorMatch (forIteratorRE); // matching alias index and IF (iteratorMatch) { // If a match to, i.e., the format is: V-for = "(Item, index) Data in" res.alias = Alias. Replace (forIteratorRE, ''); // for the alias res.iterator1 iteratorMatch = [. 1] .trim (); // Get index IF (iteratorMatch [2 ]) { res.iterator2 = iteratorMatch [2 ] .trim (); } } the else { res.alias = Alias; } return RES // returns the object, such as: {Alias: "Item", for: "the infos", a iterator1: "Key", a iterator2: "index"} }
Here the example of execution in the v-for four attributes associated with the stored v-for, as follows:
Next, when the generate function calls generated rendre genFor () _l generate a corresponding function, as follows:
function genFor ( // rendering instruction v-for EL, State, altGen, altHelper ) { var exp = EL. for ; // get the value for the var Alias = el.alias; // Get alias var a iterator1 = el.iterator1? ( "," + (el.iterator1)): ''; // (v-for when the key was the target value) obtain the index var ? = a iterator2 el.iterator2 ( "," + (el.iterator2)) : ''; // / acquisition index (v-for value when the object)) IF ( "Development" ==! 'Production' && State.maybeComponent (el)&& el.tag !== 'slot' && el.tag !== 'template' && !el.key ) { state.warn( "<" + (el.tag) + " v-for=\"" + alias + " in " + exp + "\">: component lists rendered with " + "v-for should have explicit keys. " + "See https://vuejs.org/guide/list.html#key for more info.", true /* tip */ ); } el.forProcessed = true; // avoid recursion return (altHelper || '_l') + "(("Exp + + ")," + patchwork _l function// "function(" + alias + iterator1 + iterator2 + "){" + "return " + ((altGen || genElement)(el, state)) + '})' }
Last generated render function is equal to:
with(this){return _c('div',{attrs:{"id":"app"}},_l((infos),function(item,key,index){return _c('p',[_v(_s(index)+":"+_s(key)+":"+_s(item))])}))}
Wherein associated with the v-for as follows:
_l((infos),function(item,key,index){return _c('p',[_v(_s(index)+":"+_s(key)+":"+_s(item))
The first parameter _l for our v-for goal, that is, infos, will traverse the object while
_L rendering function executes inside Vue when generating VNode, it is the global renderList, as follows:
function renderList ( // section 3691 v-for line rendering command Val, the render ) { var RET, I, L, Keys, Key; IF (Array.isArray (Val) || typeof Val === 'String') { / / if val is an array ret = new new the array (val.length); // the ret val defined as an array of the same size for (I = 0, L = val.length; I <L; I ++) { // iterate array val ret [I] = render (Val [I], I); // sequentially render function call, a parameter value of the parameter is returned vnode index 2, and the results saved to vnode which ret } } the else IF (typeof val === 'number') { ret = new Array(val); for (i = 0; i < val; i++) { ret[i] = render(i + 1, i); } } else if (isObject(val)) { keys = Object.keys(val); ret = new Array(keys.length); for (i = 0, l = keys.length; i < l; i++) { key = keys[i]; ret[i] = render(val[key], key, i); } } if(isDef (ret)) { // If ret present (called successfully) ._ isVList = (ret) to true ; // is added to the array _isVList a tag value to true } return ret // last return ret }
Finally, packaged together in a VNode array and returns, as a child of other elements (_c third parameter).