簡體   English   中英

如何在 Vue-cli 中使用 props、$ref 和 $emit?

[英]How can I use props, $ref and $emit in Vue-cli?

我一直在用 Vue-cli 學習 Vuejs。

我試圖弄清楚props$emit是如何工作的。

我不知道的一件事是,我該如何處理與多個組件相關的function

AllOngoingDone按鈕應該根據每個復選框值過濾列表,並且在活動時其顏色變為綠色。

我不知道將當前添加到ListTodo.vue中的filteredTodos() {}東西放在哪里,因為它們在Swichers.vueListTodo.vue中都是相關的。

我的代碼是:這里

如果有人知道,你能告訴我怎么做嗎?

謝謝

避免引用並在子組件中使用 state 會更符合 vuejs 的這種精神。

該應用程序包含項目和過濾器,todolist.vue 將道具綁定到過濾列表(計算屬性)。 切換器在過濾器上采用 v-model(雙向綁定)。 Remove all 作為回調屬性傳遞。

(編輯)

應用程序.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>

切換器.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是一個純 controller 組件:它沒有 state,它的唯一作用是將用戶選擇轉換為調用應用程序 model。

ListTodo是一個視圖,只負責顯示作為道具提供的待辦事項列表。 它不關心列表是否被過濾。

也可以進行一些小的樣式更改,但它們與 vuejs/emit 沒有任何關系,所以我沒有這樣做。

沙盒

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM