vue3新特性
新增功能
Fragment
不受根节点限制,渲染函数可以接收Array
Teleport
类似Portal,随用随取,e.g.弹窗
Suspense
嵌套的异步依赖,e.g.async setup()
带来的变化
- 性能提升1.3x~2x
- TS支持,新增:Fragment、Teleport、Suspense
- 按需加载(配合Vite) & 组合式API
组合式API(composition)
https://v3.vuejs.org/api/composition-api.html#setup
https://v3.cn.vuejs.org/api/composition-api.html
新建项目
vue create todo-list
eslint + prettier
https://www.cnblogs.com/jiaoshou/p/11271719.html
初始化
添加bootstrap样式
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css" rel="stylesheet">
挂载到public/index.html
引入reactive创建响应式对象
const state = reactive({
valueAdd: "", // 添加事项
valueEdit: "", // 编辑事项
});
return toRefs(state);
具体实现
渲染item
<div class="form-group form-check mb-0">
<input
type="checkbox"
class="form-check-input"
:id="'item-' + index"
v-model="item.checked"
@click="() => (item.checked = !item.checked)"
/>
<label
class="form-check-label"
v-if="!item.isEdit"
@dblclick="showEdit(item, index)"
>{{ item.name }}</label
>
<label class="form-check-label" :for="'item-' + index" v-else>
<input type="text" v-model="valueEdit" @blur="inputBlur" />
</label>
</div>
<button
type="button"
class="close"
aria-label="Close"
@click="remove(index)"
>
<span aria-hidden="true">×</span>
</button>
点击checkbox完成任务
@click="() => (item.checked = !item.checked)"
<ul class="list-group">
<li
class="list-group-item"
v-for="(item, index) of finished"
:key="'finished-' + index"
>
<div class="form-group form-check">
<input
type="checkbox"
class="form-check-input"
:id="'finished-' + index"
v-model="item.checked"
disabled
/>
<label class="form-check-label" :for="'finished-' + index">{{
item.name
}}</label>
</div>
</li>
</ul>
// 已结束事项
finished: computed(() =>
state.lists.filter((item) => item.checked == true)
),
点击按钮添加新的任务
// 添加任务
const add = () => {
state.lists.push({
name: state.valueAdd,
checked: false,
isEdit: false,
});
state.valueAdd = "";
};
双击文字编辑任务
<label
class="form-check-label"
v-if="!item.isEdit"
@dblclick="showEdit(item, index)"
>{{ item.name }}</label
>
<label class="form-check-label" :for="'item-' + index" v-else>
<input type="text" v-model="valueEdit" @blur="inputBlur" />
</label>
双击切换至编辑模式
const showEdit = (item, index) => {
editIndex = index;
item.isEdit = true;
state.valueEdit = item.name;
};
单击关闭编辑模式
const inputBlur = () => {
state.lists[editIndex] = {
name: state.valueEdit,
checked: false,
isEdit: false,
};
};
点击按钮删除任务
const remove = (index) => {
state.lists.splice(index, 1);
};
多页面数据存储
store/index.js下
export default createStore({
state: {
list : []// 数据
},
mutations: {},
actions: {},
modules: {},
});
使用时,在reactive中通过computed来时时更新list
list: computed(() => store.state.list)