tm-icons.vue 4.4 KB

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