todomvc项目_reactive vue

todomvc项目_reactive vue所有实现代码在文章结尾处分析整个实现过程的步骤:1.显示大标题“todoMVC”在h1中引入{{msg}},在js文件中将msg赋值,从而在html中显示大标签的内容2.当没有数据时,两块模板需要隐藏,用到v-if标签。将两个模板放在一个template标签中,当items.length=0时,则v-if=false,进而两块模板隐藏。3.引入数据。将JS中写好的默认数据引入在html的每一个li标签中。4.将每个事件划分为完成/未完成。该功能用到双向数据绑定,可以在浏览器中vue模

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

所有实现代码在文章结尾处

分析整个实现过程的步骤:

1.显示大标题“todoMVC”

在h1中引入{
{msg}},在js文件中将msg赋值,从而在html中显示大标签的内容

2.当没有数据时,两块模板需要隐藏,用到v-if标签。将两个模板放在一个template标签中,当items.length=0时,则v-if=false,进而两块模板隐藏。

3.引入数据。将JS中写好的默认数据引入在html的每一个li标签中。

4.将每个事件划分为完成/未完成。该功能用到双向数据绑定,可以在浏览器中vue模块查看状态以及修改。在每一个li中设置completed属性。他的true/false取决于items中的定义。completed:items.completed。

5.得到未完成的li数码。用到filter方法过滤出没完成的事件.length

{this.items=this.items.filter(completed=>!items.completed).length}赋值在remaining身上

6.左下角item为1时是单数,其余情况均为复数形式。用到 remaining=1?‘’:‘s’

7.不可以输入空数据,用trim()判空,如果trim后没有则返回原来的样子,如果有值则把它传在id+1的位置,内容传到content中。最后将输入框自动清空。

8.功能切换:全选反选按钮。利用get 与set 方法分别控制全选按钮与其余小按钮。用到双向数据绑定,在总按钮中v-model。通过true与false控制是否勾选

(1)总按钮:get()到remaining是否等于0,如果等于另说明已经全部完成,该按钮需要在此时自动勾选。

(2)每个小按钮:将总按钮设置一个setStatus值,如果总按钮被勾选,则该值为true,取消勾选则为false。获得到该值时说明总按钮正在被点击。则其余小小按钮随之改变状态。通过v-for遍历每一个按钮的completed属性,状态与总按钮SetStatus状态保持一致。

这样就实现了全选反选的功能。

9.移除功能的实现。点击每个右上角的小叉叉,就会删除掉这个li数据,通过数组函数splice移除。设置该方法splice是从你点击的这个索引值index往后数1个(也就是它本身)this.items.splice(index, 1)

10.点击清空已完成时只留下未完成的Li传入items中。设置@click方法触碰到js中事件。在此事件中再次用到filter过滤方法,过滤得到未完成的li,重新放在item中。就实现了清空已完成的操作。

要注意:当没有已完成项目时 该功能需要被隐藏。所以要判断总的项目数量是否大于未完成数量,如果true则v-show该方法,反之亦然。

11.编辑任务项。db双击li切换到新的editing中。只要双击就触碰到方法使得它俩相等,相等就会触碰到显示editing这个功能。 进入到编辑标签后,将原本的content赋予编辑标签内让我们编辑。

如果不想编辑的话就点击esc键,会使等式不相等,进而退出编辑功能。

如果想要保存的话可以点击enter键 或者使编辑框失去焦点。即可保存。在点击与失去上加上一个事件。先进行判空,在保存,再把编辑页面去掉。这样就实现了一整个编辑的大动作。

12.全局获取焦点设置当进入到这个页面后自动获取输入框的焦点,无需手动点击后获取焦点。

设置全局指令。Vue.directive()

局部指令:当进入编辑框时也无需手动再次点击才能获取焦点,设置局部指令directives:{}

