提交 a3c05355 编写于 作者: H hubvue 提交者: kimwangchong_i

fix(radio): default slot child v-model not render correct contents

上级 94b0df29
......@@ -3127,7 +3127,8 @@
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz",
"integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==",
"dev": true
"dev": true,
"optional": true
},
"cssstyle": {
"version": "0.2.37",
......@@ -5120,7 +5121,8 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
......@@ -5144,13 +5146,15 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
......@@ -5167,19 +5171,22 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
......@@ -5310,7 +5317,8 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
......@@ -5324,6 +5332,7 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
......@@ -5340,6 +5349,7 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
......@@ -5348,13 +5358,15 @@
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
......@@ -5375,6 +5387,7 @@
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
......@@ -5463,7 +5476,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
......@@ -5477,6 +5491,7 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
......@@ -5572,7 +5587,8 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
......@@ -5614,6 +5630,7 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
......@@ -5635,6 +5652,7 @@
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
......@@ -5683,13 +5701,15 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
"dev": true
"dev": true,
"optional": true
}
}
},
......
<template>
<div class="cube-radio" :class="_containerClass" :data-pos="position">
<label class="cube-radio-wrap" :class="_wrapClass">
<input class="cube-radio-input" type="radio" :disabled="option.disabled" v-model="radioValue" :value="computedOption.value">
<input
class="cube-radio-input"
type="radio"
:disabled="option.disabled"
v-model="radioValue"
:value="computedOption.value"
/>
<span class="cube-radio-ui cubeic-round-border">
<i></i>
</span>
<slot>
<span class="cube-radio-label">{{computedOption.label}}</span>
<span class="cube-radio-label">{{ computedOption.label }}</span>
</slot>
</label>
</div>
......@@ -45,13 +51,16 @@ export default {
},
created() {
const radioGroup = this.radioGroup
if (radioGroup) {
if (radioGroup && radioGroup.radioValue !== void 0) {
this.radioValue = radioGroup.radioValue
this._cancelWatchGroup = this.$watch(() => {
return radioGroup.radioValue
}, (newValue) => {
this.radioValue = newValue
})
this._cancelWatchGroup = this.$watch(
() => {
return radioGroup.radioValue
},
newValue => {
this.radioValue = newValue
}
)
}
},
beforeDestroy() {
......@@ -102,113 +111,173 @@ export default {
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@require "../../common/stylus/variable.styl"
@require "../../common/stylus/mixin.styl"
$ui-width = 1.42em
.cube-radio
position: relative
padding: 0 16px
text-align: left
font-size: 100%
color: $radio-color
&[data-pos="right"]
.cube-radio-ui
margin-right: 0
position: absolute
right: 0
.cube-radio-label
margin-right: $ui-width
.cube-radio-wrap
position: relative
display: flex
align-items: center
box-sizing: border-box
width: 100%
height: 100%
padding: 11px 0
line-height: 1.5
word-break: break-word
word-wrap: break-word
.cube-radio-input
z-index: 1
position: absolute
top: 0
left: 0
width: 100%
height: 100%
opacity: 0
.cube-radio-ui
position: relative
width: 1em
height: 1em
margin-right: $ui-width - 1em
line-height: 1
color: transparent
background-color: transparent
border-radius: 50%
&::before, i
transition: all .2s
&::before
color: $radio-icon-color
display: inline-block
transform: scale(1.24)
i
position: absolute
top: 0
left: 0
overflow: hidden
width: 100%
height: 100%
border-radius: 50%
transform: scale(.4)
&::before
content: ""
position: absolute
top: 50%
left: 50%
width: 50%
height: 50%
transform: translate(-50%, -50%) scale(.8)
// background-color: transparent
border-radius: 50%
.cube-radio_selected
.cube-radio-ui
background-color: $radio-selected-icon-bgc
&::before
color: transparent
i
transform: scale(1)
// color: $radio-selected-icon-color
&::before
background-color: $radio-selected-icon-color
.cube-radio_disabled
.cube-radio-ui
background-color: $radio-disabled-icon-bgc
&::before, i
transition: none
&::before
color: transparent
.cube-radio-hollow
&.cube-radio_selected, &.cube-radio_disabled
.cube-radio-ui
background-color: transparent
i::before
transform: translate(-50%, -50%) scale(1)
&.cube-radio_selected
.cube-radio-ui
&::before
color: $radio-hollow-selected-icon-color
i
&::before
background-color: $radio-hollow-selected-icon-color
&.cube-radio_disabled
.cube-radio-ui
&::before
color: $radio-hollow-disabled-icon-color
&.cube-radio_selected
.cube-radio-ui
i
&::before
background-color: $radio-hollow-disabled-icon-color
@require '../../common/stylus/variable.styl';
@require '../../common/stylus/mixin.styl';
$ui-width = 1.42em;
.cube-radio {
position: relative;
padding: 0 16px;
text-align: left;
font-size: 100%;
color: $radio-color;
&[data-pos='right'] {
.cube-radio-ui {
margin-right: 0;
position: absolute;
right: 0;
}
.cube-radio-label {
margin-right: $ui-width;
}
}
}
.cube-radio-wrap {
position: relative;
display: flex;
align-items: center;
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 11px 0;
line-height: 1.5;
word-break: break-word;
word-wrap: break-word;
}
.cube-radio-input {
z-index: 1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.cube-radio-ui {
position: relative;
width: 1em;
height: 1em;
margin-right: $ui-width - 1em;
line-height: 1;
color: transparent;
background-color: transparent;
border-radius: 50%;
&::before, i {
transition: all 0.2s;
}
&::before {
color: $radio-icon-color;
display: inline-block;
transform: scale(1.24);
}
i {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
width: 100%;
height: 100%;
border-radius: 50%;
transform: scale(0.4);
&::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%) scale(0.8);
// background-color: transparent
border-radius: 50%;
}
}
}
.cube-radio_selected {
.cube-radio-ui {
background-color: $radio-selected-icon-bgc;
&::before {
color: transparent;
}
i {
transform: scale(1);
// color: $radio-selected-icon-color
&::before {
background-color: $radio-selected-icon-color;
}
}
}
}
.cube-radio_disabled {
.cube-radio-ui {
background-color: $radio-disabled-icon-bgc;
&::before, i {
transition: none;
}
&::before {
color: transparent;
}
}
}
.cube-radio-hollow {
&.cube-radio_selected, &.cube-radio_disabled {
.cube-radio-ui {
background-color: transparent;
i::before {
transform: translate(-50%, -50%) scale(1);
}
}
}
&.cube-radio_selected {
.cube-radio-ui {
&::before {
color: $radio-hollow-selected-icon-color;
}
i {
&::before {
background-color: $radio-hollow-selected-icon-color;
}
}
}
}
&.cube-radio_disabled {
.cube-radio-ui {
&::before {
color: $radio-hollow-disabled-icon-color;
}
}
&.cube-radio_selected {
.cube-radio-ui {
i {
&::before {
background-color: $radio-hollow-disabled-icon-color;
}
}
}
}
}
}
</style>
......@@ -12,74 +12,75 @@ describe('Radio.vue', () => {
})
it('use', () => {
Vue.use(RadioGroup)
expect(Vue.component(RadioGroup.name))
.to.be.a('function')
expect(Vue.component(RadioGroup.name)).to.be.a('function')
})
it('should render correct contents', () => {
vm = createRadioGroup()
const el = vm.$el
expect(el.className)
.to.equal('cube-radio-group my-radio border-top-1px border-bottom-1px')
expect(el.className).to.equal(
'cube-radio-group my-radio border-top-1px border-bottom-1px'
)
const options = el.querySelectorAll('.cube-radio')
expect(options.length)
.to.equal(3)
expect(options[0].getAttribute('data-pos'))
.to.equal('right')
expect(options[0].querySelector('.cube-radio-wrap').className)
.to.equal('cube-radio-wrap border-bottom-1px')
expect(options[0].querySelector('.cube-radio-input').value)
.to.equal('1')
expect(options[0].querySelector('.cube-radio-label').textContent.trim())
.to.equal('Option1')
expect(options.length).to.equal(3)
expect(options[0].getAttribute('data-pos')).to.equal('right')
expect(options[0].querySelector('.cube-radio-wrap').className).to.equal(
'cube-radio-wrap border-bottom-1px'
)
expect(options[0].querySelector('.cube-radio-input').value).to.equal('1')
expect(
options[0].querySelector('.cube-radio-label').textContent.trim()
).to.equal('Option1')
expect(options[1].querySelector('.cube-radio-wrap').className)
.to.equal('cube-radio-wrap border-bottom-1px')
expect(options[1].querySelector('.cube-radio-input').value)
.to.equal('Option2')
expect(options[1].querySelector('.cube-radio-label').textContent.trim())
.to.equal('Option2')
expect(options[1].querySelector('.cube-radio-wrap').className).to.equal(
'cube-radio-wrap border-bottom-1px'
)
expect(options[1].querySelector('.cube-radio-input').value).to.equal(
'Option2'
)
expect(
options[1].querySelector('.cube-radio-label').textContent.trim()
).to.equal('Option2')
expect(options[2].className)
.to.include('cube-radio_selected cube-radio_disabled')
expect(options[2].querySelector('.cube-radio-wrap').className)
.to.equal('cube-radio-wrap border-bottom-1px')
expect(options[2].querySelector('.cube-radio-input').value)
.to.equal('3')
expect(options[2].querySelector('.cube-radio-label').textContent.trim())
.to.equal('Option3')
expect(options[2].className).to.include(
'cube-radio_selected cube-radio_disabled'
)
expect(options[2].querySelector('.cube-radio-wrap').className).to.equal(
'cube-radio-wrap border-bottom-1px'
)
expect(options[2].querySelector('.cube-radio-input').value).to.equal('3')
expect(
options[2].querySelector('.cube-radio-label').textContent.trim()
).to.equal('Option3')
})
it('should render correct contents - horizontal', () => {
vm = createRadioGroup(true)
const el = vm.$el
expect(el.className)
.to.equal('cube-radio-group my-radio')
expect(el.getAttribute('data-horz'))
.to.equal('true')
expect(el.className).to.equal('cube-radio-group my-radio')
expect(el.getAttribute('data-horz')).to.equal('true')
const options = el.querySelectorAll('.cube-radio')
expect(options.length)
.to.equal(3)
expect(options.length).to.equal(3)
expect(options[0].className)
.to.equal('cube-radio border-right-1px')
expect(options[0].querySelector('.cube-radio-wrap').className)
.to.equal('cube-radio-wrap')
expect(options[2].className)
.to.include('cube-radio_selected cube-radio_disabled')
expect(options[2].querySelector('.cube-radio-wrap').className)
.to.equal('cube-radio-wrap')
expect(options[0].className).to.equal('cube-radio border-right-1px')
expect(options[0].querySelector('.cube-radio-wrap').className).to.equal(
'cube-radio-wrap'
)
expect(options[2].className).to.include(
'cube-radio_selected cube-radio_disabled'
)
expect(options[2].querySelector('.cube-radio-wrap').className).to.equal(
'cube-radio-wrap'
)
})
it('should toggle v-model value', (done) => {
it('should toggle v-model value', done => {
vm = createRadioGroup()
expect(vm.$parent.selected)
.to.equal('3')
expect(vm.$parent.selected).to.equal('3')
vm.$el.querySelector('.cube-radio-input').click()
setTimeout(() => {
expect(vm.$parent.selected)
.to.equal('1')
expect(vm.$parent.selected).to.equal('1')
done()
})
})
it('v-model should be a number value', (done) => {
it('v-model should be a number value', done => {
vm = createVue({
template: `
<cube-radio-group v-model="selected" :options="options"></cube-radio-group>
......@@ -109,14 +110,24 @@ describe('Radio.vue', () => {
})
vm.$el.querySelector('.cube-radio-input').click()
setTimeout(() => {
expect(vm.$parent.selected)
.to.equal(0)
expect(vm.$parent.selected).to.equal(0)
done()
})
})
it('default slot mode should render correct default value', done => {
let vModelGroupVM = createUserDefaltSlotRadioGroup()
expect(vModelGroupVM.$parent.selected).to.equal('3')
let froupOptions = vModelGroupVM.$el.querySelectorAll('.cube-radio')
expect(froupOptions[2].className).to.include('cube-radio_selected')
let vModelChildVM = createUserDefaltSlotRadioGroup(false)
expect(vModelChildVM.$parent.selected).to.equal('3')
let childOptions = vModelChildVM.$el.querySelectorAll('.cube-radio')
expect(childOptions[2].className).to.include('cube-radio_selected')
done()
})
})
function createRadioGroup (horizontal = false) {
function createRadioGroup(horizontal = false) {
const vm = createVue({
template: `
<cube-radio-group v-model="selected" :options="options" class="my-radio" position="right" :horizontal="${horizontal}"></cube-radio-group>
......@@ -139,3 +150,38 @@ function createRadioGroup (horizontal = false) {
})
return vm
}
function createUserDefaltSlotRadioGroup(vModelGroup = true) {
const vm = createVue({
template: `
<cube-radio-group ${
vModelGroup ? `v-model="selected"` : ''
} :options="options" class="my-radio" position="right" :horizontal="true">
<cube-radio
v-for="(option, idx) in options"
:key="idx"
:option="option"
:horizontal="true"
position="right"
${vModelGroup ? '' : `v-model="selected"`}
>
{{option.label}}
</cube-radio>
</cube-radio-group>
`,
data: {
selected: '3',
options: [
{
label: 'Option1',
value: '1'
},
'Option2',
{
label: 'Option3',
value: '3'
}
]
}
})
return vm
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册