Vue入门

本文介绍了Vue.js的基本概念,为何选择Vue,以及其核心特性如声明式渲染、数据绑定和指令应用。内容涵盖了创建Vue实例、入门程序示例、声明式渲染的优势、常用指令(如v-text、v-html、v-on和v-model)和实现简单记事本功能的步骤。
摘要由CSDN通过智能技术生成

1 Vue.js 介绍

1.1 Vue.js是什么?

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计 为可以自底向上逐层应用. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一 方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。自底向上逐层应用:作为渐进式框架要实现的目标就是方便项目增量开发(即插即用)。

官方网站: https://cn.vuejs.org/v2/guide/ 作者 尤雨溪是中国人.

1.2 为甚么使用Vue?

  1. 声明式渲染: 前后端分离是未来趋势
  2. 渐进式框架: 适用于各种业务需求
  3. 简单易学: 国人开发,中文文档,不存在语言障碍,易于理解和学习

2 Vue.js 基础

2.1 Vue.js的使用

  1. 在html页面使用script引入vue.js的库即可使用。
    远程CDN 
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> 
    本地
    <script src="vue.min.js"></script>
    
  2. Vue-CLI脚手架:使用vue.js官方提供的CLI脚本架很方便去创建vue.js工程雏形

2.2 入门程序

创建一个vuetest目录, 并且在目录下创建 01_vue入门程序.html 文件.
代码编写步骤:
1、定义html,引入vue.js
2、定义app div,此区域作为vue的接管区域
3、定义Vue实例,接管app区域。
4、定义model(数据对象)
5、在app中展示数据

<!DOCTYPE html> 
<html lang="en"> 
<head>
	<meta charset="UTF-8"> 
	<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
	<title>Vue入门</title> 
	
	<!-- 1.创建HTML文件, 引入vue.js 有两种方式--> 
	<!-- 第一种 引入 vue.js的CDN地址 --> 
	<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"> </script> --> 
	<!-- 第二种 本地导入 --> 
	<script src="vue.min.js"></script> 
</head> 
<body>
	<!-- 2. 定义app div,此区域作为vue的接管区域 --> 
	<div id="app"> 
		<!-- {{}} 双括号是VUE中的差值表达式,将表达式的值输出到HTML页面 --> 
		{{name}} 
	</div> 
</body> 
<script> 
	//3. 创建vue实例 
	var VM = new Vue({ 
		//定义 Vue实例挂载的元素节点,表示vue接管该div 
		el:'#app', 
		//4.定义model模型数据对象 
		data:{
			name:"哈拉少" 
		} 
	}); 
</script> 
</html>
  1. {{}}: 插值表达式

    1. 插值表达式的作用?
      通常用来获取Vue实例中定义的数据(data)
      属性节点中 不能够使用插值表达式
  2. el: 挂载点

    1. el的作用 ?
      定义 Vue实例挂载的元素节点,表示vue接管该区域
    2. Vue的作用范围是什么 ?
      Vue会管理el选项命中的元素,及其内部元素
    3. el选择挂载点时,是否可以使用其他选择器 ?
      可以,但是建议使用 ID选择器
    4. 是否可以设置其他的DOM元素进行关联 ?
      可以但是建议选择DIV, 不能使用HTML和Body标签
  3. data: 数据对象

    1. Vue中用到的数据定义在data中
    2. data中可以写复杂类型
    3. 渲染复杂类型数据的时候,遵守js语法
<body>
	<!-- 此区域作为vue的接管区域 --> 
	<div id="app"> 
		{{name}} <br> 
		{{school.name}} {{school.mobile}}<br> 
		<ul>
			<li>{{names[0]}}</li> 
			<li>{{names[1]}}</li> 
			<li>{{names[2]}}</li> 
		</ul> 
	</div> 
</body> 
<script> 
	//创建vue实例 
	var VM = new Vue({ 
		el:'#app', 
		data:{
			name:"雷霆八嘎", 
			//对象类型数据 
			school:{ 
				name:"侯哥教育", 
				mobile:"1001001" 
			},
			//数组类型 
			names:["小斌","张百万","刘能"] 
		} 
	}); 
