Bladeren bron

Revert "[WIP] Support for ref callback (#4807)"

This reverts commit acec8db2c4b54ac6f9cda7ab8fcc3bdd213eb3ed.
Evan You 9 jaren geleden
bovenliggende
commit
e7a2510e63
5 gewijzigde bestanden met toevoegingen van 32 en 102 verwijderingen
  1. 1 5
      flow/component.js
  2. 0 2
      src/core/instance/lifecycle.js
  3. 30 26
      src/core/vdom/modules/ref.js
  4. 1 1
      src/core/vdom/patch.js
  5. 0 68
      test/unit/features/ref.spec.js

+ 1 - 5
flow/component.js

@@ -2,10 +2,6 @@ import type { Config } from '../src/core/config'
 import type VNode from '../src/core/vdom/vnode'
 import type Watcher from '../src/core/observer/watcher'
 
-declare type Refs = {
-  [key: string]: Component | Element | Array<Component | Element> | void;
-};
-
 declare interface Component {
   // constructor information
   static cid: number;
@@ -28,7 +24,7 @@ declare interface Component {
   $parent: Component | void;
   $root: Component;
   $children: Array<Component>;
-  $refs: Refs;
+  $refs: { [key: string]: Component | Element | Array<Component | Element> | void };
   $slots: { [key: string]: Array<VNode> };
   $scopedSlots: { [key: string]: () => VNodeChildren };
   $vnode: VNode;

+ 0 - 2
src/core/instance/lifecycle.js

@@ -3,7 +3,6 @@
 import config from '../config'
 import { perf } from '../util/perf'
 import Watcher from '../observer/watcher'
-import { resetRefs } from '../vdom/modules/ref'
 import { createEmptyVNode } from '../vdom/vnode'
 import { observerState } from '../observer/index'
 import { updateComponentListeners } from './events'
@@ -56,7 +55,6 @@ export function lifecycleMixin (Vue: Class<Component>) {
     const prevVnode = vm._vnode
     const prevActiveInstance = activeInstance
     activeInstance = vm
-    vm.$refs = resetRefs(vm.$refs)
     vm._vnode = vnode
     // Vue.prototype.__patch__ is injected in entry points
     // based on the rendering backend used.

+ 30 - 26
src/core/vdom/modules/ref.js

@@ -1,40 +1,44 @@
 /* @flow */
 
+import { remove } from 'shared/util'
+
 export default {
-  create: registerRef,
-  update: registerRef
+  create (_: any, vnode: VNodeWithData) {
+    registerRef(vnode)
+  },
+  update (oldVnode: VNodeWithData, vnode: VNodeWithData) {
+    if (oldVnode.data.ref !== vnode.data.ref) {
+      registerRef(oldVnode, true)
+      registerRef(vnode)
+    }
+  },
+  destroy (vnode: VNodeWithData) {
+    registerRef(vnode, true)
+  }
 }
 
-export function registerRef (_: any, vnode: VNodeWithData) {
+export function registerRef (vnode: VNodeWithData, isRemoval: ?boolean) {
   const key = vnode.data.ref
   if (!key) return
 
+  const vm = vnode.context
   const ref = vnode.componentInstance || vnode.elm
-  const refs = vnode.context.$refs
-
-  if (typeof key === 'function') {
-    key(ref)
-  } else if (vnode.data.refInFor) {
-    const refArray = refs[key]
-    if (Array.isArray(refArray)) {
-      if (refArray.indexOf(ref) < 0) {
-        refArray.push(ref)
-      }
-    } else {
-      refs[key] = [ref]
+  const refs = vm.$refs
+  if (isRemoval) {
+    if (Array.isArray(refs[key])) {
+      remove(refs[key], ref)
+    } else if (refs[key] === ref) {
+      refs[key] = undefined
     }
   } else {
-    refs[key] = ref
-  }
-}
-
-export function resetRefs (refs: Refs): Refs {
-  const res = {}
-  // keep existing v-for ref arrays even if empty
-  for (const key in refs) {
-    if (Array.isArray(refs[key])) {
-      res[key] = []
+    if (vnode.data.refInFor) {
+      if (Array.isArray(refs[key]) && refs[key].indexOf(ref) < 0) {
+        refs[key].push(ref)
+      } else {
+        refs[key] = [ref]
+      }
+    } else {
+      refs[key] = ref
     }
   }
-  return res
 }

+ 1 - 1
src/core/vdom/patch.js

@@ -189,7 +189,7 @@ export function createPatchFunction (backend) {
     } else {
       // empty component root.
       // skip all element-related modules except for ref (#3455)
-      registerRef(null, vnode)
+      registerRef(vnode)
       // make sure to invoke the insert hook
       insertedVnodeQueue.push(vnode)
     }

+ 0 - 68
test/unit/features/ref.spec.js

@@ -157,72 +157,4 @@ describe('ref', () => {
     }).$mount()
     expect(vm.$refs.test).toBe(vm.$children[0])
   })
-
-  it('should should call callback method (v-for)', done => {
-    const vm = new Vue({
-      data: {
-        items: [1, 2, 3]
-      },
-      template: `
-        <div>
-          <test v-for="n in items" :key="n" :ref="onRef" :n="n"></test>
-        </div>
-      `,
-      components: {
-        test: {
-          props: ['n'],
-          template: '<div>{{ n }}</div>'
-        }
-      },
-      methods: {
-        onRef (ref) {
-          (this.$refs.list || (this.$refs.list = [])).push(ref)
-        }
-      }
-    }).$mount()
-    assertRefs()
-    // updating
-    vm.items.push(4)
-    waitForUpdate(assertRefs)
-      .then(() => { vm.items = [] })
-      .then(assertRefs)
-      .then(done)
-
-    function assertRefs () {
-      expect(Array.isArray(vm.$refs.list)).toBe(true)
-      expect(vm.$refs.list.length).toBe(vm.items.length)
-      expect(vm.$refs.list.every((comp, i) => comp.$el.textContent === String(i + 1))).toBe(true)
-    }
-  })
-
-  it('should should call inline callback (v-for)', done => {
-    const vm = new Vue({
-      data: {
-        items: [1, 2, 3]
-      },
-      template: `
-        <div>
-          <test v-for="n in items" :key="n" :ref="function (ref) { $refs[n] = ref }" :n="n"></test>
-        </div>
-      `,
-      components: {
-        test: {
-          props: ['n'],
-          template: '<div>{{ n }}</div>'
-        }
-      }
-    }).$mount()
-    assertRefs()
-    // updating
-    vm.items.push(4)
-    waitForUpdate(assertRefs)
-      .then(() => { vm.items = [] })
-      .then(assertRefs)
-      .then(done)
-
-    function assertRefs () {
-      expect(Object.keys(vm.$refs).length).toBe(vm.items.length)
-      expect(Object.keys(vm.$refs).every(i => vm.$refs[i].$el.textContent === String(i))).toBe(true)
-    }
-  })
 })