Repository: vuejs/vue
Pull request: feat(weex): support object syntax of class

Object syntax class is supported in Weex now:

```html
<div v-bind:class="{ active: isActive }"></div>
```


<!--
Please make sure to read the Pull Request Guidelines:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
-->

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [ ] Bugfix
- [x] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [x] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

**Other information:**


Changed files:
filename: src/platforms/weex/runtime/modules/class.js
patch: @@ -1,6 +1,6 @@
 /* @flow */
 
-import { extend } from 'shared/util'
+import { extend, isObject } from 'shared/util'
 
 function updateClass (oldVnode: VNodeWithData, vnode: VNodeWithData) {
   const el = vnode.elm
@@ -15,25 +15,8 @@ function updateClass (oldVnode: VNodeWithData, vnode: VNodeWithData) {
     return
   }
 
-  const oldClassList = []
-  // unlike web, weex vnode staticClass is an Array
-  const oldStaticClass: any = oldData.staticClass
-  if (oldStaticClass) {
-    oldClassList.push.apply(oldClassList, oldStaticClass)
-  }
-  if (oldData.class) {
-    oldClassList.push.apply(oldClassList, oldData.class)
-  }
-
-  const classList = []
-  // unlike web, weex vnode staticClass is an Array
-  const staticClass: any = data.staticClass
-  if (staticClass) {
-    classList.push.apply(classList, staticClass)
-  }
-  if (data.class) {
-    classList.push.apply(classList, data.class)
-  }
+  const oldClassList = makeClassList(oldData)
+  const classList = makeClassList(data)
 
   if (typeof el.setClassList === 'function') {
     el.setClassList(classList)
@@ -49,6 +32,22 @@ function updateClass (oldVnode: VNodeWithData, vnode: VNodeWithData) {
   }
 }
 
+function makeClassList (data: VNodeData): Array<string> {
+  const classList = []
+  // unlike web, weex vnode staticClass is an Array
+  const staticClass: any = data.staticClass
+  const dataClass = data.class
+  if (staticClass) {
+    classList.push.apply(classList, staticClass)
+  }
+  if (Array.isArray(dataClass)) {
+    classList.push.apply(classList, dataClass)
+  } else if (isObject(dataClass)) {
+    classList.push.apply(classList, Object.keys(dataClass).filter(className => dataClass[className]))
+  }
+  return classList
+}
+
 function getStyle (oldClassList: Array<string>, classList: Array<string>, ctx: Component): Object {
   // style is a weex-only injected object
   // compiled from <style> tags in weex files

filename: test/weex/cases/cases.spec.js
patch: @@ -54,6 +54,7 @@ function createEventTestCase (name) {
 describe('Usage', () => {
   describe('render', () => {
     it('sample', createRenderTestCase('render/sample'))
+    it('class', createRenderTestCase('render/class'))
   })
 
   describe('event', () => {

filename: test/weex/cases/render/class.vdom.js
patch: @@ -0,0 +1,19 @@
+({
+  type: 'div',
+  children: [{
+    type: 'div',
+    classList: ['box', 'box1']
+  }, {
+    type: 'div',
+    classList: ['box', 'box2']
+  }, {
+    type: 'div',
+    classList: ['box', 'box3']
+  }, {
+    type: 'div',
+    classList: ['box', 'box4']
+  }, {
+    type: 'div',
+    classList: ['box', 'box5']
+  }]
+})

filename: test/weex/cases/render/class.vue
patch: @@ -0,0 +1,56 @@
+<template>
+  <div>
+    <div :class="class1"></div>
+    <div :class="class2"></div>
+    <div class="box" :class="class3"></div>
+    <div class="box" :class="class4"></div>
+    <div class="box" :class="{ box5: class5 }"></div>
+  </div>
+</template>
+
+<style scoped>
+  .box {
+    width: 100px;
+    height: 100px;
+  }
+
+  .box1 {
+    background-color: #DDD;
+  }
+
+  .box2 {
+    background-color: #CCC;
+  }
+
+  .box3 {
+    background-color: #BBB;
+  }
+
+  .box4 {
+    background-color: #AAA;
+  }
+
+  .box5 {
+    background-color: #999;
+  }
+</style>
+
+<script>
+  module.exports = {
+    data () {
+      return {
+        class1: ['box', 'box1'],
+        class2: {
+          'box': true,
+          'box1': false,
+          'box2': true
+        },
+        class3: ['box3'],
+        class4: {
+          'box4': true
+        },
+        class5: true
+      }
+    }
+  }
+</script>
\ No newline at end of file