</script>

2.3 声明式渲染的好处

Vue中的声明式渲染,简单理解就是我们声明数据,Vue帮我们将数据渲染到HTML.

<!DOCTYPE html> 
<html lang="en"> 
	<head> 
		<meta charset="UTF-8" /> 
		<meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
		<title>Document</title> 
	</head> 
<body> 
	<div id="app"> 
		<h2>{{name}}</h2> 
	</div>
</body> 
	<!-- jQuery中,如果 DOM 发生变化, js代码也需要做相应的改变,高耦合 . 
	<script src="./js/jquery-1.8.3.min.js"></script> 
	<script> 
		$(document).ready(function () { 
			$("#app").append("<h2>Hello Word! !</h2>"); 
		}); 
	</script> --> 
	<!-- 在用 Vue中,只需要定义好展示数据,并把它放在 DOM 合适的位置就可以. --> 
	<script src="js/vue.min.js"></script> 
	<script> 
		var VM = new Vue({ 
			el: "#app", 
			//挂载点 
			data: { 
				name: "Hello Word! !"
			} 
		}); 
	</script> 
</html>

2.4 Vue常用指令

根据官网的介绍,指令 是带有 v- 前缀的特殊属性。通过指令来操作DOM元素

  1. v-text 指令
    作用: 获取data数据, 设置标签的内容.
    注意: 默认写法会替换全部内容,使用插值表达式{{}}可以替换指定内容.

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-text 指令</title>
    <!-- 1 引入vue -->
    <script src="js/vue.min.js"></script>
</head>
<body>
    <div id="app"> 
        <!-- v-text 获取data数据,设置标签内容,会覆盖之前的内容体--> 
        <h2 v-text="message">百度</h2> 
        <!-- 使用插值表达式,不会覆盖 --> 
        <h2>{{message}}百度</h2> 
        <!-- 拼接字符串 --> 
        <h2 v-text="message+1"></h2> 
        <h2 v-text="message+'abc'"></h2> 
    </div> 
    <script> 
        var VM = new Vue({ 
            el:"#app", 
            data:{
                message:"Java程序员" 
            }
        }) 
    </script> 
</body>
</html>
  1. v-html 指令
    作用: 设置元素的 innerHTML (可以向元素中写入新的标签)

代码示例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-html 指令</title>
</head>

<body>
    <div id="app">
        <!-- 获取普通文本 -->
         {{message}} 
        <h2 v-text="message"></h2>
        <h2 v-html="message"></h2> 
        <!-- 设置元素的innerHTML -->
        <h2 v-html="url"></h2>
        <h2 v-text="url"></h2>
    </div>
</body>
<script src="js/vue.min.js"></script>
<script> 
    var VM = new Vue({ 
        el: "#app", 
        data: { 
            message: "Java程序员", 
            url: "<a href='https://www.baidu.com'>百度一下</a>", 
        }, 
    });  
</script>

</html>
  1. v-on 指令
    作用: 为元素绑定事件, 比如: v-on:click,可以简写为 @click=“方法”
    绑定的方法定义在 VUE实例的, method属性中

语法格式

<div id="app"> 
	<!-- 使用v-on 绑定click 点击事件 --> 
	<input type="button" value="点击按钮" v-on:click="方法名"> 
	<!-- 使用 @符号也可以绑定--> 
	<input type="button" value="点击按钮" @click="方法名"> 
</div>

var VM = new Vue({ 
	el:"#app", 
	//通过methods ,专门存放Vue中的方法 
	methods:{ 
		方法名:function(){ 
			alert("123!") 
		}
	} 
})

代码示例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-on 指令</title>
</head>

<body>
    <div id="app">
        <!-- 使用v-on 绑定click 点击事件 -->
        <input type="button" value="点击按钮" v-on:click="show">
        <!-- 简写 @方式 -->
        <input type="button" value="点击按钮" @click="show">
        <!-- 双击事件 -->
        <input type="button" value="双击击按钮" @dblclick="show">
        <!-- 绑定点击事件 -->
        <h2 @click="changeFood">{{food}}</h2>
    </div>
</body>

<script src="js/vue.min.js"></script>
<script>
    var VM = new Vue({ 
        el: "#app", 
        data: { 
            food: "麻辣小龙虾" 
        },
        //通过methods ,专门存放Vue中的方法 
        methods:{ 
            show:function(){ 
                alert("程序员!") 
            },
            changeFood:function(){ 
                //使用this获取 
                console.log(this.food); 
                //在VUE中不需要考虑如何更改DOM元素, 重点放在更改数据,数据更新之后,使用数据 的那个元素会同步更新
                this.food+="真好吃!"; 
            } 
        } 
    })
</script>

</html>
  1. 计数器案例

    1. 编码步骤

      1. data中定义数据: 比如 num 值为1
      2. methods中添加两个方法: 比如add(递增) ,sub(递减)
      3. 使用{{}} 将num设置给 span标签
      4. 使用v-on 将add,sub 分别绑定给 + ,- 按钮
      5. 累加到10 停止
      6. 递减到0 停止
    2. 案例演示

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>简易计算器</title>
          <style>
             
          </style>
      </head>
      
      <body>
          <div id="app">
              <!-- 计算功能区域 -->
              <div>
                  <input type="button"  @click="add" value="+">
                  <span>{{num}}</span>
                  <input type="button"  @click="sub" value="-">
              </div>
          </div>
      
      </body>
      <script src="js/vue.min.js"></script>
      <script> 
          //创建VUE实例 
          var VM = new Vue({ 
              el:"#app", 
              data:{
                  num:1 
              },
              methods: { 
                  add:function(){ 
                      //console.log("add"); 
                      if(this.num < 10){ 
                          this.num++; 
                      }else{
                          alert("别点啦!最大了!") 
                      }
                  },
                  sub:function(){ 
                      //console.log("sub"); 
                      if(this.num > 0){ 
                          this.num--; 
                      }else{
                          alert("别点啦!最小了!") 
                      } 
                  } 
              } 
          })
      </script>
      </html >
      
    3. 案例总结
      创建VUE实例时: el(挂载点) , data(数据) , methods(方法)
      v-on 指令的作用是绑定事件,简写为 @
      方法中使用this关键字,获取data中的数据
      v-text 与 {{}} 的作用都是用来 设置元素的文本值

  2. v-show指令
    作用: v-show指令, 根据真假值,切换元素的显示状态

代码示例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-show 指令</title>
</head>

<body>
    <div id="app"> 
        <input type="button" value="切换状态" @click="changeShow" /> 
        <img v-show="isShow" src="./img/11.jpg" />
        <img v-show="age > 18" src="./img/22.jpg" /> 
    </div>
</body>
<script src="js/vue.min.js"></script>
<script>
    var VM = new Vue({ 
        el: "#app", 
        data: { 
            isShow: true, 
            age: 19, 
        },
        methods: { 
            changeShow: function () { 
                //触发方法, 对isShow进行取反 
                this.isShow = !this.isShow; 
            }, 
        }, 
    });
</script>
</html>

v-show 指令总结:

原理是修改元素的display,实现显示或者隐藏
指令后面的内容,最终会解析为 布尔值
值为true 显示, 为false 则隐藏
数据改变之后,显示的状态会同步更新
  1. v-if 指令
    作用: 根据表达值的真假,切换元素的显示和隐藏( 操纵dom 元素 )

代码示例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-if 指令</title>
</head>

<body>
    <div id="app">
        <input type="button" value="切换显示状态" @click="changeShow">
        <img v-if="isShow" src="./img/11.jpg" alt="">
    </div>
</body>
<script src="./js/vue.min.js"></script>
<script> 
    var VM = new Vue({ 
        el: "#app", 
        data: { 
            isShow: false 
        },
        methods: { 
            changeShow: function () { 
                this.isShow = !this.isShow; 
            } 
        } 
    }) 
</script>

