From e2709d809e49f3364d12f7a381bdcf9f4636f644 Mon Sep 17 00:00:00 2001
From: tangjinzhou <415800467@qq.com>
Date: Thu, 22 Feb 2018 17:19:47 +0800
Subject: [PATCH] fix

---
 components/align/Align.vue           |  5 +-
 components/trigger/Popup.vue         |  8 +++-
 components/vc-select/Select.vue      | 25 +++++++---
 components/vc-select/demo/single.vue |  4 +-
 components/vc-select/demo/tags.vue   | 70 ++++++++++++++++++++++++++++
 components/vc-select/util.js         |  5 +-
 examples/routes.js                   |  2 +-
 7 files changed, 104 insertions(+), 15 deletions(-)
 create mode 100644 components/vc-select/demo/tags.vue

diff --git a/components/align/Align.vue b/components/align/Align.vue
index 8e4e4e794..9ca83a79e 100644
--- a/components/align/Align.vue
+++ b/components/align/Align.vue
@@ -36,6 +36,7 @@ export default {
     monitorBufferTime: PropTypes.number.def(50),
     monitorWindowResize: PropTypes.bool.def(false),
     disabled: PropTypes.bool.def(false),
+    visible: PropTypes.bool.def(false),
   },
   data () {
     this.aligned = false
@@ -55,8 +56,8 @@ export default {
     const prevProps = this.prevProps
     const props = this.$props
     let reAlign = false
-    if (!props.disabled) {
-      if (prevProps.disabled || !isEqual(prevProps.align, props.align)) {
+    if (!props.disabled && this.visible) {
+      if (prevProps.disabled || prevProps.align !== props.align) {
         reAlign = true
       } else {
         const lastTarget = prevProps.target()
diff --git a/components/trigger/Popup.vue b/components/trigger/Popup.vue
index 7424f596a..465e0655f 100644
--- a/components/trigger/Popup.vue
+++ b/components/trigger/Popup.vue
@@ -129,10 +129,13 @@ export default {
       const transitionEvent = {
         beforeEnter: (el) => {
           el.style.display = el.__vOriginalDisplay
-          this.$refs.alignInstance.forceAlign()
+          // this.$refs.alignInstance.forceAlign()
         },
         enter: (el, done) => {
-          animate(el, `${transitionName}-enter`, done)
+          // align updated后执行动画
+          this.$nextTick(() => {
+            animate(el, `${transitionName}-enter`, done)
+          })
         },
         leave: (el, done) => {
           animate(el, `${transitionName}-leave`, done)
@@ -169,6 +172,7 @@ export default {
           monitorWindowResize
           align={align}
           onAlign={this.onAlign}
+          visible={visible}
         >
           <PopupInner
             {...popupInnerProps}
diff --git a/components/vc-select/Select.vue b/components/vc-select/Select.vue
index 1a7fa7b31..28ac6790d 100644
--- a/components/vc-select/Select.vue
+++ b/components/vc-select/Select.vue
@@ -6,7 +6,7 @@ import classes from 'component-classes'
 import { Item as MenuItem, ItemGroup as MenuItemGroup } from '../vc-menu'
 import warning from 'warning'
 import Option from './Option'
-import { hasProp, getSlotOptions } from '../_util/props-util'
+import { hasProp, getSlotOptions, getKey } from '../_util/props-util'
 import getTransitionProps from '../_util/getTransitionProps'
 import { cloneElement, getClass, getPropsData, getValueByProp as getValue, getEvents } from '../_util/vnode'
 import BaseMixin from '../_util/BaseMixin'
@@ -98,6 +98,7 @@ export default {
     if (sValue.length > 0) {
       this._valueOptions = this.getOptionsByValue(sValue)
     }
+    console.log(sValue)
     return {
       sValue,
       inputValue,
@@ -166,11 +167,23 @@ export default {
     }
   },
   methods: {
-    updateLabelAndTitleMap () {
-      const labelMap = {}
-      const titleMap = {}
-      this.labelMap = labelMap
-      this.titleMap = titleMap
+    updateLabelAndTitleMap (children = []) {
+      this.titleMap = {}
+      this.updateTitleMap(this.$slots.default)
+    },
+    updateTitleMap (children = []) {
+      children.forEach(child => {
+        if (!child) {
+          return
+        }
+        if (getSlotOptions(child).isSelectOptGroup) {
+          this.updateTitleMap(child.componentOptions.children)
+        } else {
+          const key = getValuePropValue(child)
+          this.titleMap[key] = getValue(child, 'title')
+          this.labelMap[key] = this.getLabelFromOption(child)
+        }
+      })
     },
     updateState () {
       const { combobox, $slots } = this
diff --git a/components/vc-select/demo/single.vue b/components/vc-select/demo/single.vue
index ccbabd09f..155be8635 100644
--- a/components/vc-select/demo/single.vue
+++ b/components/vc-select/demo/single.vue
@@ -6,7 +6,7 @@ export default {
   data () {
     return {
       destroy: false,
-      value: '01',
+      value: 'hello',
     }
   },
   methods: {
@@ -58,7 +58,7 @@ export default {
           firstActiveValue='2'
           backfill
         >
-          <Option value='01' text='jack' title='jack'>
+          <Option key='hello' text='jack' title='jack'>
             <b
               style={{
                 color: 'red',
diff --git a/components/vc-select/demo/tags.vue b/components/vc-select/demo/tags.vue
new file mode 100644
index 000000000..364e38959
--- /dev/null
+++ b/components/vc-select/demo/tags.vue
@@ -0,0 +1,70 @@
+<script>
+import Select, { Option } from '../index'
+import '../assets/index.less'
+
+export default {
+  data () {
+    return {
+      disabled: false,
+      value: ['name2', 'name3'],
+      maxTagCount: undefined,
+    }
+  },
+  methods: {
+    onChange (value, option) {
+      console.log(`changed ${value}`, option)
+      this.value = value
+    },
+
+    onSelect (value, option) {
+      console.log(`selected ${value}`, option.props)
+    },
+
+    onDeselect (value, option) {
+      console.log(`deselected ${value}`, option)
+    },
+
+    toggleDisabled () {
+      this.disabled = !this.disabled
+    },
+
+    toggleMaxTagCount (count) {
+      this.maxTagCount = count
+    },
+  },
+
+  render () {
+    const children = []
+    for (let i = 10; i < 36; i++) {
+      children.push(<Option key={i.toString(36) + i} test={i}>{i.toString(36) + i}</Option>)
+    }
+    return (<div>
+      <h2>tags select(scroll the menu)</h2>
+
+      <div>
+        <Select
+          placeholder='placeholder'
+          tags
+          dropdownMenuStyle={{ maxHeight: '200px' }}
+          style={{ width: '500px' }}
+          disabled={this.disabled}
+          maxTagCount={this.maxTagCount}
+          maxTagTextLength={10}
+          value={this.value}
+          onChange={this.onChange}
+          onSelect={this.onSelect}
+          onDeselect={this.onDeselect}
+          tokenSeparators={[' ', ',']}
+        >
+          {children}
+        </Select>
+      </div>
+      <p>
+        <button onClick={this.toggleDisabled}>toggle disabled</button>
+        <button onClick={() => this.toggleMaxTagCount(0)}>toggle maxTagCount (0)</button>
+        <button onClick={() => this.toggleMaxTagCount(1)}>toggle maxTagCount (1)</button>
+      </p>
+    </div>)
+  },
+}
+</script>
diff --git a/components/vc-select/util.js b/components/vc-select/util.js
index 7569640f6..d11a32a6f 100644
--- a/components/vc-select/util.js
+++ b/components/vc-select/util.js
@@ -1,4 +1,5 @@
 import { getPropsData, getSlotOptions, getKey, getAttrs } from '../_util/props-util'
+import { cloneVNodes } from '../_util/vnode'
 export function getValuePropValue (child) {
   const props = getPropsData(child)
   if ('value' in props) {
@@ -21,9 +22,9 @@ export function getPropValue (child, prop) {
   }
   if (prop === 'children') {
     if (child.$slots) {
-      return child.$slots.default
+      return cloneVNodes(child.$slots.default, true)
     } else {
-      return child.componentOptions.children
+      return cloneVNodes(child.componentOptions.children, true)
     }
   }
   const data = getPropsData(child)
diff --git a/examples/routes.js b/examples/routes.js
index 5e4a0d694..5a51123a9 100644
--- a/examples/routes.js
+++ b/examples/routes.js
@@ -3,7 +3,7 @@ const AsyncComp = () => {
   const hashs = window.location.hash.split('/')
   const d = hashs[hashs.length - 1]
   return {
-    component: import(`../components/vc-select/demo/${d}.vue`),
+    component: import(`../components/vc-select/demo/single.vue`),
   }
 }
 export default [