![](/img/trans.png)
[英]Get the value of a computed property in Vue.js and use it in a data property
[英]vue.js cannot use data property in computed method
我正在尝试在这样的计算方法中使用我的数据的属性:
data() {
return {
ToDoItems: [
{ id: uniqueId("todo-"), label: "Learn Vue", done: false },
{
id: uniqueId("todo-"),
label: "Create a Vue project with the CLI",
done: true,
},
{ id: uniqueId("todo-"), label: "Have fun", done: true },
{ id: uniqueId("todo-"), label: "Create a to-do list", done: false },
],
};
},
computed: {
listSummary() {
const numberFinishedItems = this.ToDoItems.filter((item) => item.done)
.length;
return `${numberFinishedItems} out of ${this.ToDoItems.length} items completed`;
},
},
但是 IDE (Visual Studio Code) 和编译器会抛出错误:
类型“ComponentPublicInstance<{}、{}、{}、{}、{}、EmitsOptions、{}、{}、false、ComponentOptionsBase<{}、{}、{}、{} 上不存在属性“ToDoItems” , {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, 字符串, {}>>'。
我正在关注 mozilla 的 vue.js 教程( https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties#adding_a_summary_ )
有什么改变是不可能的/不同的吗?
提前致谢
完整代码:
<template>
<div id="app">
<h1>To-Do List</h1>
<to-do-form @todo-added="addToDo"></to-do-form>
<h2 id="list-summary">{{ listSummary }}</h2>
<ul aria-labelledby="list-summary" class="stack-large">
<li v-for="item in ToDoItems" :key="item.id">
<to-do-item :label="item.label" :done="true" :id="item.id"></to-do-item>
</li>
</ul>
</div>
</template>
<script lang="ts">
import uniqueId from "lodash.uniqueid";
import { defineComponent } from "vue";
import ToDoItem from "./components/ToDoItem.vue";
import ToDoForm from "./components/ToDoForm.vue";
export default defineComponent({
name: "App",
components: {
ToDoItem,
ToDoForm,
},
data() {
return {
ToDoItems: [
{ id: uniqueId("todo-"), label: "Learn Vue", done: false },
{
id: uniqueId("todo-"),
label: "Create a Vue project with the CLI",
done: true,
},
{ id: uniqueId("todo-"), label: "Have fun", done: true },
{ id: uniqueId("todo-"), label: "Create a to-do list", done: false },
],
};
},
methods: {
addToDo(toDoLabel: string) {
this.ToDoItems.push({
id: uniqueId("todo-"),
label: toDoLabel,
done: false,
});
},
},
computed: {
listSummary() {
const numberFinishedItems = this.ToDoItems.filter((item) => item.done)
.length;
return `${numberFinishedItems} out of ${this.ToDoItems.length} items completed`;
},
},
});
</script>
<style>
/* Global styles */
.btn {
padding: 0.8rem 1rem 0.7rem;
border: 0.2rem solid #4d4d4d;
cursor: pointer;
text-transform: capitalize;
}
.btn__danger {
color: #fff;
background-color: #ca3c3c;
border-color: #bd2130;
}
.btn__filter {
border-color: lightgrey;
}
.btn__danger:focus {
outline-color: #c82333;
}
.btn__primary {
color: #fff;
background-color: #000;
}
.btn-group {
display: flex;
justify-content: space-between;
}
.btn-group > * {
flex: 1 1 auto;
}
.btn-group > * + * {
margin-left: 0.8rem;
}
.label-wrapper {
margin: 0;
flex: 0 0 100%;
text-align: center;
}
[class*="__lg"] {
display: inline-block;
width: 100%;
font-size: 1.9rem;
}
[class*="__lg"]:not(:last-child) {
margin-bottom: 1rem;
}
@media screen and (min-width: 620px) {
[class*="__lg"] {
font-size: 2.4rem;
}
}
.visually-hidden {
position: absolute;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
clip-path: rect(1px, 1px, 1px, 1px);
white-space: nowrap;
}
[class*="stack"] > * {
margin-top: 0;
margin-bottom: 0;
}
.stack-small > * + * {
margin-top: 1.25rem;
}
.stack-large > * + * {
margin-top: 2.5rem;
}
@media screen and (min-width: 550px) {
.stack-small > * + * {
margin-top: 1.4rem;
}
.stack-large > * + * {
margin-top: 2.8rem;
}
}
/* End global styles */
#app {
background: #fff;
margin: 2rem 0 4rem 0;
padding: 1rem;
padding-top: 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 2.5rem 5rem 0 rgba(0, 0, 0, 0.1);
}
@media screen and (min-width: 550px) {
#app {
padding: 4rem;
}
}
#app > * {
max-width: 50rem;
margin-left: auto;
margin-right: auto;
}
#app > form {
max-width: 100%;
}
#app h1 {
display: block;
min-width: 100%;
width: 100%;
text-align: center;
margin: 0;
margin-bottom: 1rem;
}
</style>
要在您的组件中获得类型推断,您应该使用defineComponent
function 创建它:
import {defineComponent} from 'vue';
export default defineComponent({
data() {
return {
ToDoItems: [
{ id: uniqueId("todo-"), label: "Learn Vue", done: false },
{
id: uniqueId("todo-"),
label: "Create a Vue project with the CLI",
done: true,
},
{ id: uniqueId("todo-"), label: "Have fun", done: true },
{ id: uniqueId("todo-"), label: "Create a to-do list", done: false },
],
};
},
computed: {
listSummary() {
const numberFinishedItems = this.ToDoItems.filter((item) => item.done)
.length;
return `${numberFinishedItems} out of ${this.ToDoItems.length} items completed`;
},
},
})
也许你应该尝试注释计算的返回值
请参阅 vue3 文档注释返回类型
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.