Cette fois, je vais vous montrer comment utiliser les slots/slots scoped dans Vue. Quelles sont les précautions pour utiliser les slots/slots scoped dans Vue. Voici des cas pratiques, jetons un coup d'oeil.
J'ai toujours été intéressé par les machines à sous dans Vue. Voici quelques-unes de mes compréhensions simples. J'espère que cela pourra aider tout le monde à mieux comprendre les machines à sous
Le combiné suivant. avec un exemple, expliquez brièvement le principe de fonctionnement des slots
Le modèle du sous-composant dx-li est le suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <li class = "dx-li" >
<slot>
你好!
</slot>
</li>
dx-ul父组件的template如下:
<ul>
<dx-li>
hello juejin!
</dx-li>
</ul>
结合上述例子以及vue中相关源码进行分析
dx-ul父组件中template编译后,生成的组件render函数:
module.exports={
render: function (){
var _vm=this;
var _h=_vm. $createElement ;
var _c=_vm._self._c||_h;
return _c( 'ul' ,
[_c( 'dx-li' , [_vm._v( "hello juejin!" )])],
1)
},
staticRenderFns: []
}
|
Copier après la connexion
Le contenu du slot transmis 'bonjour juejin!' Sera compilé dans un nœud enfant du nœud VNode du sous-composant dx-li.
Rendu le sous-composant dx-li, dans lequel la fonction de rendu du sous-composant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | module.exports={
render: function (){
var _vm=this;
var _h=_vm. $createElement ;
var _c=_vm._self._c||_h;
return _c( 'li' ,
{staticClass: "dx-li" },
[_vm._t( "default" , [_vm._v( "你好 掘金!" )])],
2
)
},
staticRenderFns: []
}
|
Copier après la connexion
Pendant le processus d'initialisation de l'instance vue du sous-composant dx-li, la fonction initRender va être appelé :
1 2 3 4 5 6 7 | function initRender (vm) {
...
这里为dx-ul组件实例
vm. $slots = resolveSlots(options._renderChildren, renderContext);
...
}
|
Copier après la connexion
La fonction solveSlots est :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
export function resolveSlots (
children: ?Array<VNode>,
context: ?Component
): { [key: string]: Array<VNode> } {
const slots = {}
if (!children) {
return slots
}
for (let i = 0, l = children.length; i < l; i++) {
const child = children[i]
const data = child.data
if (data && data.attrs && data.attrs.slot) {
delete data.attrs.slot
}
if ((child.context === context || child.fnContext === context) &&
data && data.slot != null
) {
const name = data.slot
const slot = (slots[name] || (slots[name] = []))
if (child.tag === 'template' ) {
slot.push.apply(slot, child.children || [])
} else {
slot.push(child)
}
} else {
(slots. default || (slots. default = [])).push(child)
}
}
for ( const name in slots) {
if (slots[name].every(isWhitespace)) {
delete slots[name]
}
}
return slots
}
|
Copier après la connexion
Ensuite, lorsque le composant dx-li est monté, la fonction de rendu du composant dx-li sera appelée dans le processus. , la fonction renderSlot sera appelée :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | export function renderSlot (
name: string,
fallback: ?Array<VNode>,
props: ?Object,
bindObject: ?Object
): ?Array<VNode> {
const scopedSlotFn = this. $scopedSlots [name]
let nodes
if (scopedSlotFn) {
props = props || {}
if (bindObject) {
if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) {
warn(
'slot v-bind without argument expects an Object' ,
this
)
}
props = extend(extend({}, bindObject), props)
}
nodes = scopedSlotFn(props) || fallback
} else {
const slotNodes = this. $slots [name]
if (slotNodes) {
if (process.env.NODE_ENV !== 'production' && slotNodes._rendered) {
warn(
`Duplicate presence of slot "${name}" found in the same render tree ` +
`- this will likely cause render errors.`,
this
)
}
slotNodes._rendered = true
}
nodes = slotNodes || fallback
}
const target = props && props.slot
if (target) {
return this. $createElement ( 'template' , { slot: target }, nodes)
} else {
return nodes
}
}
|
Copier après la connexion
scoped slots comprend
le modèle du sous-composant dx-li est le suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <li class = "dx-li" >
<slot str= "你好 掘金!" >
hello juejin!
</slot>
</li>
dx-ul父组件的template如下:
<ul>
<dx-li>
<span slot-scope= "scope" >
{{scope.str}}
</span>
</dx-li>
</ul>
结合例子和Vue源码简单作用域插槽
dx-ul父组件中template编译后,产生组件render函数:
module.exports={
render: function (){
var _vm=this;
var _h=_vm. $createElement ;
var _c=_vm._self._c||_h;
return _c( 'ul' , [_c( 'dx-li' , {
scopedSlots: _vm._u([{
key: "default" ,
fn: function (scope) {
return _c( 'span' ,
{},
[_vm._v(_vm._s(scope.str))]
)
}
}])
})], 1)
},
staticRenderFns: []
}
|
Copier après la connexion
où _vm._u fonction :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function resolveScopedSlots (
fns,
res
) {
res = res || {};
for ( var i = 0; i < fns.length; i++) {
if (Array.isArray(fns[i])) {
resolveScopedSlots(fns[i], res);
} else {
res[fns[i].key] = fns[i].fn;
}
}
return res
}
|
Copier après la connexion
du sous-composant Le processus de rendu ultérieur est similaire aux slots. Le principe des slots scoped est fondamentalement le même que celui des slots. La différence est que lors de la compilation du modèle de composant parent, une fonction qui renvoie un VNode sera générée. Lorsque le composant enfant correspond à la fonction scope slot transmise par le composant parent, la fonction est appelée pour générer le VNode correspondant.
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php. !
Lecture recommandée :
React implémente la synchronisation des données des numéros de téléphone mobile
Comment Babel convertit-il la syntaxe de la classe es6
Explication détaillée de l'utilisation du filtre Vue
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!