</html>
  1. v-bind 指令
    作用: 设置元素的属性 (比如:src,title,class)

语法格式

v-bind:属性名=表达式 
<img v-bind:src="imgSrc"> 
var VM = new Vue({ 
	el:"#app", 
	data:{
		imgSrc:"图片地址" 
	} 
})
v-bind 可以省略,简写为冒号 : 
<img :src="imgSrc">

代码示例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-bind 指令</title>

    <style>
        .class01{
            width: 100px;
            height: 100px;
            background-color: blue;
        }
    </style>
    <script src="./js/vue.min.js"></script>
</head>

<body>
    <div id="app">
        <!-- 使用v-bind设置src属性值 -->
        <img v-bind:src="imgSrc" alt="" width="100px">
        <!-- 简写 设置title -->
        <img :src="imgSrc" alt="" :title="imgTitle" width="100">
        <!-- 设置class -->
        <div :style="{ fontSize: size + 'px'}">v-bind指令</div>
        <div v-bind:class="{class01:ccc}"></div>
        <!-- 简写 -->
        <div :class="c1"></div>
    </div>
</body>

<script> 
    var VM = new Vue({ 
        el: "#app", 
        data: { 
            imgSrc: "./img/11.jpg", 
            imgTitle: "我是图片标题", 
            size: 100 ,
            ccc : true,
            c1 : "class01"
        } 
    }) 
</script>

</html>

v-bind指令总结

v-bind 指令的作用是: 为元素绑定属性
完整写法 v-bind:属性名,可以简写为 :属性名
  1. v-for 指令
    作用: 根据数据生成列表结构

语法结构

<div id="app"> 
	<ul>
		<li v-for="item in arr"></li>
	</ul> 
</div> 

var VM = new Vue({ 
	el:"#app", 
	data:{
		arr:[1,2,3,4,5], 
		objArr:[ {name:"tom"}, {name:"jack"} ] 
	} 
})

代码示例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-for 指令</title>
</head>

<body>
    <div id="app"> 
        <input type="button" value="添加数据" @click="add"> 
        <input type="button" value="移除数据" @click="remove">
        <ul>
            <!-- 在li标签中获取数组元素 -->
            <li v-for="(item,index) in arr">  {{index+1 }}城市: {{item}} </li>
        </ul> 
        <!-- 使用h2标签显示 v-for 结合 v-bind一起使用 -->
        <h2 v-for="p in persons" v-bind:title="p.name"> {{p.name}} </h2>
    </div>
</body>
<script src="./js/vue.min.js"></script> 
<script> 
    var VM = new Vue({ 
        el:"#app", 
        data:{
            //普通数组 
            arr:["上海","北京","天津","杭州"], 
            //对象数组 
            persons:[ {name:"尼古拉斯·赵四"}, {name:"莱安纳多·小沈阳"} ] },
            methods: { 
                add:function(){ 
                    //push 添加 
                    this.persons.push({name:"多利安·刘能"}) 
                },
                remove:function(){ 
                    this.persons.shift();
                } 
            } 
        }) 
</script>
</html>

v-for指令总结

v-for 指令的作用: 根据数据生成列表结构
数组经常和 v-for结合使用,数组有两个常用方法:
push() 向数组末尾添加一个或多个元素
shift() 把数组中的第一个元素删除
语法是: (item,index) in 数据
item和index 可以结合其他指令一起使用
数组的长度变化,会同步更新到页面上,是响应式的
  1. v-on 指令补充
    1. 传递自定义参数 : 函数调用传参
    2. 事件修饰符: 对事件触发的方式进行限制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-on 补充</title>
</head>
<body>
    <div id="app"> 
        <!-- 函数传参 --> 
        <input type="button" value="礼物刷起来" 
        			@click="showTime(666,'爱你老铁!')" />
        <!-- 事件修饰符 指定哪些方式可以触发事件 --> 
        <input type="text" @keyup.enter="hi" /> 
    </div>
