tm-icons.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <!-- 图标 -->
  3. <view @click="onclick" v-if="name" class="tm-icons vertical-align-top" style="display: inline-block;font-size: 0;" >
  4. <view class="flex-center " :style="{
  5. width: sizes,
  6. height: sizes,
  7. lineHeight:sizes,
  8. }">
  9. <block v-if="vtype == false">
  10. <image :src="name" :style="{
  11. width: sizes,
  12. height: sizes
  13. }" mode="scaleToFill"></image>
  14. </block>
  15. <block v-if="vtype == true">
  16. <!-- #ifdef APP-NVUE -->
  17. <text :style="{
  18. fontSize: sizes,
  19. fontFamily:'iconfontTM'
  20. }" class="icons "
  21. :class="[ black_tmeme ? colors+'-bk':colors, dense ? '' : 'pa-10', black ? 'opacity-6' : '']">{{iconName}}</text>
  22. <!-- #endif -->
  23. <!-- #ifdef MP -->
  24. <text :style="{
  25. fontSize: sizes,
  26. }" class="icons mt--4"
  27. :class="[prefx_computed, black_tmeme ? 'bk' : '', iconName, colorTheme ? colors : '', dense ? '' : 'pa-10', black ? 'opacity-6' : '']"></text>
  28. <!-- #endif -->
  29. <!-- #ifndef MP -->
  30. <text :style="{
  31. fontSize: sizes,
  32. }" class="icons "
  33. :class="[prefx_computed, black_tmeme ? 'bk' : '', iconName, colorTheme ? colors : '', dense ? '' : 'pa-10', black ? 'opacity-6' : '']"></text>
  34. <!-- #endif -->
  35. </block>
  36. </view>
  37. </view>
  38. </template>
  39. <script>
  40. /**
  41. * 图标组件
  42. * @property {Boolean} dense = [true|false] 默认false,是否去除边距
  43. * @property {String} prefx = [iconfont] 默认iconfont,默认图标的前缀,对自定义图标时有好处。
  44. * @property {String} name = [] 默认'',图标名称,注意不带前缀。
  45. * @property {String | Number} size = [] 默认28, 图标大小,单位是upx
  46. * @property {String} color = [primary] 默认primary, 图标主题颜色名
  47. * @property {Function} click 图标点击事件。
  48. * @example <tm-icons name='icon-clear'></tm-icons>
  49. */
  50. export default {
  51. props: {
  52. dense: {
  53. //是否小边距
  54. type: Boolean,
  55. default: false
  56. },
  57. black: {
  58. type: Boolean,
  59. default: null
  60. },
  61. prefx: {
  62. type: String, //前缀
  63. default: 'iconfont'
  64. },
  65. name: {
  66. type: String, //图标名称。
  67. default: ''
  68. },
  69. size: {
  70. type: String | Number, //图标名称。
  71. default: 28
  72. },
  73. color: {
  74. type: String, //颜色名称或者颜色值。
  75. default: 'primary'
  76. },
  77. //强制转换图标类型,不通过内置判定,解决自己引用图片svg图标时当作字体图标的错误。
  78. iconType: {
  79. type: String,
  80. default: '' //img|icon
  81. },
  82. // 跟随主题色的改变而改变。
  83. fllowTheme: {
  84. type: Boolean | String,
  85. default: false
  86. }
  87. },
  88. computed: {
  89. iconName: function() {
  90. // #ifdef APP-NVUE || APP-PLUS-NVUE
  91. let fontList = require('@/tm-vuetify/scss/iconfonts/iconfont.json');
  92. let name = this.name.replace('icon-', '');
  93. // fontList.glyphs
  94. let itemIcon = fontList.glyphs.find((item, index) => {
  95. return item.font_class == name;
  96. })
  97. return eval('"\\u' + itemIcon.unicode + '"');
  98. // #endif
  99. return this.name;
  100. },
  101. prefx_computed(){
  102. let prefix = this.name.split('-')[0];
  103. if(prefix=='icon') return 'iconfont';
  104. if(prefix=='mdi') return 'mdi';
  105. return prefix;
  106. },
  107. black_tmeme: function() {
  108. return this.$tm.vx.state().tmVuetify.black;
  109. },
  110. vtype: function() {
  111. if (this.name[0] == "." ||
  112. this.name[0] == "/" ||
  113. this.name.substring(0, 4) == 'http' ||
  114. this.name.substring(0, 5) == 'https' ||
  115. this.name.substring(0, 3) == 'ftp'
  116. ) {
  117. return false;
  118. }
  119. return true;
  120. },
  121. sizes: function() {
  122. if (typeof this.size === 'string') {
  123. if (/[rpx|upx|rem|em|vx|vh|px]$/.test(this.size)) {
  124. return this.size;
  125. }
  126. return uni.upx2px(parseInt(this.size)) + 'px';
  127. }
  128. if (typeof this.size === 'number' && !isNaN(this.size)) {
  129. return uni.upx2px(this.size) + 'px';
  130. }
  131. },
  132. color_tmeme: function() {
  133. if (this.$tm.vx.state().tmVuetify.color !== null && this.$tm.vx.state().tmVuetify.color && this
  134. .fllowTheme) {
  135. return this.$tm.vx.state().tmVuetify.color;
  136. }
  137. return this.color;
  138. },
  139. colors: {
  140. get: function() {
  141. if (!this.color_tmeme) return 'text-primary';
  142. if (!this.$TestColor(this.color_tmeme)) {
  143. return this.color_tmeme;
  144. }
  145. return 'text-' + this.color_tmeme;
  146. },
  147. set: function() {
  148. if (!this.$TestColor(this.color_tmeme)) {
  149. this.colorTheme = false;
  150. return this.color_tmeme;
  151. }
  152. this.colorTheme = true;
  153. }
  154. }
  155. },
  156. data() {
  157. return {
  158. colorTheme: true
  159. };
  160. },
  161. methods: {
  162. onclick(e) {
  163. this.$emit('click', e);
  164. }
  165. }
  166. };
  167. </script>
  168. <style lang="scss" scoped>
  169. .tm-icons {
  170. vertical-align: middle;
  171. .icons {
  172. &.black {
  173. color: #fff;
  174. }
  175. }
  176. }
  177. </style>