如何在 Vue-cli 中使用 props、$ref 和 $emit?
Posted
技术标签:
【中文标题】如何在 Vue-cli 中使用 props、$ref 和 $emit?【英文标题】:How can I use props, $ref and $emit in Vue-cli? 【发布时间】:2020-09-19 04:39:47 【问题描述】:我一直在用 Vue-cli 学习 Vuejs。
我正在尝试弄清楚 props
和 $emit
是如何工作的。
我想不通的一件事是如何处理与多个组件相关的function
。
All
,Ongoing
,Done
按钮应该根据每个复选框值过滤列表,并且在激活时其颜色变为绿色。
我不知道把filteredTodos()
的东西放在哪里,目前我在ListTodo.vue
中添加了这些东西,因为它们在Swichers.vue
和ListTodo.vue
中都相关。
我的代码是:Here
如果有人知道,你能告诉我怎么做吗?
谢谢
【问题讨论】:
我想你明白了!在 App 中取消注释您的data
项目,并在 ListToDo 中取消注释 prop
。剩下要做的就是将道具传递给 ListTodo...<ListToDo :filtered="filtered />
另外,根据您在切换器中发出的内容,filtered
属性似乎应该是字符串,而不是对象。
感谢您的评论,我按照您的方式,需要添加 filterState: this.filtered
以逃避覆盖道具。但是,仍然没有解决。我更新了一个问题和代码。如果您不介意,请看一下。
【参考方案1】:
更符合 vuejs 的这种精神,避免 refs 和在子组件中具有状态。
应用程序包含项目和过滤器,todolist.vue 将道具绑定到过滤列表(计算属性)。 切换器在过滤器上采用 v-model(双向绑定)。 Remove all 作为回调属性传递。
(编辑)
App.vue
<template>
<div>
<h1>TODO</h1>
<input type="text" v-model="inputTask" placeholder="Enter your task">
<button @click="addTask">Add task</button>
<Switchers
v-model='filter'
:onRemoveAll="removeAllItem"
/>
<ListTodo :todos='filtered' :noTask='noTask' :onRemoveTask='removeTask' :onToggleStatus='toggleStatus' />
</div>
</template>
<script>
import Switchers from "./components/Switchers";
import ListTodo from "./components/ListTodo";
export default
keyName: 'myTodoList',
components:
Switchers,
ListTodo,
,
created()
let keyObject =JSON.parse(localStorage.getItem(this.keyName))
if (keyObject)
this.todos = keyObject;
,
data()
return
inputTask: '',
// filtered:'',
filter: 'all',
todos: [],
;
,
computed:
filtered()
this.filter; this.todos;
return this.filteredTodos()
,
id() return this.todos.length+1 ,
noTask()
return
'all': 'No tasks',
'ongoing': 'No ongoing tasks',
'done': 'No done tasks',
[this.filter]
,
,
methods:
addTask()
if (this.inputTask==='')
return
this.addTaskChild(this.inputTask);
this.inputTask=''
,
addTaskChild(inputValue)
const todo = id: this.id, task:inputValue, done:false
this.todos.push(todo)
localStorage.setItem(this.keyName, JSON.stringify(this.todos));
this.filter = 'all'
,
removeAllItem()
this.todos = []
localStorage.clear();
this.filter = 'all'
,
filteredTodos()
return this.todos.filter(todo =>
if (this.filter === 'ongoing')
return !todo.done;
else if (this.filter === 'done')
return todo.done;
else
return true;
);
,
toggleStatus(todo)
todo.done = !todo.done
localStorage.setItem(this.keyName, JSON.stringify(this.todos));
,
removeTask(t)
this.todos = this.todos.filter(todo => todo.id !== t.id)
,
;
</script>
ListTodo.vue
<template>
<div>
<p>todos.length tasks left / todos.length tasks of all</p>
<ul>
<li v-for="todo in todos" :class="done:todo.done" :key="todo.id">
<input type="checkbox" :checked="todo.done" @click="status(todo)">
todo.task
<button @click="onRemoveTask(todo)">Remove task</button>
</li>
</ul>
<p v-show="todos.length===0">noTask</p>
</div>
</template>
<script>
export default
props:
todos:
type: Array,
required: true
,
onRemoveTask:
type: Function,
required: true
,
onToggleStatus:
type: Function,
required: true
,
noTask:
type: String,
required: true
,
data()
return
id: 1,
done:false,
;
,
methods:
status(todo)
this.onToggleStatus(todo)
,
,
;
</script>
Switchers.vue
<template>
<div>
<button :class="active: filter ==='all'" @click="set_filter('all')">All</button>
<button :class="active: filter ==='ongoing'" @click="set_filter('ongoing')">Ongoing</button>
<button :class="active: filter ==='done'" @click="set_filter('done')">Done</button>
<button @click="onRemoveAll">Remove all</button>
</div>
</template>
<script>
export default
props:
value:
type: String,
required: true
,
onRemoveAll:
type: Function,
required: true
,
watch:
value:
handler(v)
if (this.filter !== v)
this.filter = v
,
immediate: true
,
data()
return
filter:'',
;
,
methods:
set_filter(f)
this.filter = f
this.$emit('input', f)
,
,
;
</script>
<style lang="scss" scoped>
.active background: turquoise;
</style>
惯用的 vuejs 更喜欢响应式属性而不是命令式风格。在这种情况下,我们宁愿保留一份待办事项列表 + 过滤条件(在 App 中),并公开下一个 id、过滤列表和 noTask 消息的计算属性。
Switchers
是一个纯控制器组件:它没有状态,唯一的作用是将用户选择转换为调用 App 模型。
ListTodo
是一个视图,只负责显示作为道具提供的待办事项列表。它不关心列表是否被过滤。
也可以进行一些小的样式更改,但它们与 vuejs/emit 没有任何关系,所以我没有这样做。
Sandbox
【讨论】:
感谢您的评论,我是 Vue 的初学者。以我的毛孔经验,我无法想象你说什么:(我会多练习! 我用完整的源代码编辑了我的答案。希望能帮助到你。祝你好运! 非常感谢您的回答和描述。仍然需要一些时间来了解它们如何根据您的代码相互连接。无论如何,我会弄清楚谢谢,我很感激。以上是关于如何在 Vue-cli 中使用 props、$ref 和 $emit?的主要内容,如果未能解决你的问题,请参考以下文章