</body>
<script src="./js/vue.min.js"></script> 
<script> 
    var VM = new Vue({ 
        el: "#app", 
        data: {}, 
        methods: { 
            showTime: function (p1, p2) { 
                console.log(p1); 
                console.log(p2); 
            },
            hi: function () { 
                alert("你好吗?"); 
            }, 
        }, 
    }); 
</script>
</html>

总结

事件绑定方法,可以传入自定义参数
定义方法时,需要定义形参,来接收实际的参数
事件的后面跟上 .修饰符 可以对事件进行限制
.enter 可以限制触发的按键为回车
事件修饰符有许多 使用时可以查询文档
  1. MVVM模式
  • MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式.

  • MVVM模式将页面,分层了 M 、V、和VM ,解释为:

    • Model: 负责数据存储
    • View: 负责页面展示
    • View Model: 负责业务逻辑处理(比如Ajax请求等),对数据进行加工后交给视图展示
    <body>
    	<div id="app"> 
    		<!-- View 视图部分 --> 
    		<h2>{{name}}</h2> 
    	</div> 
    </body> 
    <script src="./js/vue.min.js"></script> 
    <script> 
    	//创建的vue实例,就是 
    	VM ViewModel var VM = new Vue({ 
    		el: "#app", 
    		//data就是MVVM模式中的 model 
    		data: { 
    			name: "hello", 
    		}, 
    	}); 
    </script>
    

    在这里插入图片描述

  • 首先,我们将上图中的DOM Listeners和Data Bindings看作两个工具,它们是实现双向绑定的关键。

    • 从View侧看,ViewModel中的DOM Listeners工具会帮我们监测页面上DOM元素的变化,如果有变化,则更改Model中的数据;
    • 从Model侧看,当我们更新Model中的数据时,Data Bindings工具会帮我们更新页面中的DOM元素。
  • MVVM的思想,主要是为了让我们的开发更加的方便,因为MVVM提供了数据的双向绑定

  1. v-mode 指令
    作用: 获取和设置表单元素的值(实现双向数据绑定)
  • 双向数据绑定
    • 单向绑定: 就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新。
    • 双向绑定: 用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。
  • 什么情况下用户可以更新View呢?
    • 填写表单就是一个最直接的例子。当用户填写表单时,View的状态就被更新了,如果此时MVVM框架可以自动更新Model的状态,那就相当于我们把Model和View做了双向绑定:

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-model</title>
</head>
<body>
    <div id="app"> 
        <input type="button" value="修改message" @click="update" /> 
        <!-- View 视图 --> 
        <!-- <input type="text" v-bind:value="message" /> --> 
        <!-- v-model 实现双向数据绑定 --> 
        <input type="text" v-model="message" /> 
        <input type="text" v-model="password" /> 
        <h2>{{message}}</h2> 
    </div>
</body>
<script src="./js/vue.min.js"></script> 
<script> 
    //VM 业务逻辑控制 
    var VM = new Vue({ 
        el: "#app", 
        //Model 数据存储 
        data: { 
            message: "admin", 
            password: 123, 
        },
        methods: { 
            update: function () { 
                this.message = "root"; 
            }, 
        },
    }); 
</script>
</html>

2.5 实现简单记事本

index.css

html,
body {
  margin: 0;
  padding: 0;
}
body {
  background: #fff ;
}
button {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: 100%;
  vertical-align: baseline;
  font-family: inherit;
  font-weight: inherit;
  color: inherit;
  -webkit-appearance: none;
  appearance: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
  line-height: 1.4em;
  background: #f1b7b7;
  color: #4d4d4d;
  min-width: 230px;
  max-width: 550px;
  margin: 0 auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-weight: 300;
}

:focus {
  outline: 0;
}

.hidden {
  display: none;
}

#app {
  background: #fff;
  margin: 180px 0 40px 0;
  position: relative;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}

#app input::-webkit-input-placeholder {
  font-style: italic;
  font-weight: 300;
  color: #e6e6e6;
}

#app input::-moz-placeholder {
  font-style: italic;
  font-weight: 300;
  color: #e6e6e6;
}

