尝鲜 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.实现效果