我对如何更改组件内的属性感到有点困惑,假设我有以下组件:
{
props: {
visible: {
type: Boolean,
default: true
}
},
methods: {
hide() {
this.visible = false;
}
}
}
虽然它有效但会发出以下警告:
避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖。而是根据prop的值使用数据或计算属性。支持变异:“可见” (在组件中找到)
现在我想知道处理这个问题的最佳方法是什么,显然在DOM中创建组件时会传入visible
属性:<Foo :visible="false"></Foo>
答案 0 :(得分:13)
不知何故,你应该决定一个地方居住,而不是两个。我不知道是否更适合在Alert
中或仅在其父项中使用它,但是你应该选择一个。
父级或任何兄弟组件是否依赖于状态?
在极少数情况下,您可能需要组合。也许你想让父母和孩子都有隐藏孩子的能力。那么你应该在父母和孩子都有状态(所以你不必在孩子里面编辑孩子的道具)。
例如,如果出现以下情况,则可以看到子项:visible && state_visible
,其中visible
来自道具并反映父项状态中的值,state_visible
来自孩子的状态。
我不确定这是否是你想要的行为,但是here is a fiddle。我会假设您实际上只想在单击子组件时调用父组件的toggleAlert
。
答案 1 :(得分:4)
在阅读了您的最新评论后,似乎您担心在父母上显示/隐藏警报的逻辑。因此,我建议如下:
<强>父强>
# template
<alert :alert-visible="alertVisible"></alert>
# script
data () {
alertVisible: false,
...
},
...
然后在儿童警报中,您将观察道具的价值并将所有逻辑移至警报中:
孩子(提醒)
# script
data: {
visible: false,
...
},
methods: {
hide () {
this.visible = false
},
show () {
this.visible = true
},
...
},
props: [
'alertVisible',
],
watch: {
alertVisible () {
if (this.alertVisible && !this.visible) this.show()
else if (!this.alertVisible && this.visible) this.hide()
},
...
},
...
答案 2 :(得分:3)
如果道具仅适用于此子组件,请为孩子提供prop
initialVisible
和data
mutableVisible
,并在created
钩子(组装组件的数据结构时调用),只需this.mutableVisible = this.initialVisible
。
如果道具由父组件的其他子项共享,则您需要将其设为父项data
,以使其可供所有子项使用。然后在孩子this.$emit('visibleChanged', currentVisible)
中通知家长更改visible
。在父模板中,使用<ThatChild ... :visibleChanged="setVisible" ...>
。请查看指南:http://vuejs.org/v2/guide/components.html
答案 3 :(得分:2)
为了帮助任何人,我遇到了同样的问题。我只是将我的var里面的v-model =“”从props数组改为数据。记住道具和数据之间的区别,我的情况不是改变它的问题,你应该重视你的决定。
E.g:
return EMPTY;
在:
<v-dialog v-model="dialog" fullscreen hide-overlay transition="dialog-bottom-transition">
后:
export default {
data: function () {
return {
any-vars: false
}
},
props: {
dialog: false,
notifications: false,
sound: false,
widgets: false
},
methods: {
open: function () {
var vm = this;
vm.dialog = true;
}
}
}
答案 4 :(得分:0)
也许它看起来像黑客并违反了单个数据源的概念,但它的工作) 此解决方案是创建本地代理变量并从props继承数据。接下来使用代理变量。
Vue.component("vote", {
data: function() {
return {
like_: this.like,
dislike_: this.dislike,
}
},
props: {
like: {
type: [String, Number],
default: 0
},
dislike: {
type: [String, Number],
default: 0
},
item: {
type: Object
}
},
template: '<div class="tm-voteing"><span class="tm-vote tm-vote-like" @click="onVote(item, \'like\')"><span class="fa tm-icon"></span><span class="tm-vote-count">{{like_}}</span></span><span class="tm-vote tm-vote-dislike" @click="onVote(item, \'dislike\')"><span class="fa tm-icon"></span><span class="tm-vote-count">{{dislike_}}</span></span></div>',
methods: {
onVote: function(data, action) {
var $this = this;
// instead of jquery ajax can be axios or vue-resource
$.ajax({
method: "POST",
url: "/api/vote/vote",
data: {id: data.id, action: action},
success: function(response) {
if(response.status === "insert") {
$this[action + "_"] = Number($this[action + "_"]) + 1;
} else {
$this[action + "_"] = Number($this[action + "_"]) - 1;
}
},
error: function(response) {
console.error(response);
}
});
}
}
});
使用组件并传递道具
<vote :like="item.vote_like" :dislike="item.vote_dislike" :item="item"></vote>
答案 5 :(得分:0)
当父属性更新时,它将向下传递给子节点,但不会反过来。那么,当事情发生时,我们如何与父母沟通?这就是Vue的自定义事件系统的用武之地。
使用来自孩子的$emit('my-event)
将事件发送给父母。通过v-on:my-event
(或@my-event
)在父级内的子声明中接收事件。
工作示例:
// child
Vue.component('child', {
template: '<div><p>Child</p> <button @click="hide">Hide</button></div>',
methods: {
hide () {
this.$emit('child-hide-event')
}
},
})
// parent
new Vue({
el: '#app',
data: {
childVisible: true
},
methods: {
childHide () {
this.childVisible = false
},
childShow () {
this.childVisible = true
}
}
})
&#13;
.box {
border: solid 1px grey;
padding: 16px;
}
&#13;
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app" class="box">
<p>Parent | childVisible: {{ childVisible }}</p>
<button @click="childHide">Hide</button>
<button @click="childShow">Show</button>
<p> </p>
<child @child-hide-event="childHide" v-if="childVisible" class="box"></child>
</div>
&#13;
答案 6 :(得分:0)
我想知道为什么警告提示时其他人会错过它
避免直接更改prop,因为每当父组件重新渲染时,该值就会被覆盖。而是根据道具的值使用数据或计算属性。道具被突变:“可见”(位于组件中)
尝试从子组件中接收的prop中创建计算属性
computed: {
isVisible => this.visible
}
并使用在您的子组件中计算出的值,并将更改发送给您的父组件。