〖Vue〗必备小知识-Vue 组件实练小栗子-todolist优化

246 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

Vue 组件 component 实练小栗子

前文我们学习了 Vue 组件的概念/组件传值/及小小例子, 上一篇我们练习了一个 进度条的小栗子,

本文我们继续上手演练小栗子, 实练一下 todolist, 并进行优化

2. todoList

todoList 实现代码 及 每步注释 (方法一)

<div id="box">
  <my-form :add="add" :query="query"></my-form>
  <my-list :todos="todos" :del="del"></my-list>
</div>
<script>
  var myForm = {
    props: ['add', 'query'], // 接收父组件传递过来的两个方法
    data() {
      return {
        str: '',
      }
    },
    template: `
      <div>
        <input type="text" v-model="str" v-on:keyup.enter="addItem(str)" />
        <button v-on:click="query(str)">查找</button>
      </div>
    `,
    methods: {
      addItem(str) {
        this.add(str) // str 文本框输入的内容
        this.str = '' // 文本框输入的内容清空
      },
    },
  }

  var myList = {
    props: ['todos', 'del'],
    template: `
      <ul>
        <li v-for="(item, index) in todos" v-bind:key="index" v-show="item.flag">
          {{ index }} {{ item.text }}
          <button v-on:click="del(index)">删除</button>
        </li>
      </ul>
    `
  }

  var vm = new Vue({
    el: '#box',
    components: {
      myList, myForm,
    },
    data: {
      todos: [
        { text: '学习 TypeScript', flag: true},
        { text: '学习 Vue3 源码', flag: true},
        { text: '然后整个牛项目, 让大家大开眼界', flag: true},
      ],
    },

    methods: {
      add(str) { // 接收 子组件数据, 子组件调用了这个方法
        this.todos.push({ "text": str, flag: true }) // 添加一个项目
      },

      del(index) { // 接收子组件数据, 子组件调用了这个方法 del 根据下标进行删除
        this.todos.splice(index, 1)
      },

      query(str) { // 接收子组件数据, 子组件调用了这个方法 query 根据str 进行查找
        this.todos.forEach((item) => {
          if(item.text.includes(str)) {
            item.flag = true // true 表示查找到
          } else {
            item.flag = false // false 表示不符合查找条件, 不用显示出来
          }
        })
      }
    },
  })
</script>

改造 todoList 进行组件化 实现代码 及 每步注释 (方法二)

<div id="box">
  <my-form :add="add" :query="query" @child="receive"></my-form>
  <my-list :todos="todos" :del="del"></my-list>
</div>
<script>
  var myForm = {
    props: ['add', 'query'], // 接收父组件传递过来的两个方法
    data() {
      return {
        msg: '',
      }
    },
    template: `
      <div>
        <input type="text" v-model="msg" v-on:keyup.enter="addItem" v-on:input="input"/>
        <button v-on:click="query">查找</button>
      </div>
    `,
    methods: {
      addItem() {
        this.add() // 文本框输入的内容
        this.msg = '' // 文本框输入的内容清空
      },
      input() {
        this.$emit("child", this.msg) // 向父组件发送文本框输入的内容
      }
    },
  }

  var myList = {
    props: ['todos', 'del'],
    template: `
      <ul>
        <li v-for="(item, index) in todos" v-bind:key="index" v-show="item.flag">
          {{ index }} {{ item.text }}
          <button v-on:click="del(index)">删除</button>
        </li>
      </ul>
    `
  }

  var vm = new Vue({
    el: '#box',
    components: {
      myList, myForm,
    },
    data: {
      todos: [
        { text: '学习 TypeScript', flag: true},
        { text: '学习 Vue3 源码', flag: true},
        { text: '然后整个牛项目, 然后惊艳所有人!', flag: true},
      ],
    },

    methods: {
      add(str) { // 接收 子组件数据, 子组件调用了这个方法
        this.todos.push({ "text": str, flag: true }) // 添加一个项目
      },

      del(index) { // 接收子组件数据, 子组件调用了这个方法 del 根据下标进行删除
        this.todos.splice(index, 1)
      },

      query(str) { // 接收子组件数据, 子组件调用了这个方法 query 根据str 进行查找
        this.todos.forEach((item) => {
          if(item.text.includes(str)) {
            item.flag = true // true 表示查找到
          } else {
            item.flag = false // false 表示不符合查找条件, 不用显示出来
          }
        })
      },
      receive(p) {
        this.str = p
      }
    },
  })
</script>