在Vue 3中创建自定义指令与在JavaScript中创建对象或函数相比,是十分简便的,因为指令是Vue框架的一部分,它允许你在组件之上添加额外的逻辑,而不需要修改组件内部的实现。更好的代码组织,让指令可以集中在一个地方,而不是分散在多个组件中。这使得代码更容易维护和理解。更好的复用性使用户可以轻松地在多个组件之间共享指令。与Vue的响应式系统集成,指令可以直接利用Vue的响应式系统,使得它们能够响应数据的变化。
为了让读者朋友更好的理解后续的指令,先在前面给大家复习一下vue指令:
-
v-if
:条件性地渲染元素。 -
v-else
:用于v-if
的 else 块。 -
v-else-if
:用于v-if
的 else-if 块。xml<!-- 条件渲染 --> <div> //isLoggedIn为真则进入 <h1 v-if="isLoggedIn">欢迎回来!</h1> <h1 v-else>请登录。</h1> </div>
-
v-show
:根据表达式之真假,切换元素的display
CSS属性。 -
v-for
:基于源数据多次渲染元素或模板块。xml<!-- 循环渲染 --> <ul> <li v-for="item in items" :key="item.id">{{ item.text }}</li> </ul>
-
v-bind
:绑定属性值,简写为一个冒号:
。xml<!-- 属性绑定 --> <img v-bind:src="imageSrc" alt="Vue.js 图标"> <!-- 简写 --> <img :src="imageSrc" alt="Vue.js 图标">
-
v-on
:绑定事件监听器,简写为@
。xml<!-- 事件监听 --> <button v-on:click="doSomething">点击我</button> <!-- 简写 --> <button @click="doSomething">点击我</button>
-
v-model
:在表单元素和应用状态之间创建双向绑定。xml<!-- 双向绑定 --> <input v-model="message">
时间就是金钱,效率就是生命
为什么要用vue来做这个记事本呢?对于vue初学者而言,JS应该是已经掌握的很好了,可能你们也用JS实现过这个备忘录的效果,但是在时间就是金钱,效率就是生命的今天,使用JS写这种有整体框架的项目效率实在是低下,不管是花费的时间还是对于代码的整洁度,vue的优势都是传统JS所无法比拟的。
这是目标项目的初步样式,我们将新增已办事项,未办事项,全部事项 三个新增功能
分模块步骤完成项目
arduino
//明确目标
//1.搭建一个VUE框架
//2.实现最开始的新增事项(add)
//3.完成事件按钮的绑定和数据的更改
//4.实现 已办事项,未办事项,全部事项 三大功能
1.创建大容器container作为vue框架的架构,全部功能放置在内
javascript
<div class="container">
<h1>小黑记事本</h1>
<textarea></textarea>
<button>添加</button>
<ul>
<li>
<span>{{index+1}}{{item.name}}</span>
<button>点击完成</button>
</li>
</ul>
<div class="total"><span>全部合计:{{list.length}} 件事项</span>
//"三大件"
<button id="Allhave" @click="alldata()">全部事项</button>
<button id="haved" @click="check_cmp()">已办事项</button>
<button id="unhaved" @click="check_uncmp()">待办事项</button></div>
</div>
//创建框架
const app=new Vue({
el:'.container',
data:{
//原始数据
list:[{id:1,name:'跳绳',isConplete:false},{id:2,name:'跑步',isConplete:false}],
list_copy:[{id:1,name:'跳绳',isConplete:false},{id:2,name:'跑步',isConplete:false}],
},
methods:{
},
}
在app的data中的数据list为什么需要两份呢,这是因为在后续我们对与list会进行一系列的操作,如增查操作,在container框架内展示的都是list内的内容,而我们没有通过V-if进行筛选,所以每一次的查找list实际的值都发生了改变,而list_copy中记录的全部的数据,因此我们可以通过这个实现这些操作。
bash
id用来记录事件的序号
isConplete用来判断事件是否完成,默认为false
name用来记录时间的名称
刨去CSS样式大体是这样子
接下来进行我们的第二步骤:
arduino
//给textarea后面的按钮加上点击事件按钮,函数设置为add()
<button @click="add()">添加</button>
在app的methods中加入add()方法:
kotlin
methods:{
add(){
if(this.up_data===''||this.up_data===' '){
// 是空就不提交
}
else{
const timer=+new Date()//使用时间戳来代表ID,也可以记录该创建时间
this.list.push({id:timer,name:this.up_data,isConplete:false})
//复制数据,存贮
this.list_copy=this.list
//清空输入框
this.up_data=''
}
}
},
第三步 完成事件按钮的绑定和数据的更改
在标签的button按钮中,加上@click="cmp(item.id)事件,item.id确保获取到的事件准确
xml
<li v-for="(item,index) in list">
<span>{{index+1}}{{item.name}}</span>
<button @click="cmp(item.id)">完成</button>
</li>
在methods中加入cmp()方法:
kotlin
cmp(i){
//创建临时变量index
let index
//获得未完成项目
this.list=this.list.filter(item=>{
if(item.id===i)
//记录下被移除的项目
index=item;
return item.id !=i })
//做出标记
if(!index.isConplete){
index.isConplete=true
index.name+='(完成)'
//将完成的项目放置最后
}
this.list.push(index)
this.list_copy=this.list
},
第四步 实现 已办事项,未办事项,全部事项 三大功能
已办事项
arduino
//给已办事项button按钮加上点击事件按钮,函数设置为check_cmp()
<button id="haved" @click="check_cmp()">已办事项</button>
在app的methods中加入check_cmp()方法:
kotlin
check_cmp(){
//防止list数据不全面,将全部数据再赋值
this.list=this.list_copy
this.list=this.list.filter(item=>item.isConplete===true)
},
未办事项
arduino
//给未办事项button按钮加上点击事件按钮,函数设置为check_uncmp()
<button id="unhaved" @click="check_uncmp()">待办事项</button>
在app的methods中加入check_uncmp()方法:
kotlin
check_uncmp(){
//防止list数据不全面,将全部数据再赋值
this.list=this.list_copy
this.list=this.list.filter(item=>item.isConplete===false)
},
全部事项
arduino
//给未办事项button按钮加上点击事件按钮,函数设置为"alldata()
<button id="Allhave" @click="alldata()">全部事项</button>
在app的methods中加入check_uncmp()方法:
javascript
alldata(){
//将全部数据送回list
this.list=this.list_copy
},
全部完成后可以实现以下效果
至于删除操作与这些操作大同小异,大家可以自行编辑操作。
VUE对于JS在框架这方面的优势是十分明显的了,这些代码除CSS外只有90行不到,纯VUE代码只有70行不到,如果使用纯JS书写200行或许都不够
这个只有录入和删除功能的JS都100多行了。 原本想再写个纯JS版本的工作量太大了,还是算了吧,等以后补上吧。
最后代码奉上:
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./DiaryNote.css">
<title>Todos</title>
</head>
<body>
<div class="container">
<h1>小黑记事本</h1>
<textarea v-model="up_data" maxlength="15" placeholder="最大输入15字事件"></textarea>
<button @click="add()">添加</button>
<ul>
<li v-for="(item,index) in list">
<span>{{index+1}} {{item.name}}</span>
<button @click="cmp(item.id)">完成</button>
</li>
</ul>
<div class="total"><span>全部合计:{{list.length}} 件事项</span><button id="Allhave" @click="alldata()">全部事项</button> <button id="haved" @click="check_cmp()">已办事项</button><button id="unhaved" @click="check_uncmp()">待办事项</button></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el:'.container',
data:{
list:[{id:1,name:'跳绳',isConplete:false},{id:2,name:'跑步',isConplete:false}],
list_copy:[{id:1,name:'跳绳',isConplete:false},{id:2,name:'跑步',isConplete:false}],
up_data:''
},
methods:{
add(){
if(this.up_data===''||this.up_data===' '){
// 是空就不提交
}
else{
const timer=+new Date()
this.list.push({id:timer,name:this.up_data,isConplete:false})
//复制数据,存贮
this.list_copy=this.list
//清空输入框
this.up_data=''
}
},
cmp(i){
// console.log(this.list)
let index
this.list=this.list.filter(item=>{
if(item.id===i)
//记录下被移除的项目
index=item;
return item.id !=i })
//做出标记
if(!index.isConplete){
index.isConplete=true
index.name+='(完成)'
//将完成的项目放置最后
}
this.list.push(index)
this.list_copy=this.list
},
check_cmp(){
//防止list数据不全面,将全部数据再赋值
this.list=this.list_copy
this.list=this.list.filter(item=>item.isConplete===true)
},
check_uncmp(){
this.list=this.list_copy
this.list=this.list.filter(item=>item.isConplete===false)
},
alldata(){
this.list=this.list_copy
},
}
})
</script>
ps:写这些代码的时候一直想着数据,其实查找操作可以使用V-if大家可以试试。
感谢阅读指点。