@netang/quasar 0.0.77 → 0.0.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/field-text/index.vue +2 -10
- package/components/img/index.vue +179 -0
- package/components/thumbnail/index.vue +25 -75
- package/package.json +1 -1
- package/sass/common.scss +10 -0
- package/utils/getImage.js +65 -65
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
<script>
|
|
74
74
|
import { computed } from 'vue'
|
|
75
75
|
|
|
76
|
-
import $
|
|
76
|
+
import $n_omit from 'lodash/omit'
|
|
77
77
|
|
|
78
78
|
import $n_copy from '../../utils/copy'
|
|
79
79
|
|
|
@@ -133,15 +133,7 @@ export default {
|
|
|
133
133
|
* 插槽标识数组
|
|
134
134
|
*/
|
|
135
135
|
const slotNames = computed(function() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
$n_forIn(slots, function(val, key) {
|
|
139
|
-
if (key !== 'default') {
|
|
140
|
-
lists.push(key)
|
|
141
|
-
}
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
return lists
|
|
136
|
+
return $n_isValidObject(slots) ? Object.keys($n_omit(slots, [ 'default' ])) : []
|
|
145
137
|
})
|
|
146
138
|
|
|
147
139
|
// ==========【方法】=============================================================================================
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<q-img
|
|
3
|
+
:src="currentSrc"
|
|
4
|
+
:width="imageProps.width"
|
|
5
|
+
:height="imageProps.height"
|
|
6
|
+
:spinner-size="imageProps.spinnerSize"
|
|
7
|
+
v-bind="$attrs"
|
|
8
|
+
v-if="currentSrc"
|
|
9
|
+
>
|
|
10
|
+
<!-- 错误插槽 -->
|
|
11
|
+
<template v-slot:error>
|
|
12
|
+
<slot name="error">
|
|
13
|
+
<div class="absolute-full flex flex-center bg-grey-5 text-white no-padding">
|
|
14
|
+
<q-icon
|
|
15
|
+
:size="errorIconSize"
|
|
16
|
+
:name="errorIcon"
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
</slot>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<!-- 默认插槽 -->
|
|
23
|
+
<slot />
|
|
24
|
+
|
|
25
|
+
<!-- 预览点击 -->
|
|
26
|
+
<div
|
|
27
|
+
class="absolute-full transparent cursor-pointer"
|
|
28
|
+
@click.prevent.stop="onPreview"
|
|
29
|
+
@dblclick.prevent.stop="onNoop"
|
|
30
|
+
v-if="preview"
|
|
31
|
+
></div>
|
|
32
|
+
</q-img>
|
|
33
|
+
|
|
34
|
+
<!-- 如果没有图片 -->
|
|
35
|
+
<div
|
|
36
|
+
class="q-img"
|
|
37
|
+
v-bind="imageProps"
|
|
38
|
+
v-else
|
|
39
|
+
>
|
|
40
|
+
<div class="q-img__content absolute-full q-anchor--skip">
|
|
41
|
+
<slot name="error">
|
|
42
|
+
<div class="absolute-full flex flex-center bg-grey-5 text-white no-padding">
|
|
43
|
+
<q-icon
|
|
44
|
+
:size="errorIconSize"
|
|
45
|
+
:name="errorIcon"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
</slot>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
import { computed } from 'vue'
|
|
55
|
+
|
|
56
|
+
import $n_get from 'lodash/get'
|
|
57
|
+
import $n_px from '@netang/utils/px'
|
|
58
|
+
|
|
59
|
+
import $n_getImage from '../../utils/getImage'
|
|
60
|
+
import $n_previewImage from '../../utils/previewImage'
|
|
61
|
+
|
|
62
|
+
export default {
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 标识
|
|
66
|
+
*/
|
|
67
|
+
name: 'NImg',
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 关闭组件 attribute 透传行为
|
|
71
|
+
*/
|
|
72
|
+
inheritAttrs: false,
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 声明属性
|
|
76
|
+
*/
|
|
77
|
+
props: {
|
|
78
|
+
// 图片地址
|
|
79
|
+
src: [ String, Array, Object ],
|
|
80
|
+
// 宽
|
|
81
|
+
width: [ String, Number ],
|
|
82
|
+
// 高
|
|
83
|
+
height: [ String, Number ],
|
|
84
|
+
// 加载旋转器尺寸
|
|
85
|
+
spinnerSize: [ String, Number ],
|
|
86
|
+
// 错误尺寸
|
|
87
|
+
errorSize: {
|
|
88
|
+
type: [ String, Number ],
|
|
89
|
+
default: 70,
|
|
90
|
+
},
|
|
91
|
+
// 错误图标大小
|
|
92
|
+
errorIconSize: {
|
|
93
|
+
type: String,
|
|
94
|
+
default: 'sm',
|
|
95
|
+
},
|
|
96
|
+
// 错误图标
|
|
97
|
+
errorIcon: {
|
|
98
|
+
type: String,
|
|
99
|
+
default: 'image',
|
|
100
|
+
},
|
|
101
|
+
// 是否点击放大预览
|
|
102
|
+
preview: Boolean,
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 组合式
|
|
107
|
+
*/
|
|
108
|
+
setup(props, { attrs }) {
|
|
109
|
+
|
|
110
|
+
// ==========【计算属性】==========================================================================================
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 当前图片地址
|
|
114
|
+
*/
|
|
115
|
+
const currentSrc = computed(function () {
|
|
116
|
+
const res = $n_getImage(props.src, { w: props.width, zoom: true })
|
|
117
|
+
if (res) {
|
|
118
|
+
return res
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 图片声明属性
|
|
124
|
+
*/
|
|
125
|
+
const imageProps = computed(function () {
|
|
126
|
+
|
|
127
|
+
let width = props.width ? $n_px(props.width) : undefined
|
|
128
|
+
let height = props.height ? $n_px(props.height) : undefined
|
|
129
|
+
|
|
130
|
+
// 如果有当前值
|
|
131
|
+
if (currentSrc.value) {
|
|
132
|
+
return {
|
|
133
|
+
width,
|
|
134
|
+
height,
|
|
135
|
+
spinnerSize: props.spinnerSize ? $n_px(props.spinnerSize) : undefined,
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 如果没有宽 || 没有高
|
|
140
|
+
if (! width || ! height) {
|
|
141
|
+
width = $n_px(props.errorSize)
|
|
142
|
+
height = width
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
class: $n_get(attrs, 'class'),
|
|
147
|
+
style: [
|
|
148
|
+
{
|
|
149
|
+
width,
|
|
150
|
+
height,
|
|
151
|
+
},
|
|
152
|
+
$n_get(attrs, 'style'),
|
|
153
|
+
],
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
// ==========【方法】=============================================================================================
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 预览
|
|
161
|
+
*/
|
|
162
|
+
function onPreview() {
|
|
163
|
+
// 预览图片
|
|
164
|
+
$n_previewImage(props.src)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
// 当前图片地址
|
|
169
|
+
currentSrc,
|
|
170
|
+
// 图片声明属性
|
|
171
|
+
imageProps,
|
|
172
|
+
// 预览
|
|
173
|
+
onPreview,
|
|
174
|
+
// 点击空方法
|
|
175
|
+
onNoop() {},
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
</script>
|
|
@@ -1,41 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
:
|
|
4
|
-
:
|
|
5
|
-
:
|
|
6
|
-
:height="toPx(size)"
|
|
7
|
-
fit="fill"
|
|
2
|
+
<g-img
|
|
3
|
+
:spinner-size="size / 2"
|
|
4
|
+
:width="size"
|
|
5
|
+
:height="size"
|
|
8
6
|
v-bind="$attrs"
|
|
9
|
-
v-if="currentSrc"
|
|
10
7
|
>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
<!-- 插槽 -->
|
|
9
|
+
<template
|
|
10
|
+
v-for="slotName in slotNames"
|
|
11
|
+
v-slot:[slotName]
|
|
12
|
+
>
|
|
13
|
+
<slot
|
|
14
|
+
:name="slotName"
|
|
15
|
+
/>
|
|
18
16
|
</template>
|
|
19
|
-
|
|
20
|
-
<!-- 预览点击 -->
|
|
21
|
-
<div
|
|
22
|
-
class="absolute-full transparent cursor-pointer"
|
|
23
|
-
@click.prevent.stop="onPreview"
|
|
24
|
-
@dblclick.prevent.stop="onNoop"
|
|
25
|
-
v-if="preview"
|
|
26
|
-
></div>
|
|
27
|
-
</q-img>
|
|
17
|
+
</g-img>
|
|
28
18
|
</template>
|
|
29
19
|
|
|
30
20
|
<script>
|
|
31
21
|
import { computed } from 'vue'
|
|
32
|
-
import { useQuasar } from 'quasar'
|
|
33
22
|
|
|
34
|
-
import $
|
|
35
|
-
import $n_noop from '@netang/utils/noop'
|
|
23
|
+
import $n_isValidObject from '@netang/utils/isValidObject'
|
|
36
24
|
|
|
37
|
-
import
|
|
38
|
-
import $n_previewImage from '../../utils/previewImage'
|
|
25
|
+
import GImg from '../img'
|
|
39
26
|
|
|
40
27
|
export default {
|
|
41
28
|
|
|
@@ -45,77 +32,40 @@ export default {
|
|
|
45
32
|
name: 'NThumbnail',
|
|
46
33
|
|
|
47
34
|
/**
|
|
48
|
-
*
|
|
35
|
+
* 组件
|
|
49
36
|
*/
|
|
50
|
-
|
|
37
|
+
components: {
|
|
38
|
+
GImg,
|
|
39
|
+
},
|
|
51
40
|
|
|
52
41
|
/**
|
|
53
42
|
* 声明属性
|
|
54
43
|
*/
|
|
55
44
|
props: {
|
|
56
|
-
// 图片地址
|
|
57
|
-
src: [String, Array, Object],
|
|
58
45
|
// 图片尺寸
|
|
59
46
|
size: {
|
|
60
47
|
type: Number,
|
|
61
48
|
default: 40,
|
|
62
49
|
},
|
|
63
|
-
// 错误图标大小
|
|
64
|
-
errorIconSize: {
|
|
65
|
-
type: String,
|
|
66
|
-
default: 'sm',
|
|
67
|
-
},
|
|
68
|
-
// 错误图标
|
|
69
|
-
errorIcon: {
|
|
70
|
-
type: String,
|
|
71
|
-
default: 'image',
|
|
72
|
-
},
|
|
73
|
-
// 是否点击放大预览
|
|
74
|
-
preview: Boolean,
|
|
75
50
|
},
|
|
76
51
|
|
|
77
52
|
/**
|
|
78
53
|
* 组合式
|
|
79
54
|
*/
|
|
80
|
-
setup(props) {
|
|
81
|
-
|
|
82
|
-
// ==========【数据】============================================================================================
|
|
83
|
-
|
|
84
|
-
// quasar 对象
|
|
85
|
-
const $q = useQuasar()
|
|
55
|
+
setup(props, { slots }) {
|
|
86
56
|
|
|
87
57
|
// ==========【计算属性】==========================================================================================
|
|
88
58
|
|
|
89
59
|
/**
|
|
90
|
-
*
|
|
60
|
+
* 插槽标识
|
|
91
61
|
*/
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
if (res) {
|
|
95
|
-
return res
|
|
96
|
-
}
|
|
97
|
-
return 'error'
|
|
62
|
+
const slotNames = computed(function() {
|
|
63
|
+
return $n_isValidObject(slots) ? Object.keys(slots) : []
|
|
98
64
|
})
|
|
99
65
|
|
|
100
|
-
// ==========【方法】=============================================================================================
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* 预览
|
|
104
|
-
*/
|
|
105
|
-
function onPreview() {
|
|
106
|
-
// 预览图片
|
|
107
|
-
$n_previewImage(props.src)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
66
|
return {
|
|
111
|
-
//
|
|
112
|
-
|
|
113
|
-
// 预览
|
|
114
|
-
onPreview,
|
|
115
|
-
// 转像素
|
|
116
|
-
toPx: $n_px,
|
|
117
|
-
// 点击空方法
|
|
118
|
-
onNoop: $n_noop,
|
|
67
|
+
// 插槽标识
|
|
68
|
+
slotNames,
|
|
119
69
|
}
|
|
120
70
|
}
|
|
121
71
|
}
|
package/package.json
CHANGED
package/sass/common.scss
CHANGED
|
@@ -39,6 +39,16 @@ body {
|
|
|
39
39
|
--n-bg-grey-10: rgba(var(--n-reverse-color-rgb), 0.86);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// 自动显示横向滚动条
|
|
43
|
+
.n-overflow-auto-x {
|
|
44
|
+
overflow-x: auto;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 自动显示竖向滚动条
|
|
48
|
+
.n-overflow-auto-y {
|
|
49
|
+
overflow-y: auto;
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
// 字体大小 12 像素
|
|
43
53
|
.n-font-size-12 {
|
|
44
54
|
font-size: 12px;
|
package/utils/getImage.js
CHANGED
|
@@ -42,20 +42,22 @@ export default function getImage(src, params) {
|
|
|
42
42
|
// 如果为对象定义的规格
|
|
43
43
|
if ($n_isValidObject(params)) {
|
|
44
44
|
|
|
45
|
-
//
|
|
46
|
-
// 如果没有定义 w
|
|
45
|
+
// 是否自动缩放
|
|
47
46
|
// --------------------------------------------------
|
|
48
|
-
|
|
47
|
+
// 如果有定义 w
|
|
48
|
+
if ($n_has(params, 'w')) {
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
let {
|
|
51
|
+
w,
|
|
52
|
+
maxWidth,
|
|
52
53
|
zoom,
|
|
53
54
|
} = params
|
|
54
55
|
|
|
55
|
-
//
|
|
56
|
-
|
|
56
|
+
// 先设为 0
|
|
57
|
+
params.w = 0
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
// 如果开启缩放 && 有宽度
|
|
60
|
+
if (zoom && w) {
|
|
59
61
|
|
|
60
62
|
if (! $n_isNumeric(w) && $n_isString(w)) {
|
|
61
63
|
w = w.replace('px', '')
|
|
@@ -74,77 +76,75 @@ export default function getImage(src, params) {
|
|
|
74
76
|
/* #endif */
|
|
75
77
|
|
|
76
78
|
if (w > 10) {
|
|
77
|
-
w =
|
|
79
|
+
w = Math.floor(w / 10) * 10
|
|
78
80
|
} else {
|
|
79
|
-
w =
|
|
81
|
+
w = Math.floor(w)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 如果有最大宽度
|
|
85
|
+
if (maxWidth && maxWidth > w) {
|
|
86
|
+
w = maxWidth
|
|
80
87
|
}
|
|
81
|
-
|
|
88
|
+
|
|
89
|
+
params.w = w
|
|
82
90
|
}
|
|
83
91
|
}
|
|
84
92
|
}
|
|
85
93
|
}
|
|
86
94
|
// --------------------------------------------------
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const {
|
|
91
|
-
type,
|
|
92
|
-
domain,
|
|
93
|
-
} = $n_config('uploader.upload')
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
const {
|
|
97
|
+
type,
|
|
98
|
+
domain,
|
|
99
|
+
} = $n_config('uploader.upload')
|
|
100
|
+
|
|
101
|
+
// 判断图片上传方式
|
|
102
|
+
switch (type) {
|
|
103
|
+
|
|
104
|
+
// 七牛云
|
|
105
|
+
case 'qiniu':
|
|
106
|
+
|
|
107
|
+
const {
|
|
108
|
+
w,
|
|
109
|
+
h,
|
|
110
|
+
q,
|
|
111
|
+
format,
|
|
112
|
+
} = Object.assign({
|
|
113
|
+
// 宽
|
|
114
|
+
w: 0,
|
|
115
|
+
// 高
|
|
116
|
+
h: 0,
|
|
117
|
+
// 质量
|
|
118
|
+
q: 75,
|
|
119
|
+
// 格式
|
|
120
|
+
format: 'webp',
|
|
121
|
+
}, params)
|
|
122
|
+
|
|
123
|
+
// 裁剪图片方式
|
|
124
|
+
src += '?imageView2/2'
|
|
96
125
|
|
|
97
|
-
// 七牛云
|
|
98
|
-
case 'qiniu':
|
|
99
|
-
|
|
100
|
-
const {
|
|
101
|
-
w,
|
|
102
|
-
h,
|
|
103
|
-
q,
|
|
104
|
-
// local,
|
|
105
|
-
format,
|
|
106
|
-
} = Object.assign({
|
|
107
|
-
// 宽
|
|
108
|
-
w: 0,
|
|
109
|
-
// 高
|
|
110
|
-
h: 0,
|
|
111
126
|
// 质量
|
|
112
|
-
q
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// 格式
|
|
116
|
-
format: 'webp',
|
|
117
|
-
}, params)
|
|
118
|
-
|
|
119
|
-
// 如果是本地路径
|
|
120
|
-
// if (local) {
|
|
121
|
-
// return src
|
|
122
|
-
// }
|
|
123
|
-
|
|
124
|
-
// 裁剪图片方式
|
|
125
|
-
src += '?imageView2/2'
|
|
126
|
-
|
|
127
|
-
// 质量
|
|
128
|
-
if (q) {
|
|
129
|
-
src += '/q/' + q
|
|
130
|
-
}
|
|
127
|
+
if (q) {
|
|
128
|
+
src += '/q/' + q
|
|
129
|
+
}
|
|
131
130
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
// 宽
|
|
132
|
+
if (w) {
|
|
133
|
+
src += '/w/' + w
|
|
134
|
+
}
|
|
136
135
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
// 高
|
|
137
|
+
if (h) {
|
|
138
|
+
src += '/h/' + h
|
|
139
|
+
}
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
// 格式
|
|
142
|
+
if (format) {
|
|
143
|
+
src += '/format/' + format
|
|
144
|
+
}
|
|
146
145
|
|
|
147
|
-
|
|
146
|
+
return $n_slash(domain, 'end', true) + src
|
|
147
|
+
}
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
}
|