# 3.3 侧边导航(Side nav)

用于让用户在不同的视图中进行切换。

# 纵向导航栏

多用于插件页二级页面存在多种分类的场景中,位于页面左侧
标签文字:建议控制在 2-7 个字内
标签数量:不限
颜色:白色或 #f9f9f9 背景时用黑色文字和黑色标识;深色背景时用白色文字和白色标识
滑动规律:
1、点击纵向选项卡中的某一选项卡,右侧页面应跳转到相应页面
2、若右侧页面可以滑动,当滑动右侧页面时,左侧选项卡应变更到相应位置
3、当纵向选项卡类别占位超过页面的一半,点击超过屏幕一半位置的选项卡,此时纵向选项卡应上移,使得被选中的选项卡处于页面中央位置。



# dof-side-nav

# 实例

# 基础用法

<template>
  <div>
    <div ref="titleBar">
      <dof-minibar
        title="侧边导航"
        background-color="#ffffff"
        :isImage="true"
        :left-button="leftButton"
        @dofMinibarLeftButtonClicked="back"
        @dofMinibarRightButtonClicked="minibarRightButtonClick"
      ></dof-minibar>
    </div>
    <!-- ios版本样式 -->
    <list
      class="right-content-ios"
      @scroll="scrollHandler"
      show-scrollbar="false"
      :style="{ 'padding-left': contentLeftDis + 'px' }"
      v-if="!isAndroid"
    >
      <cell v-for="(item, index) in contentData" :key="index" :ref="'item-' + item.proId">
        <text @appear="onappearHandler(index)">{{ item.name }}</text>
        <div class="list-image">
          <image
            :src="cItem"
            class="cell-image"
            :aria-hidden="true"
            v-for="(cItem, cIndex) in item.list0"
            :key="cIndex"
          ></image>
        </div>
        <!-- 放一条细线监听元素是否disappear -->
        <div class="line-red" @disappear="ondisappearHandler(index)"></div>
      </cell>
    </list>
    <div class="demo-content-ios" :style="{ top: titleBarHeight + 'px' }" v-if="!isAndroid">
      <dof-side-nav
        :items="dataList"
        :defaultStyle="defaultStyle"
        :height="deviceHeight"
        :backgroundColor="backgroundColor"
        @dofItemClick="dofItemClick"
        :activeFontSize="activeFontSize"
        :activeTextColor="activeTextColor"
        :activeBlockColor="activeBlockColor"
        :activeIndex="activeIndex"
      ></dof-side-nav>
    </div>
    <!-- 安卓版本样式 -->
    <div class="column-center-top" v-if="isAndroid">
      <div class="demo-content">
        <dof-side-nav
          :items="dataList"
          :defaultStyle="defaultStyle"
          :height="deviceHeight"
          :backgroundColor="backgroundColor"
          @dofItemClick="dofItemClick"
          :activeFontSize="activeFontSize"
          :activeTextColor="activeTextColor"
          :activeBlockColor="activeBlockColor"
          :activeIndex="activeIndex"
        ></dof-side-nav>
        <list class="right-content" @scroll="scrollHandler" :style="{ height: contentHeight }">
          <cell v-for="(item, index) in contentData" :key="index" :ref="'item-' + item.proId">
            <text @appear="onappearHandler(index)">{{ item.name }}</text>
            <div class="list-image">
              <image
                :src="cItem"
                class="cell-image"
                :aria-hidden="true"
                v-for="(cItem, cIndex) in item.list0"
                :key="cIndex"
              ></image>
            </div>
            <!-- 放一条细线监听元素是否disappear -->
            <div class="line-red" @disappear="ondisappearHandler(index)"></div>
          </cell>
        </list>
      </div>
    </div>
  </div>
</template>

<style scoped>
.demo-content-ios {
  position: absolute;
  left: 0;
}
.column-center-top {
  display: flex;
}
.demo-content {
  display: flex;
  flex-direction: row;
}

.right-content-ios {
  padding: 30px 30px 0 30px;
}
.right-content {
  flex: 1;
  padding: 30px 30px 0 30px;
}

