尝鲜 vue3.0 新特性 Vue Function API 实现 todo list

Vue Function API 已经公布一段时间了,今天尝鲜了一下,写了个 todo list

主要依赖: vue: 2.6.10 vue-function-api: 2.0.6

1.父组件 Parent.vue

1
2
<template>
3
  <div>
4
    <Children
5
      :list="list"
6
      @subAddItem="addItem"
7
      @subRemoveItem="removeItem"
8
      @subRemoveAll="removeAll"
9
    />
10
  </div>
11
</template>
12
13
<script>
14
import { value, onCreated } from "vue-function-api";
15
import Children from "./Children";
16
export default {
17
  components: {
18
    Children
19
  },
20
21
  setup(props, context) {
22
    const list = value([]);
23
24
    // 异步数据
25
    const getList = () => {
26
      return new Promise((resolve, reject) => {
27
        const defaultList = [
28
          "开会",
29
          "开完会写代码",
30
          "和产品沟通",
31
          "沟通完写代码",
32
          "和设计沟通",
33
          "写代码"
34
        ];
35
        setTimeout(() => {
36
          resolve(defaultList);
37
        }, 100);
38
      });
39
    };
40
41
    // 获取数据,初始化list数据
42
    onCreated(async () => {
43
      try {
44
        const defaultList = await getList();
45
        list.value = defaultList;
46
      } catch (error) {
47
        console.log(error);
48
      }
49
    });
50
51
    // 添加单个
52
    const addItem = inputValue => {
53
      list.value.push(inputValue);
54
    };
55
56
    // 删除单个
57
    const removeItem = item => {
58
      const result = confirm("确定要删除此项?");
59
      if (result) {
60
        list.value = list.value.filter(val => val !== item);
61
      }
62
    };
63
64
    // 删除所有
65
    const removeAll = item => {
66
      const result = confirm("确定要删除全部?");
67
      result ? (list.value = []) : "";
68
    };
69
70
    return {
71
      list,
72
      addItem,
73
      removeItem,
74
      removeAll
75
    };
76
  }
77
};
78
</script>

2.子组件 Children.vue

1
<template>
2
  <div class="container">
3
    <h3>vue-function-api 实现todo list</h3>
4
5
    <div>
6
      <input type="text" v-model="inputValue">
7
      <button @click="subAddItem">新增</button>
8
    </div>
9
10
    <ul class="wrapper">
11
      <li class="item" v-for="(item,index) in list" :key="index">
12
        {{item}}
13
        <button class="delete-button" @click="subRemoveItem(item)">删除</button>
14
      </li>
15
      <li class="item" v-if="list.length>1">
16
        <button class="delete-button" @click="subRemoveAll">删除全部</button>
17
      </li>
18
    </ul>
19
  </div>
20
</template>
21
22
<script>
23
import { value } from "vue-function-api";
24
export default {
25
  props: {
26
    list: {
27
      type: Array,
28
      required: false,
29
      default: () => []
30
    }
31
  },
32
  setup(props, context) {
33
    const { emit } = context;
34
    const inputValue = value("");
35
36
    // 添加单个
37
    const subAddItem = () => {
38
      const { value } = inputValue;
39
      const { list } = props;
40
      if (!value) {
41
        alert("请输入内容");
42
        return;
43
      }
44
      if (list.includes(value)) {
45
        alert("已存在此项");
46
      } else {
47
        // 分发事件
48
        emit("subAddItem", value);
49
      }
50
      inputValue.value = "";
51
    };
52
53
    // 删除单个
54
    const subRemoveItem = item => {
55
      // 分发事件
56
      emit("subRemoveItem", item);
57
    };
58
59
    // 删除所有
60
    const subRemoveAll = () => {
61
      // 分发事件
62
      emit("subRemoveAll");
63
    };
64
65
    // 生命周期
66
    onCreated(() => {
67
      console.log(props.list, "onCreated"); // 拿不到异步props数据
68
    });
69
70
    onMounted(() => {
71
      console.log(props.list, "onMounted"); // 拿不到异步props数据
72
    });
73
74
    onUpdated(() => {
75
      console.log(props.list, "onUpdated"); // 可以拿到异步props数据
76
    });
77
78
    return {
79
      inputValue,
80
      subAddItem,
81
      subRemoveItem,
82
      subRemoveAll
83
    };
84
  }
85
};
86
</script>
87
88
<style lang="less" scoped>
89
.container {
90
  width: 400px;
91
  margin: 200px auto;
92
  padding: 20px;
93
  background-color: #f5f5f5;
94
  box-sizing: border-box;
95
  .wrapper {
96
    box-sizing: border-box;
97
    width: 200px;
98
    margin: 0;
99
    padding: 0;
100
    .item {
101
      box-sizing: border-box;
102
      list-style: none;
103
      overflow: hidden;
104
      margin: 0;
105
      margin-top: 20px;
106
      color: #373737;
107
      cursor: pointer;
108
      .delete-button {
109
        float: right;
110
      }
111
    }
112
  }
113
}
114
</style>

3.实现效果
在这里插入图片描述