#app input::input-placeholder {
  font-style: italic;
  font-weight: 300;
  color: gray;
}

#app h1 {
  position: absolute;
  top: -160px;
  width: 100%;
  font-size: 60px;
  font-weight: 100;
  text-align: center;
  color: rgba(175, 47, 47, .8);
  -webkit-text-rendering: optimizeLegibility;
  -moz-text-rendering: optimizeLegibility;
  text-rendering: optimizeLegibility;
}

.new-todo,
.edit {
  position: relative;
  margin: 0;
  width: 100%;
  font-size: 24px;
  font-family: inherit;
  font-weight: inherit;
  line-height: 1.4em;
  border: 0;
  color: inherit;
  padding: 6px;
  border: 1px solid #999;
  box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.new-todo {
  padding: 16px;
  border: none;
  background: rgba(0, 0, 0, 0.003);
  box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
}

.main {
  position: relative;
  z-index: 2;
  border-top: 1px solid #e6e6e6;
}

.toggle-all {
  width: 1px;
  height: 1px;
  border: none; /* Mobile Safari */
  opacity: 0;
  position: absolute;
  right: 100%;
  bottom: 100%;
}

.toggle-all + label {
  width: 60px;
  height: 34px;
  font-size: 0;
  position: absolute;
  top: -52px;
  left: -13px;
  -webkit-transform: rotate(90deg);
  transform: rotate(90deg);
}

.toggle-all + label:before {
  content: "❯";
  font-size: 22px;
  color: #e6e6e6;
  padding: 10px 27px 10px 27px;
}

.toggle-all:checked + label:before {
  color: #737373;
}

.listview {
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 420px;
  overflow: auto;
}

.listview li {
  position: relative;
  font-size: 24px;
  border-bottom: 1px solid #ededed;
  height: 60px;
  box-sizing: border-box;
}

.listview li:last-child {
  border-bottom: none;
}

.listview .view .index {
  position: absolute;
  color: gray;
  left: 10px;
  top: 20px;
  font-size: 16px;
}

.listview li .toggle {
  text-align: center;
  width: 40px;
  /* auto, since non-WebKit browsers doesn't support input styling */
  height: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  margin: auto 0;
  border: none; /* Mobile Safari */
  -webkit-appearance: none;
  appearance: none;
}

.listview li .toggle {
  opacity: 0;
}

.listview li .toggle + label {
  /*
		Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
		IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
	*/
  background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center left;
}

.listview li .toggle:checked + label {
  background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E");
}

.listview li label {
  word-break: break-all;
  padding: 15px 15px 15px 60px;
  display: block;
  line-height: 1.2;
  transition: color 0.4s;
}

.listview li.completed label {
  color: #d9d9d9;
  text-decoration: line-through;
}

.listview li .destroy {
  display: none;
  position: absolute;
  top: 0;
  right: 10px;
  bottom: 0;
  width: 40px;
  height: 40px;
  margin: auto 0;
  font-size: 30px;
  color: #cc9a9a;
  margin-bottom: 11px;
  transition: color 0.2s ease-out;
}

.listview li .destroy:hover {
  color: #af5b5e;
}

.listview li .destroy:after {
  content: "×";
}

.listview li:hover .destroy {
  display: block;
}

.listview li .edit {
  display: none;
}

.listview li.editing:last-child {
  margin-bottom: -1px;
}

.footer {
  color: #777;
  padding: 10px 15px;
  height: 20px;
  text-align: center;
  border-top: 1px solid #e6e6e6;
}

.footer:before {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 50px;
  overflow: hidden;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6,
    0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6,
    0 17px 2px -6px rgba(0, 0, 0, 0.2);
}

.todo-count {
  float: left;
  text-align: left;
}

.todo-count strong {
  font-weight: 300;
}

.filters {
  margin: 0;
  padding: 0;
  list-style: none;
  position: absolute;
  right: 0;
  left: 0;
}

.filters li {
  display: inline;
}

.filters li a {
  color: inherit;
  margin: 3px;
  padding: 3px 7px;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 3px;
}

.filters li a:hover {
  border-color: rgba(175, 47, 47, 0.1);
}

.filters li a.selected {
  border-color: rgba(175, 47, 47, 0.2);
}

.clear-completed,
html .clear-completed:active {
  float: right;
  position: relative;
  line-height: 20px;
  text-decoration: none;
  cursor: pointer;
}

.clear-completed:hover {
  text-decoration: underline;
}

.info {
  margin: 50px auto 0;
  color: #bfbfbf;
  font-size: 15px;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
  text-align: center;
}

.info p {
  line-height: 1;
}

.info a {
  color: inherit;
  text-decoration: none;
  font-weight: 400;
}

.info a:hover {
  text-decoration: underline;
}

/*
	Hack to remove background from Mobile Safari.
	Can't use it globally since it destroys checkboxes in Firefox
*/
@media screen and (-webkit-min-device-pixel-ratio: 0) {
  .toggle-all,
  .listview li .toggle {
    background: none;
  }

  .listview li .toggle {
    height: 40px;
  }
}

@media (max-width: 430px) {
  .footer {
    height: 50px;
  }

  .filters {
    bottom: 10px;
  }
}

1.功能介绍
2.新增内容
步骤

  1. 生成列表结构(v-for 数组)
  2. 获取用户输入(v-model 双向绑定)
  3. 回车,新增数据(v-on .enter事件修饰符)
  4. 页面布局不熟悉,可以通过审查元素的方式快速找到元素
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单记事本</title>
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
</head>

<body>
    <!-- VUE示例接管区域 -->
    <section id="app">
        <!-- 输入框 -->
        <header class="header">
            <h1>VUE记事本</h1> <!-- v-on 绑定事件 --> 
            <input v-model="inputValue" @keyup.enter="add" autofocus="autofocus"
                autocomplete="off" placeholder="输入日程" class="new-todo" />
        </header> 
        <!-- 列表区域 -->
        <section class="main">
            <ul class="listview">
                <li class="todo" v-for="(item,index) in list">
                    <div class="view"> 
                        <span class="index">{{index+1}}</span> 
                        <label>{{item}} </label> 
                        <button class="destroy"></button> 
                    </div>
                </li>
            </ul>
        </section>
    </section>
</body>
<script src="./js/vue.min.js"></script> 
<script> 
    var VM = new Vue({ 
        el:"#app", 
        data:{
            list:["写代码","吃饭","睡觉"], 
            inputValue:"996还是997" 
        },
        methods: { 
            //新增方法 
            add:function(){ 
                //将用户输入的内容添加到list 
                this.list.push(this.inputValue); 
            }
        } 
    }) 
</script>
</html>

3.删除内容
步骤

  1. 点击删除指定的内容( 根据索引删除元素)
  2. 在methods中添加一个删除的方法,使用splice函数进行删除

代码示例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单记事本</title>
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
</head>

<body>
    <!-- VUE示例接管区域 -->
    <section id="app">
        <!-- 输入框 -->
        <header class="header">
            <h1>VUE记事本</h1> <!-- v-on 绑定事件 --> 
            <input v-model="inputValue" @keyup.enter="add" autofocus="autofocus"
                autocomplete="off" placeholder="输入日程" class="new-todo" />
        </header> 
        <!-- 列表区域 -->
        <section class="main">
            <ul class="listview">
                <li class="todo" v-for="(item,index) in list">
                    <div class="view"> 
                        <span class="index">{{index+1}}</span> 
                        <label>{{item}} </label> 
                        <!-- 删除按钮 --> 
                        <button class="destroy" @click="remove(index)"></button>
                    </div>
                </li>
            </ul>
        </section>
    </section>
</body>
<script src="./js/vue.min.js"></script> 
<script> 
    var VM = new Vue({ 
        el:"#app", 
        data:{
            list:["写代码","吃饭","睡觉"], 
            inputValue:"996还是997" 
        },
        methods: { 
            //新增方法 
            add:function(){ 
                //将用户输入的内容添加到list 
                this.list.push(this.inputValue); 
            },
            //删除方法 
            remove:function(index){ 
                console.log(index); 
                //使用splice(元素索引,删除几个) 根据索引删除 
                this.list.splice(index,1); 
            }
        } 
    }) 
</script>
</html>

4.统计操作
步骤

  1. 统计页面信息的个数,就是列表中的元素的个数.
  2. 获取 list数组的长度,就是信息的个数
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单记事本</title>
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
</head>

<body>
    <!-- VUE示例接管区域 -->
    <section id="app">
        <!-- 输入框 -->
        <header class="header">
            <h1>VUE记事本</h1> <!-- v-on 绑定事件 --> 
            <input v-model="inputValue" @keyup.enter="add" autofocus="autofocus"
                autocomplete="off" placeholder="输入日程" class="new-todo" />
        </header> 
        <!-- 列表区域 -->
        <section class="main">
            <ul class="listview">
                <li class="todo" v-for="(item,index) in list">
                    <div class="view"> 
                        <span class="index">{{index+1}}</span> 
                        <label>{{item}} </label> 
                        <!-- 删除按钮 --> 
                        <button class="destroy" @click="remove(index)"></button>
                    </div>
                </li>
            </ul>
        </section>
        <!-- 统计和清空 --> 
        <footer class="footer"> 
            <span class="todo-count"> 
                <strong>{{list.length}}</strong> items left 
            </span> 
            <button class="clear-completed"> Clear </button> 
        </footer>
    </section>
</body>
<script src="./js/vue.min.js"></script> 
<script> 
    var VM = new Vue({ 
        el:"#app", 
        data:{
            list:["写代码","吃饭","睡觉"], 
            inputValue:"996还是997" 
        },
        methods: { 
            //新增方法 
            add:function(){ 
                //将用户输入的内容添加到list 
                this.list.push(this.inputValue); 
            },
            //删除方法 
            remove:function(index){ 
                console.log(index); 
                //使用splice(元素索引,删除几个) 根据索引删除 
                this.list.splice(index,1); 
            }
        } 
    }) 
</script>
</html>

总结:

  1. 基于数据的开发方式
  2. v-text设置的是文本,可以使用简化方式 {{}}

5.清空数据
步骤:

  1. 点击清除所有信息
  2. 本质就是清空数组
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单记事本</title>
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
</head>

<body>
    <!-- VUE示例接管区域 -->
    <section id="app">
        <!-- 输入框 -->
        <header class="header">
            <h1>VUE记事本</h1> <!-- v-on 绑定事件 --> 
            <input v-model="inputValue" @keyup.enter="add" autofocus="autofocus"
                autocomplete="off" placeholder="输入日程" class="new-todo" />
        </header> 
        <!-- 列表区域 -->
        <section class="main">
            <ul class="listview">
                <li class="todo" v-for="(item,index) in list">
                    <div class="view"> 
                        <span class="index">{{index+1}}</span> 
                        <label>{{item}} </label> 
                        <!-- 删除按钮 --> 
                        <button class="destroy" @click="remove(index)"></button>
                    </div>
                </li>
            </ul>
        </section>
        <!-- 统计和清空 --> 
        <footer class="footer"> 
            <span class="todo-count"> 
                <strong>{{list.length}}</strong> items left 
            </span> 
            <button class="clear-completed" @click="clear()"> Clear </button> 
        </footer>
    </section>
</body>
<script src="./js/vue.min.js"></script> 
<script> 
    var VM = new Vue({ 
        el:"#app", 
        data:{
            list:["写代码","吃饭","睡觉"], 
            inputValue:"996还是997" 
        },
        methods: { 
            //新增方法 
            add:function(){ 
                //将用户输入的内容添加到list 
                this.list.push(this.inputValue); 
            },
            //删除方法 
            remove:function(index){ 
                console.log(index); 
                //使用splice(元素索引,删除几个) 根据索引删除 
                this.list.splice(index,1); 
            },
            //清空数组元素 
            clear:function(){ 
                this.list=[]; 
            }
        } 
    }) 
</script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

侯彦庆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值