.cell-image {
  width: 200px;
  height: 200px;
  margin: 0 20px 20px 0;
}
.list-image {
  margin: 30px 0;
  width: auto;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
.line-red {
  width: auto;
  height: 1px;
  margin-bottom: 20px;
}
</style>
<script>
import { DofMinibar, DofSideNav } from 'dolphin-weex-ui'
const dom = weex.requireModule('dom')
const modal = weex.requireModule('modal')
const isAndroid = weex.config.env.platform == 'android' ? true : false
let remote_pic =
  'https://bpic.588ku.com/element_list_pic/19/03/06/b933751940fe6ff5ee29c42e7d1edbcb.jpg!/fw/253/quality/90/unsharp/true/compress/true'

export default {
  components: { DofMinibar, DofSideNav },
  data: () => ({
    leftButton: 'http://dolphin-weex-dev.msmartlife.cn/cdn/images/header/icon_back@3x.png',
    dataList: ['空调', '冰箱', '洗衣机', '厨房大电', '厨房小电', '热水器', '净水/饮水', '生活护理', '家居家装'],
    contentData: [
      {
        name: '空调',
        proId: 10,
        list0: [remote_pic, remote_pic]
      },
      {
        name: '冰箱',
        proId: 11,
        list0: [remote_pic, remote_pic, remote_pic]
      },
      {
        name: '洗衣机',
        proId: 12,
        list0: [remote_pic]
      },
      {
        name: '厨房大电',
        proId: 13,
        list0: [remote_pic, remote_pic, remote_pic, remote_pic, remote_pic]
      },
      {
        name: '厨房小电',
        proId: 14,
        list0: [remote_pic, remote_pic, remote_pic, remote_pic, remote_pic]
      },
      {
        name: '热水器',
        proId: 15,
        list0: [remote_pic, remote_pic, remote_pic, remote_pic]
      },
      {
        name: '净水/饮水',
        proId: 16,
        list0: [remote_pic, remote_pic]
      },
      {
        name: '生活护理',
        proId: 17,
        list0: [remote_pic, remote_pic]
      },
      {
        name: '家居家装',
        proId: 18,
        list0: [
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic,
          remote_pic
        ]
      }
    ],
    defaultStyle: {
      width: 200,
      height: 92,
      fontSize: 24,
      color: '#999999'
    },
    activeFontSize: 28,
    backgroundColor: '#f9f9f9',
    activeTextColor: '#333333',
    activeBlockColor: '#333333',
    proName: '',
    activeIndex: 0,
    preScrollY: 0,
    scrollDirection: '',
    titleBarHeight: 0,
    dofItemClickFlag: false, //左边item点击标识
    setTimeoutHandler: null,
    isAndroid,
    remote_pic:
      'https://bpic.588ku.com/element_list_pic/19/03/06/b933751940fe6ff5ee29c42e7d1edbcb.jpg!/fw/253/quality/90/unsharp/true/compress/true'
  }),

  created() {},
  computed: {
    deviceHeight() {
      return weex.config.env.realDeviceHeight || weex.config.env.deviceHeight
    },
    contentHeight() {
      return this.deviceHeight - this.titleBarHeight
    },
    contentLeftDis() {
      return this.defaultStyle.width + 20
    }
  },
  mounted() {
    this.$nextTick(() => {
      let ele = this.$refs.titleBar
      this.getEleHeight(ele.children[0])
    })
  },
  methods: {
    dofItemClick(value) {
      let self = this
      if (this.setTimeoutHandler) {
        clearTimeout(this.setTimeoutHandler)
      }
      this.proName = value.item
      this.activeIndex = value.index
      //对应右边滑动
      this.dofItemClickFlag = true
      this.makeScrollToELe(this.activeIndex)
      this.setTimeoutHandler = setTimeout(() => {
        self.dofItemClickFlag = false
        clearTimeout(self.setTimeoutHandler)
      }, 500)
    },
    makeScrollToELe(index) {
      let currId = this.contentData[index]['proId']
      let currItemId = `item-${currId}`
      let el = this.$refs[currItemId][0]
      dom.scrollToElement(el, {}, () => {
        modal.toast({
          message: 'finish'
        })
      })
    },
    scrollHandler(e) {
      let currScrollY = parseInt(e.contentOffset.y)
      if (currScrollY > this.preScrollY) {
        //页面向下滑
        this.scrollDirection = 'down'
      } else {
        //页面向上滑
        this.scrollDirection = 'up'
      }
      this.preScrollY = currScrollY
    },
    onappearHandler(index) {
      if (this.scrollDirection == 'down' && !this.dofItemClickFlag) {
        this.activeIndex = index
      }
    },
    ondisappearHandler(index) {
      if (this.scrollDirection == 'up' && !this.dofItemClickFlag) {
        this.activeIndex = index + 1
      }
    },
    getEleHeight(ele) {
      let self = this
      dom.getComponentRect(ele, result => {
        let size = result.size || {}
        let height = parseInt(size.height)
        if (!height) {
          self.getEleHeight(ele)
        } else {
          self.titleBarHeight = height
        }
      })
    }
  }
}
</script>


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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

# Attributes

Prop Type Required Default Description
height [Number, String] N 600 高度
items Array Y {} 数据列表
activeFontSize Number N 28 选中时文字font-size
activeIndex Number N 0 当前选中index
activeTextColor String N #333333 选中时文字color
activeBlockColor String N #333333 选中时标志块背景颜色
defaultStyle Object N {} 自定义样式
backgroundColor String N #f9f9f9 组件整体背景颜色

# Events

事件名 说明 回调参数
dofItemClick 点击选项 e
Last Updated: 7/20/2023, 2:20:51 PM