gpt4 book ai didi

javascript - 重构vue单文件组件

转载 作者:行者123 更新时间:2023-11-30 14:24:46 24 4
gpt4 key购买 nike

随着我的单个文件组件越来越大,我尝试对其进行一些重构。结果我有几个对话框使 .vue 文件变得很大(800 行以上)。所以为了保持组件干净,我试图将对话框变成专用的子组件(mydialog)。我正在使用 vuetify(不需要熟悉 vuetify)。

我在父组件中有一个启用对话框的按钮。我将 dialog 属性发送到子组件,然后子组件附加到对话框的 v-model。问题是,它只在第一次有效。那是因为当我点击 close 按钮时,它会将 dialog 的值更改为 false 并且它仍然是 false 永远,因为子组件与父组件失去了联系。在这种情况下,我该如何解决?

这是片段:

Vue.component('mydialog', {
props:{
dialog: {
type: Boolean,
default: false
}
},

template: `
<div class="text-xs-center">
<v-dialog
v-model="dialog"
width="500"
>

<v-card>
<v-card-title
class="headline grey lighten-2"
primary-title
>
A Dialog
</v-card-title>

<v-card-text>
Lorem ipsum dolor sit amet,
</v-card-text>

<v-divider></v-divider>

<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="primary"
flat
@click="dialog = false"
>
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
`,
data: function() {
return {
// dialog: false,
}
}

});

new Vue({
el: '#app',
data: {
dialog: false
}

});
<!doctype html>
<html>

<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.css" />
</head>

<body>
<div id="app">
<v-app id="inspire">
<v-btn color="red lighten-2" dark @click="dialog=true">Click Me</v-btn>
<mydialog :dialog="dialog"></mydialog>
</v-app>

</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>
</body>

</html>

最佳答案

您的组件通信有点不正常:基本上您的对话框没有通知应用程序组件它已关闭。以下两个更改启用了模态和应用程序之间的上游通信:

app 模板中:

  <mydialog :dialog.sync="dialog"></mydialog>

mydialog Controller 中:

data: function() {
return {
dialog$: false,
};
},
methods: {
onClose() {
this.dialog$ = false;
this.$emit('update:dialog', this.dialog$);
},
},
watch: {
dialog: {
immediate: true,
handler() {
this.dialog$ = this.dialog;
},
},
}

第一个更改是让 app 组件监听 mydialogdialog 属性的更新。

mydialog 中,我添加了一个数据属性 dialog$,它反射(reflect)了 dialog Prop (因为 Prop 被认为是常量,不应更改) .观察者负责 dialog 上的下游更新更新 dialog$onClose 方法会在对话框关闭时更新 dialog$ 并向订阅者(特别是 app)发送更新。

Vue.component('mydialog', {
props:{
dialog: {
type: Boolean,
default: false
}
},

template: `
<div class="text-xs-center">
<v-dialog
v-model="dialog$"
width="500"
>

<v-card>
<v-card-title
class="headline grey lighten-2"
primary-title
>
A Dialog
</v-card-title>

<v-card-text>
Lorem ipsum dolor sit amet,
</v-card-text>

<v-divider></v-divider>

<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="primary"
flat
@click="onClose"
>
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
`,
data: function() {
return {
dialog$: false,
};
},
methods: {
onClose() {
this.dialog$ = false;
this.$emit('update:dialog', this.dialog$);
},
},
watch: {
dialog: {
immediate: true,
handler() {
this.dialog$ = this.dialog;
},
},
}
});

new Vue({
el: '#app',
data: {
dialog: false
},
template: `
<v-app id="inspire">
<v-btn color="red lighten-2" dark @click="dialog=true">Click Me</v-btn>
<mydialog :dialog.sync="dialog"></mydialog>
</v-app>
`,

});
<!doctype html>
<html>

<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.css" />
</head>

<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>
</body>

</html>


正如@raina77ow 所提到的,您还可以使用event bus 解决此类问题。但在这种情况下没有必要。

关于javascript - 重构vue单文件组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52121180/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com