establish.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <view class="yt-txl-container">
  3. <view class="search">
  4. <input type="text" @input="inputFunc" class="s-input" placeholder="请输入姓氏搜索" />
  5. </view>
  6. <view class="scroll" :style="index ? '' :'right:25upx'">
  7. <scroll-view :scroll-into-view="to" scroll-y style="width: 100%;height: 100%;">
  8. <view :id="o.key" v-for="(o,i) in resource" :key="i">
  9. <view class="p" >{{o.key}}</view>
  10. <view @click="clickFunc(item)" v-for="(item,index) in o.data" class="info" :key="index" @tap="choice">
  11. <view class="item">
  12. <text class="name">{{item[name]}}</text>
  13. </view>
  14. </view>
  15. </view>
  16. </scroll-view>
  17. </view>
  18. <view class="flag" v-if="index">
  19. <scroll-view scroll-y="true" :show-scrollbar="false" class="flag-scroll" style="width: 100%;height: 100%;">
  20. <view @click="toFunc(o.key)" class="flag-key" v-for="(o,i) in resource" :key="i">
  21. {{o.key}}
  22. </view>
  23. </scroll-view>
  24. </view>
  25. </view>
  26. </template>
  27. <script>
  28. import tuiIcon from "@/components/thorui/tui-icon/tui-icon"
  29. import tuiButton from "@/components/thorui/tui-button/tui-button"
  30. 'use strict';
  31. let pinyin = new(require('./pinyin'))({
  32. charCase: 0
  33. });
  34. export default {
  35. components: {
  36. tuiIcon,
  37. tuiButton
  38. },
  39. props: {
  40. datas: {
  41. type: Array,
  42. default () {
  43. return [];
  44. }
  45. },
  46. name: {
  47. type: String,
  48. default () {
  49. return "name";
  50. }
  51. },
  52. index: {
  53. type: Boolean,
  54. default: true
  55. },
  56. color: {
  57. type:String,
  58. default:"#ffffff"
  59. }
  60. },
  61. data() {
  62. return {
  63. resource: [],
  64. chars: [],
  65. to: "",
  66. cache:[]
  67. };
  68. },
  69. watch: {
  70. datas(r) {
  71. if (!(r instanceof Array)) {
  72. console.log("the props datas type must be array")
  73. return
  74. }
  75. this._parseData(r)
  76. }
  77. },
  78. methods: {
  79. choice: function() {
  80. uni.navigateTo({
  81. url: './choice'
  82. });
  83. },
  84. toFunc(o) {
  85. this.to = o
  86. },
  87. clickFunc(item){
  88. this.$emit("ev",item)
  89. },
  90. inputFunc(r){ //搜索功能
  91. if(!r.detail.value) {
  92. this.resource = this.cache
  93. return
  94. }
  95. let temp = []
  96. this.cache.forEach(o => {
  97. o.data.forEach(item =>{
  98. if(item[this.name].indexOf(r.detail.value) > -1){ // 匹配到
  99. // 确定当前这个元素的key是谁
  100. let key = o.key
  101. // 找到temp中的key
  102. let index = 0 //下标
  103. let find = false // 数据是否存在
  104. for(let d in temp){
  105. if(temp[d].key === o.key){
  106. index = d
  107. find = true
  108. }
  109. }
  110. if(find){ // 如果key已经存在,直接插入数据
  111. temp[index].data.push(item)
  112. } else { // 不存在初始化一个并存入
  113. temp.push({
  114. key:o.key,
  115. data:[item]
  116. })
  117. }
  118. }
  119. })
  120. })
  121. this.resource = temp
  122. },
  123. _type(val){
  124. return Object.prototype.toString.call(val).slice(8,-1).toLowerCase()
  125. },
  126. _parseData(r) {
  127. // 生成a-z的数组
  128. let data = [];
  129. this.chars = []
  130. for (let i = 65; i <= 90; i++) {
  131. let key = String.fromCharCode(i)
  132. data.push({"key":key,data:[]})
  133. this.chars.push(key)
  134. }
  135. if(this._type(r) === "array") {
  136. // 填充数据
  137. r.forEach(o => {
  138. // 找到char的位置
  139. data.forEach( (item,index) => {
  140. let a = this._parseChar(o[this.name || 'name'])
  141. if(item.key === a){
  142. data[index].data.push(o)
  143. }
  144. })
  145. })
  146. }
  147. // 组合最后数据并踢出没有匹配到a-z中的任意数据
  148. let finalData = []
  149. for (let i in data) {
  150. if(data[i].data.length > 0){
  151. finalData.push(data[i])
  152. }
  153. }
  154. this.resource = finalData
  155. this.cache = finalData
  156. finalData = null
  157. },
  158. _parseChar(name) {
  159. if (Object.prototype.toString.call(name).slice(8, -1) !== 'String') {
  160. console.error("name is not string")
  161. return
  162. }
  163. let chars = pinyin.getFullChars(name);
  164. return chars[0].toUpperCase()
  165. }
  166. },
  167. mounted() {
  168. this._parseData(this.datas)
  169. }
  170. };
  171. </script>
  172. <style>
  173. page {
  174. background: #f4f4f4;
  175. }
  176. .search {
  177. width: 100%;
  178. height: 120upx;
  179. display: flex;
  180. justify-content: center;
  181. align-items: center;
  182. }
  183. .s-input {
  184. width: 100%;
  185. height: 80upx;
  186. background: url('data:image/png;base64,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') 20upx center no-repeat #fff;
  187. background-size: 40upx;
  188. text-indent: 80upx;
  189. }
  190. .scroll {
  191. position: absolute;
  192. top: 120upx;
  193. bottom: 25upx;
  194. width: 100%;
  195. }
  196. .p {
  197. position: sticky;
  198. top: 0;
  199. left: 0;
  200. background: #f4f4f4;
  201. font-size: 28upx;
  202. margin-bottom: 10upx;
  203. text-indent: 40upx;
  204. z-index: 99998;
  205. font-weight: bold;
  206. }
  207. .info {
  208. display: inline-grid;
  209. align-items: center;
  210. margin-bottom: 4upx;
  211. padding: 20upx 25upx;
  212. background: #fff;
  213. width: 64rpx;
  214. height: 64rpx;
  215. margin: 2rpx;
  216. text-align: center;
  217. }
  218. .icon {
  219. width: 64upx;
  220. height: 64upx;
  221. border-radius: 50%;
  222. margin-right: 20upx;
  223. display: flex;
  224. justify-content: center;
  225. align-items: center;
  226. font-size: 30upx;
  227. color: #fff;
  228. }
  229. .item {
  230. display: flex;
  231. flex-direction: column;
  232. justify-content: space-around;
  233. }
  234. .flag {
  235. width: 50rpx;
  236. position: fixed;
  237. top: 200upx;
  238. right: 0;
  239. bottom: 0;
  240. z-index: 99999;
  241. /* #ifdef H5 */
  242. top: 300upx;
  243. /* #endif */
  244. }
  245. .flag-scroll {
  246. padding-top: 10upx;
  247. }
  248. .flag-key {
  249. padding: 0;
  250. margin: 0 auto 2upx auto;
  251. width: 30upx;
  252. height: 30upx;
  253. border-radius: 50%;
  254. color: #000;
  255. font-weight: bold;
  256. display: flex;
  257. justify-content: center;
  258. align-items: center;
  259. font-size: 20upx;
  260. }
  261. </style>