Vuejs 實現簡易 todoList 功能 與 組件


todoList

結合之前 Vuejs 基礎與語法

  • 使用 v-model 雙向綁定 input 輸入內容與數據 data
  • 使用 @click 和 methods 關聯事件
  • 使用 v-for 進行數據循環展示
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>TodoList</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="root">
    <div>
      <input v-model="inputValue"/>
      <button @click="handleSubmit">提交</button>
    </div>
    <ul>
      <li v-for="(item,index) of list" :key="index">
        {{item}}
      </li>
    </ul>
  </div>

  <script>
    new Vue({
      el: "#root",
      data: {
        inputValue: '',
        list: []
      },
      methods: {
        handleSubmit: function(){
          this.list.push(this.inputValue)
          this.inputValue = ''
        }
      }
    })
  </script>
</body>
</html>
View Code

JSbin 預覽

todoList 組件拆分

Vuejs 組件相關 詳細參考組件基礎

全局組件

注冊全局組件,並在 HTML 中通過模板調用組件

    //注冊全局組件
    Vue.component('todo-item',{
      template: '<li>item</li>'
    })
    <ul>
      <!-- <li v-for="(item,index) of list" :key="index">
        {{item}}
      </li> -->
      <todo-item></todo-item>      <!-- 通過模板使用組件 -->
    </ul>
View Code

JSbin 預覽

局部組件

在注冊了局部組件之后,直接通過模板調用是不可以的,必須要在最外層的 Vue 的實例中添加 components: { }進行組件聲明。

    //注冊局部組件
    var TodoItem = {
      template: '<li>item</li>'
    }
    new Vue({
      el: "#root",
      components: {   //局部組件需要聲明的 components
        'todo-item': TodoItem
      },
      data: {
        inputValue: '',
        list: []
      },
      methods: {
        handleSubmit: function(){
          this.list.push(this.inputValue)
          this.inputValue = ''
        }
      }
    })
View Code

JSbin 預覽

即通過局部注冊的組件,需要在其他的 Vue 實例中使用該局部組件。必須使用 components 對該局部組件進行注冊。
上面的實例中,要在 Vue 實例中使用 TodoItem 這個局部組件,就通過 todo-item 這個標簽來使用。當在實例中 注冊好了以后,才可以在模板里面使用這個標簽。這樣就算正確的使用了局部組件。

外部傳遞參數

給 todo-item 標簽添加 :content 屬性,值為循環的每一項的內容 "item"
這樣就可以吧 content 傳遞給 todo-item 這個組件

<todo-item v-for="(item,index) of list" :key="index" :content="item"></todo-item> 

但是直接將組件改成是不行的

    Vue.component('todo-item',{
      template: '<li>{{content}}</li>'
    })

需要讓組件接收屬性,所以要在todo-item組件里面定義props屬性,其值為一個數組 'content' 。
其含義是,該組件接收從外部傳遞的進來的名字叫做 content 的屬性

    Vue.component('todo-item',{
      props: ['content'],
      template: '<li>{{content}}</li>'
    })

JSbin 預覽

組件與實例的關系

Vue 之中,每一個組件其實也是一個 Vue 的實例。因此在 Vue 項目中,是一個個實例構建而成的。
因此組件之中,也可以綁定 @click 事件,添加 methods 屬性。

    Vue.component('todo-item',{
      props: ['content'],
      template: '<li @click="handleClick">{{content}}</li>',
      methods: {
        handleClick: function(){
          alert('clicked')
        }
      }
    })

JSbin 預覽


同樣的實例也可以被稱作一個組件,那么我們這個根實例當中的 template 模板是什么呢 ?
如果一個 Vue 實例沒有模板,會到掛載點去找。如下實例,根實例會找到 #root 下面掛載點的所有內容作為模板。

    new Vue({
      el: "#root",
      data: {
        inputValue: '',
        list: []
      },
      methods: {
        handleSubmit: function(){
          this.list.push(this.inputValue)
          this.inputValue = ''
        }
      }
    })

 

為 todoList 添加刪除功能

通過 發布 / 訂閱,當子組件點擊時,通知父組件把數據刪除掉。在子組件中,發布自定義一個 'delete' 事件。調用 this.$emit 方法,並傳遞 index 的值。

子組件向外部進行發布

    //子組件
    Vue.component('todo-item',{
      props: ['content','index'],
      template: '<li @click="handleClick">{{content}}</li>',
      methods: {
        handleClick: function(){
          //發布
          this.$emit('delete', this.index)
        }
      }
    })

父組件在模板里創建子組件的時候,監聽子組件向外觸發的 delete 事件,如果監聽到 delete 事件,執行 handleDelete 函數。

      <todo-item v-for="(item,index) of list"
                 :key="index"
                 :content="item"
                 :index="index"
                 @delete="handleDelete">  <!-- 監聽delete事件 -->
      </todo-item>      <!-- 通過模板使用組件 -->

然后在父組件的 methods 中,寫好 handleDelete 方法。

    //最外層實例,父組件
    new Vue({
      el: "#root",
      data: {
        inputValue: '',
        list: []
      },
      methods: {
        handleSubmit: function(){
          this.list.push(this.inputValue)
          this.inputValue = ''
        },
        handleDelete: function(index){
          this.list.splice(index,1)  //使用splice方法刪除list
        }
      }
    })

JSbin 預覽


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM