我正在进行"状态更新"在我的实际组件中,我将第一个自定义复选框(顶部的圆圈等)标记为checked
...但是对于下面的CodePen,我只是将它们全部标记为{{ 1}}迭代我的问题。
" twitter"复选框无法检查和取消选中。 Facebook的人会。
我确定这与我在twitter复选框上启用/禁用字符计数器这一事实有关。如果你点击其中一个推特复选框,你会注意到字符计数器打开,但是从不检查复选框(或者更确切地说,检查然后立即取消选中)...
例如,在方法:checked='false'
中,如果我注释掉toggleMaxCharLength()
,则复选框可以正常工作。
如果我从输入self.enableMaxCharLength = true;
中移除:checked='false'
,则按原样运行...
更新 - 工作笔和解决方案: https://codepen.io/mikebarwick/pen/qXdqBO
答案 0 :(得分:3)
检查Twitter帐户会导致重新渲染,当然,这会将您的checked
值设置为false。
您需要记住选中的值。我做了一些小修改,但还有其他方法。
<input type="checkbox"
:ref="key"
:name="scheduleUsingBuffer ? 'buffer_profiles[]' : key + '[]'"
:value="scheduleUsingBuffer ? account.profile_id : account.page_id"
:checked="account.checked"
@change="handleAccountInputChange(key, account)">
并且
handleAccountInputChange(type, account) {
this.$set(account, 'checked', !account.checked)
if (type == 'twitter') {
this.toggleMaxCharLength();
}
},
另一种避免这种情况的方法是将复选框抽象为自己的组件,以便记住它们的状态,这样当父级重新渲染时,复选框的状态不会被覆盖。
此外,笔转换为SO片段。
var accounts = {
facebook: {
testing1: {
page_id: '23derf56hg',
img_url: null
}
},
twitter: {
testing2: {
page_id: 'fr2wlfrhoi',
img_url: null
},
testing3: {
page_id: '92frgl5639',
img_url: null
}
}
}
var app = new Vue({
el: '#app',
mounted(){
setTimeout(() => {
Object.keys(accounts).forEach((site, siteIndex) => {
Object.keys(accounts[site]).forEach((account, actIndex) =>{
accounts[site][account]["checked"] = (siteIndex === 0 && actIndex === 0)
})
})
console.log(accounts)
this.connectedAccounts = accounts
}, 100)
},
data: {
message: 'Hello Vue!',
connectedAccounts: [],
scheduleUsingBuffer: false,
formData: {},
enableMaxCharLength: false,
maxCharCount: 140,
remainingCharCount: 140,
isAboveMaxCharCount: false,
statusMessage: ''
},
methods: {
onSubmit(event) {
this.formData = serialize(event.target, { hash: true });
},
toggleMaxCharLength() {
this.enableMaxCharLength = false;
Vue.nextTick(() => {
var self = this;
this.$refs.twitter.forEach(twitterInput => {
if (twitterInput.checked) {
self.enableMaxCharLength = true;
}
});
});
},
handleAccountInputChange(type, account) {
this.$set(account, 'checked', !account.checked)
if (type == 'twitter') {
this.toggleMaxCharLength();
}
},
countdown() {
this.remainingCharCount = this.maxCharCount - this.statusMessage.length;
this.isAboveMaxCharCount = this.remainingCharCount < 0;
}
}
})
&#13;
section.create-story {
margin: 30px auto;
width: 425px;
}
section.create-story h4 {
margin-bottom: 15px;
letter-spacing: 0.1em;
text-transform: uppercase;
font-weight: normal;
font-size: 14px;
}
section.create-story .switch {
display: block;
margin-bottom: 20px;
}
section.create-story #connected-accounts {
margin-bottom: 15px;
}
section.create-story #connected-accounts label.account-checkbox {
position: relative;
display: inline-block;
margin: 0 5px 0px 0;
cursor: pointer;
}
section.create-story #connected-accounts label.account-checkbox .avatar {
position: relative;
width: 38px;
height: 38px;
border-radius: 50%;
background-size: cover !important;
background-position: center !important;
background-color: #CCC !important;
border: 2px solid #CCC;
transition: all 0.1s ease-in-out;
}
section.create-story #connected-accounts label.account-checkbox .avatar,
section.create-story #connected-accounts label.account-checkbox .account-icon {
filter: grayscale(100%);
opacity: 0.3;
}
section.create-story #connected-accounts label.account-checkbox .avatar:hover,
section.create-story #connected-accounts label.account-checkbox .account-icon:hover {
opacity: 1;
}
section.create-story #connected-accounts label.account-checkbox input[type="checkbox"] {
display: none;
}
section.create-story #connected-accounts label.account-checkbox input[type="checkbox"]:checked + .avatar {
border: 2px solid green;
}
section.create-story #connected-accounts label.account-checkbox input[type="checkbox"]:checked + .avatar + .account-icon {
color: green;
}
section.create-story #connected-accounts label.account-checkbox input[type="checkbox"]:checked + .avatar, section.create-story #connected-accounts label.account-checkbox input[type="checkbox"]:checked + .avatar + .account-icon {
filter: grayscale(0);
opacity: 1;
}
section.create-story #connected-accounts label.account-checkbox .account-icon {
position: absolute;
font-size: 13px;
width: 24px;
height: 24px;
line-height: 24px;
right: -4px;
bottom: -4px;
background: white;
color: #4d4d4d;
border-radius: 50%;
pointer-events: none;
box-shadow: 0 1px 0 0px rgba(49, 49, 93, 0.05), 0 2px 3px 0 rgba(49, 49, 93, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.1);
}
section.create-story #status {
margin-bottom: 20px;
padding: 15px;
border-radius: 5px;
border: 1px solid #4d4d4d;
}
section.create-story #status textarea {
display: block;
margin-bottom: 15px;
padding: 0;
font-style: italic;
font-size: 14px;
min-height: 60px;
border: none;
box-shadow: none;
}
section.create-story #status .remaining-chars.has-text-danger {
font-weight: bold;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
<section class="create-story box content">
<h4>New Story</h4>
<form id="new-story" v-on:submit.prevent="onSubmit">
<div id="status">
<div id="connected-accounts">
<span v-for="(accounts, key, index) in connectedAccounts">
<label v-for="(account, i) in accounts" class="account-checkbox">
<input type="checkbox"
:key="key"
:ref="key"
:name="scheduleUsingBuffer ? 'buffer_profiles[]' : key + '[]'"
:value="scheduleUsingBuffer ? account.profile_id : account.page_id"
:checked="account.checked"
@change="handleAccountInputChange(key, account)"> <!-- mark first account as "checked" :checked="index == 0 && i == 0" -->
<div
class="avatar"
:style="'background: url(' + account.img_url + ')'">
</div>
<i :class="'account-icon fa fa-' + key"></i>
</label>
</span>
</div>
<div class="control">
<textarea @keyup="countdown" v-model="statusMessage" name="status-message" class="textarea" placeholder="What story do you have to tell?"></textarea>
</div>
<div class="level">
<div class="level-right">
<div v-if="enableMaxCharLength" class="level-item">
<span :class="{'has-text-danger': isAboveMaxCharCount}" class="remaining-chars" v-text="remainingCharCount"></span>
</div>
<div class="level-item">
<input type="submit" value="Schedule" class="button is-primary">
</div>
</div>
</div>
</div>
</form>
</section>
</div>
&#13;