13.路由状态切换。通过 window.onhashchange 获取点击的路由 hash (# 开头的),来获取对应的那个状态值,并将状态 值赋值给 filterStatus。如果这个值是空,则显示所有项目,如果是active则显示未完成项目,如果为completed则显示已完成项目。此处再次用到filter过滤的方法。并且将最初的v-for内容全部换成点击a标签后才会显示的内容。

14.数据持久化:无论你保存与否,退出与否,你输入过的数据都会存在这个页面中,不会丢失,即使重新运行该代码。

使用 window.localStorage 实例进行保存数据与获取数据

  1. 定义 itemStorage 数据存储对象,里面自定义 fetch 获取本地数据 , save 存数据到本地。

  2. 修改 Vue 实例中 data 选项的 items 属性,通过 itemStorage.fetch() 方法初始化数据

  3. Vue 实例中增加一个 watch 选项,用于监听 items 的变化,一旦变化通过 itemStorage.save() 重新保存数据 到本地

<!doctype html>
<html lang="en">

<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Template • TodoMVC</title>
	<link rel="stylesheet" href="node_modules/todomvc-common/base.css">
	<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
	<!-- CSS overrides - remove if you don't need it -->
	<link rel="stylesheet" href="css/app.css">
	<script src="./node_modules/vue/dist/vue.js"></script>
</head>

<body>
	<section class="todoapp" id="todoapp">
		<header class="header">
			<h1> {
  
  {msg}} </h1>
			<!-- enter回车出发事件 -->
			<input @keyup.enter="addItem" class="new-todo" placeholder="What needs to be done?"  v-app-focus>
		</header>
		<template v-if="items.length">
			<section class="main">
				<input id="toggle-all" class="toggle-all" type="checkbox" v-model="toggleAll">
				<label for="toggle-all">Mark all as complete</label>
				<ul class="todo-list">
					<!-- These are here just to show the structure of the list items -->
					<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
					<li :class="{completed:item.completed ,editing:item===currentItem}" v-for="(item,index) in filterItems"
						:key="item.id">
						<div class="view">
							<input class="toggle" type="checkbox" v-model="item.completed">
							<!-- 双击触碰toEdit函数,在js中使得currentItem===item,便有了:editing:true 将li更换成editing模板-->
							<label @dblclick=toEdit(item)>{
  
  {item.content}} </label>
							<button class="destroy" @click="removeItem(index)"></button>
						</div>
						<input class="edit" :value="item.content" @keyup.Esc=cancelEdit
							@keyup.enter="finishEdit(item, index,$event)" @blur="finishEdit(item,index, $event)" v-todo-focus="item === currentItem">
					</li>
				</ul>
			</section>
			<!-- This footer should hidden by default and shown when there are todos -->
			<footer class="footer">
				<!-- This should be `0 items left` by default -->
				<span class="todo-count"><strong>{
  
  {remaining}}</strong> item{
  
  {remaining === 1 ? "" : "s"}} left</span>
				<!-- Remove this if you don't implement routing -->
				<ul class="filters">
					<li>
						<a :class="{selected:filterStatus==='all'}" href="#/">All</a>
					</li>
					<li>
						<a :class="{selected:filterStatus==='active'}" href="#/active">Active</a>
					</li>
					<li>
						<a :class="{selected:filterStatus==='completed'}" href="#/completed">Completed</a>
					</li>
				</ul>
				<!-- Hidden if no completed items are left ↓ -->
				<button class="clear-completed" @click="removeCompeted" v-show="items.length > remaining">Clear
					completed</button>
			</footer>
		</template>
	</section>
	<footer class="info">
		<p>Double-click to edit a todo</p>
		<!-- Remove the below line ↓ -->
		<p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
		<!-- Change this out with your name and url ↓ -->
		<p>Created by <a href="http://todomvc.com">you</a></p>
		<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
	</footer>
	<!-- Scripts here. Don't remove ↓ -->
	<script src="node_modules/todomvc-common/base.js"></script>
	<script src="js/app.js"></script>
</body>

</html>

(function (Vue) {
	//模拟数据
	const items =[
	]
	var STORAGE_KEY = 'items-vuejs';
	// 本地存储数据对象
	const itemStorage = {
		fetch() { // 获取本地数据
			return JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
		},
		save(items) { // 保存数据到本地
			localStorage.setItem(STORAGE_KEY, JSON.stringify(items));
		}
	}


	Vue.directive("app-focus",{
		//聚集函数
		inserted(el,binding){
			el.focus()
		}
	})
	const vm = new Vue({
		el:"#todoapp",
		data:{
			msg:"TobeNumOne",
			items:itemStorage.fetch(),
			currentItem:null,
			filterStatus:"all"
		},
		  // 监听器
		  watch: {
			// 如果 items 发生改变,这个函数就会运行
			items: {
				deep: true, // 发现对象内部值的变化, 要在选项参数中指定 deep: true。深度监听
				handler: function (newItems, oldItems) {
					//本地进行存储
					itemStorage.save(newItems)
				}
			}
		},
		directives:{
			"todo-focus":{
				update(el){
				el.focus()
					
				}
			}
		},
		computed:{
			remaining(){
				//filter过滤方法  : 过滤出来没完成的
				return this.items.filter(items => !items.completed).length
			},
			toggleAll:{
				//控制全选按钮
				get(){
					return this.remaining === 0
				},
				//控制下面的小小按钮
				set(newStatus){
					console.log(newStatus);
					this.items.forEach((item)=>{
						item.completed = newStatus
					})
				}
			},
			filterItems(){
				switch (this.filterStatus) {
					case "active":
						return this.items.filter(item=>!item.completed)
						break;

					case "completed":
						return this.items.filter(item=>item.completed)
						break;
				
					default:
						return this.items
						break;
				}
			}
		},
		methods:{
			addItem(event){
				console.log(event.target); //addItem
				console.log("addItem",event.target.value);
				//获取输入的数据,trim去掉前后空格
				const content = event.target.value.trim()
				//判断数据是否为空
				if(!content.length){
					return
				}
				//不空,添加到数组中去,生成ID值,现在的数组长度+1 = 它的ID值
				const id = this.items.length + 1
				//添加到数组中
				this.items.push({
					id,
					content,
					completed:false
				})
				event.target.value=""
			},
			removeItem(index){
				//从当前索引开始删除一个,也就是它本身
				this.items.splice(index, 1) 
			},
			//清除已经完成的
			removeCompeted(){
				//filter是过滤出来,是拿到没完成的。
				this.items=this.items.filter(item => !item.completed)
			},
			toEdit(item){
				this.currentItem = item
			},
			cancelEdit(){
				this.currentItem = null
			},
			finishEdit(item,index,event){
				const content = event.target.value.trim();
				if(!event.target.value.trim()){
					this.removeItem(index)
					return 
				}
				item.content = content;
				this.currentItem=null
			}
		}
	})
	window.onhashchange = function(){
		const hash = window.location.hash.substr(2) || "all"
		vm.filterStatus=hash
	}
	window.onhashchange()
})(Vue);

需要todomvc的CSS样式和bootstrap样式或者空模板想自己从0做这个项目的话可以私聊我哈,我有压缩包。

欢迎兄弟姐妹们一起来讨论!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/194757.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • log4j pattern详解_标题的含义和作用ppt

    log4j pattern详解_标题的含义和作用pptConversionPattern参数的格式含义格式名含义%c输出日志信息所属的类的全名%d输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-ddHH:mm:ss},输出类似:2002-10-18-22:10:28%f输出日志信息所属的类的类名%l输出日志事件的发生位置,即输出日志信息的语句处于它所在…

  • 8分钟完成NodeJs爬虫,把JRS小姐姐全部看个遍

    本文讲的是利用nodejs以及相关库,爬取JRS爆照区内的爆照贴,并保存相关数据到本地。依赖选择constsuperagent=require(‘superagent’);//nodejs里一个非常方便的客户端请求代理模块constcheerio=require(‘cheerio’);//Node.js版的jQueryconstasync=r…

  • 音视频开发入门_视频制作基础知识

    音视频开发入门_视频制作基础知识音视频涉及语音信号处理、数字图像处理、信息论、封装协议、编解码、渲染、流媒体协议、网络传输、视频特效、音频特效等等。而音视频在现实生活中扮演着越来越重要的角色,比如视频会议、短视频、直播、播放器、语音聊天等。所以,从事音视频工作是一件比较有意义的事情,挑战与机遇并存。本文主要从六个方面进行介绍:音视频开发基础、音视频进阶成长、音视频工作方向、音视频开源库、流媒体协议与音视频书籍。…

  • 如何用python画一个圆(python主要是做什么的)

    本文为大家分享了python实现画圆功能的实例代码,有需要的朋友请参考下文!importnumpyasnpimportmatplotlib.pyplotaspltfrommatplotlib.patchesimportPolygonimportmatplotlib.patchesasmpatchesfig=plt.figure(figsize=(16,8))ax=…

  • Python脚本语言第一行的写法「建议收藏」

    Python脚本语言第一行的写法「建议收藏」脚本语言的第一行,目的就是指出,你想要你的这个文件中的代码用什么可执行程序去运行它,就这么简单#!/usr/bin/python是告诉操作系统执行这个脚本的时候,调用/usr/bin下的python

  • cefsharp设置cookie,CefSharp如何存储Cookie

    cefsharp设置cookie,CefSharp如何存储CookieIcan’tgetcookiestosaveinCefSharp.HereiswhatItried:CefSettingssettings=newCefSettings();stringpath=Environment.GetFolderPath(Environment.SpecialFolder.Desktop);Cef.Initialize(newCefS…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号