Explorar el Código

support _scopeId

Evan You hace 10 años
padre
commit
7503f8eb15

+ 12 - 0
src/core/vdom/patch.js

@@ -78,6 +78,7 @@ export function createPatchFunction (backend) {
       // in that case we can just return the element and be done.
       if (isDef(i = vnode.child)) {
         invokeCreateHooks(vnode, insertedVnodeQueue)
+        setScope(vnode)
         return vnode.elm
       }
     }
@@ -87,6 +88,7 @@ export function createPatchFunction (backend) {
       elm = vnode.elm = vnode.ns
         ? nodeOps.createElementNS(vnode.ns, tag)
         : nodeOps.createElement(tag)
+      setScope(vnode)
       if (Array.isArray(children)) {
         for (i = 0; i < children.length; ++i) {
           nodeOps.appendChild(elm, createElm(children[i], insertedVnodeQueue))
@@ -114,6 +116,16 @@ export function createPatchFunction (backend) {
     }
   }
 
+  // set scope id attribute for scoped CSS.
+  // this is implemented as a special case to avoid the overhead
+  // of going through the normal attribute patching process.
+  function setScope (vnode) {
+    let i
+    if (isDef(i = vnode.context) && isDef(i = i.$options._scopeId)) {
+      nodeOps.setAttribute(vnode.elm, i, '')
+    }
+  }
+
   function addVnodes (parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
     for (; startIdx <= endIdx; ++startIdx) {
       nodeOps.insertBefore(parentElm, createElm(vnodes[startIdx], insertedVnodeQueue), before)

+ 4 - 0
src/platforms/web/runtime/node-ops.js

@@ -45,3 +45,7 @@ export function setTextContent (node: Node, text: string) {
 export function childNodes (node: Node): NodeList {
   return node.childNodes
 }
+
+export function setAttribute (node: Element, key: string, val: string) {
+  node.setAttribute(key, val)
+}

+ 8 - 0
test/unit/modules/vdom/patch/element.spec.js

@@ -1,3 +1,4 @@
+import Vue from 'vue'
 import { patch } from 'web/runtime/patch'
 import VNode from 'core/vdom/vnode'
 
@@ -30,4 +31,11 @@ describe('element', () => {
     expect(elm.childNodes[0].tagName).toBe('SPAN')
     expect(elm.childNodes[1].textContent).toBe('hello world')
   })
+
+  it('should create element with scope attribute', () => {
+    const vnode = new VNode('div')
+    vnode.context = new Vue({ _scopeId: 'foo' })
+    const elm = patch(null, vnode)
+    expect(elm.hasAttribute('foo')).toBe(true)
+  })
 })