天天看点

vue基础学习记录(一)工具准备

根据B站黑马程序员 VUE教程基础学习

为了毕业设计做准备

Vue基础

  • 工具准备
    • Vue的基本使用步骤
    • vue模板语法
      • `v-cloak`指令用法
      • 数据绑定指令
      • 数据响应式
      • 双向数据绑定
      • MVVM设计思想
      • 事件绑定
      • 事件修饰符
      • 按键修饰符
    • 案例:简单计算器
      • 属性绑定
      • 样式绑定 class
      • style样式处理
      • 分支循环结构
      • Tab选项卡
      • 常用特性
        • 表单操作
        • 自定义指令
        • 计算属性
        • 过滤器
          • 使用过滤器格式化日期
        • 侦听器
          • 侦听器案例:验证用户名是否可用
        • 生命周期
      • 图书管理
    • 组件化开发
      • 组件注册
      • 组件命名方式

工具准备

Sublime text 3*链接:Sublime text 3

提取码:5kk5

package controlpackage control

Vue的基本使用步骤

  1. 需要提供标签用于填充数据

    <div>

    容器
<div id="app">
<div>{{msg}}</div>
</div>
           

{{}}

插值表达式

2. 引入vue.js库文件

在官网上下载开发版的vue.js文件,官网地址:vue;

4. 可以使用vue的语法做功能了

提供一个变量存储vue对象

var vm = new Vue({
  el:'#app ',//告诉vue数据填充的位置,#代表id选择器
   data:{
   		msg:'Hello Vue'
  }
});
           
vue基础学习记录(一)工具准备

5. 把vue提供的数据填充到标签 ;

*[前端渲染]:

vue基础学习记录(一)工具准备

vue模板语法

指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

v-cloak

指令用法

插值表达式会出现“闪动”现象 (刷新时会出现标签之间的内容)

  1. 提供样式
[v-cloak] {
  display: none;
}
           
  1. 在插值表达式所在的标签中添加v-cloak指令

    背后原理:

    先通过样式隐藏内容,然后在内存中进行值的替换,替换好之后再显示最终值

数据绑定指令

  • v-text

    填充纯文本

    相比插值表达式更简洁

  • v-html

    填充Html片段

    存在安全问题

    本网站内部数据可以使用,来自第三方的数据不可使用

  • v-pre

    填充原始信息

    显示原始信息,跳过编译过程(分析编译过程)

<div v-text='msg'></div>
	<div v-html='msg1'></div>
	<div v-pre>{{msg}}</div>
           
vue基础学习记录(一)工具准备

数据响应式

  • html5中的响应式

    屏幕尺寸变化导致样式的变化 自适应

  • 数据的响应式

    数据的变化导致页面样式的变化

  • 数据绑定

    将数据填充到标签中

  • v-once

    只编译一次

    显示内容之后不再具有响应式功能

    如果显示的信息后续不需要再修改,可以使用,提高性能

双向数据绑定

v-model

控制台和input表单数据改变时页面内容也改变

MVVM设计思想

  • M(model)
  • V(view)
  • VM(view-model)
    vue基础学习记录(一)工具准备

事件绑定

事件处理:

v-on

指令

  • 用法:

    v-on:click

  • 简写:

    @click

    事件函数调用方式
  • 直接绑定函数名称调用:

    v-on:click='函数名'

    如果事件直接绑定函数名称,那么默认会传递事件对象作为事件的第一个参数
  • 调用函数:

    v-on:click='say()'

    如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象必须是

    $event

    事件函数参数传递
  • 普通参数传参对象

    $event

    接收事件对象,function括号中不加美元符

    event.target.tagName

    事件标签名称

    event.target.innerHTML

    事件内容
    vue基础学习记录(一)工具准备

事件修饰符

  • stop

    阻止冒泡

    冒泡:里层出发的事件会传递到外层,并触发外层事件

  • prevent

    阻止默认行为,如跳转
  • 阻止冒泡函数

    event.stopPropagation()‘

  • 阻止默认行为

    event.preventDefault()‘

按键修饰符

按键后触发事件函数

  • enter

    回车键

    v-on:keyup.enter

  • delete

    删除键

    v-on:keyup.delete

  • 自定义按键修饰符

    全局

    config.keyCodes

    对象

案例:简单计算器

vue基础学习记录(一)工具准备
  1. 通过v-model指令实现数值a和数值b的绑定
  2. 给计算按钮绑定事件,实现计算逻辑
  3. 将计算结果绑定到对应位置
<!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">
		<h1>简单计算器</h1>
		<div>
			<span>数值A:</span>
			<span>
				<input type="text" v-model='a'>
			</span>
		</div>
		<div>
			<span>数值B:</span>
			<span>
				<input type="text" v-model='b'>
			</span>
		</div>
		<div>
			<button v-on:click="handle">计算</button>
		</div>
		<div>
			<span>计算结果:</span>
			<span v-text="result"></span>
		</div>
	</div>
	<script type="text/javascript" src="js/vue.js"></script>
	<script type="text/javascript">
		
		var vm = new Vue({
			el:'#app',
			data:{
				a:'',
				b:'',
				result:''
			},
			methods:{
				handle:function(){
					//实现计算逻辑
					this.result = parseInt(this.a) + parseInt(this.b);
					//this.a 和 this.b中得到的是字符串,默认字符串拼接,所以要强制转换
				}

			}
		});

	</script>
</body>
</html>
           
vue基础学习记录(一)工具准备

属性绑定

  • v-bind

    vue基础学习记录(一)工具准备
    双向数据绑定

    v-model

    的低层实现原理分析
    vue基础学习记录(一)工具准备
    三种实现效果相同

样式绑定 class

  1. 对象绑定和数组绑定可以结合使用
  2. Class绑定的值可以简化操作 放在data中的数组或者对象集合
vue基础学习记录(一)工具准备

style样式处理

vue基础学习记录(一)工具准备

分支循环结构

  • v-if

  • v-else

  • v-else-if

  • v-show

v-if 和 v-show 的区别

  • v-if 控制元素是否渲染到页面
  • v-show 控制元素是否显示(已经渲染到了页面)

循环结构

v-for

vue基础学习记录(一)工具准备
vue基础学习记录(一)工具准备

Tab选项卡

最重要的是用

currentIndex

进行判断

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style type="text/css">
		.tab ul{
			overflow: hidden;
			padding: 0;
			margin: 0;
		}
		.tab ul li{
			box-sizing: border-box;;
			padding: 0;
			float: left;
			width: 100px;
			height: 45px;
			line-height: 45px;
			list-style: none;
			text-align: center;
			border-top: 1px solid blue;
			border-right: 1px solid blue;
			cursor: pointer;
		}
		.tab ul li:first-child{
			border-left: 1px solid blue;
		}
		.tab ul li.active{
			background-color:  orange;
		}
		.tab div{
			width: 500px;
			height: 300px;
			display: none;
			text-align: center;
			font-size: 30px;
			line-height: 300px;
			border: 1px solid blue;
			}
			.tab div.current{
				display:block;
			}
	</style>
</head>
<body>
	<div id="app">
		<div class="tab">
		<ul>
			<li v-on:click='change(index)' :class='currentIndex==index?"active":""' :key='item.id' v-for='(item,index) in list'>{{item.title}}</li>
		</ul>
		<div :class='currentIndex==index?"current":""'  :key='item.id' v-for='(item,index) in list'>
			<img :src="item.path">
		</div>
	</div>

</div>
	<script type="text/javascript" src="js/vue.js"></script>
	<script type="text/javascript">
		var vm = new Vue({
			el:'#app',
			data:{
				currentIndex: 0,//选项卡当前的索引
				list:[{
					id: 1,
					title:'apple',
					path:'img/apple.jpg'
				},{
					id: 2,
					title:'orange',
					path:'img/orange.jpg'
				},{
					id: 3,
					title:'lemon',
					path:'img/lemon.jpg'
				}]
			},
			methods:{
				change:function(index){
					//在这里实现选项卡切换操作
					//通过currentIndex操作类名
					this.currentIndex = index;
				}
			}
		});
	</script>
</body>
</html>
           

常用特性

表单操作

  • Input 单行文本
  • textarea 多行文本
  • select 下拉多选
  • radio 单选框
  • checkbox 多选框

表单域修饰符

  • number 转化为数值 不再需要强制转换
  • trim 去掉开始和结尾的空格
  • lazy 将input事件转换为change事件 Input每次输入触发,change每次失去焦点触发(常用于注册用户名验证重复)
    vue基础学习记录(一)工具准备

自定义指令

第一个参数:指令名称

第二个参数,实现逻辑 el表示指令所绑定的元素

vue基础学习记录(一)工具准备

使用时候 v-focus

vue基础学习记录(一)工具准备

计算属性

vue基础学习记录(一)工具准备

插值表达式里直接写函数名,不需要加()

基于data中的值进行处理

<!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">
		<div>{{msg}}</div>
		<div>{{reverseString}}</div>
	</div>

	<script type="text/javascript" src="js/vue.js"></script>
	<script type="text/javascript">
		
		var vm = new Vue({
			el:'#app',
			data:{
				msg:'Hello'
			},
			computed:{
				reverseString:function(){
					return this.msg.split('').reverse().join('');
				}
			}
		})
	</script>
</body>
</html>
           

计算属性与方法的区别

  • 计算属性基于它们的依赖进行缓存的(依赖:data中数据)
  • 方法不存在缓存
  • 方法要加括号,计算属性直接用名称不用加括号
  • 方法可以传参,计算属性不行

过滤器

格式化数据,比如字符串格式化为首字母大写,将日期格式化为指定的格等。

vue基础学习记录(一)工具准备

自定义过滤器可以全局使用

vue基础学习记录(一)工具准备

参数级联使用,上一个参数的返回值作为下一个参数的输入值

计算属性不能连续使用,过滤器可以

vue基础学习记录(一)工具准备

定义在Vue里,只有在本组件中使用

vue基础学习记录(一)工具准备

带参数的过滤器,使用时format接收的参数是从第二个参数开始,第一个参数默认为

data

使用过滤器格式化日期

将时间格式化为yyyy-MM-dd格式

vue基础学习记录(一)工具准备

侦听器

数据变化时执行异步或开销较大的操作

vue基础学习记录(一)工具准备
vue基础学习记录(一)工具准备
侦听器案例:验证用户名是否可用

需求:输入框中输入姓名,失去焦点时验证是否存在,如果已经存在,提示重新输入;如果不存在,提示可以使用。

  1. 通过v-model实现数据绑定
  2. 需要提供提示信息
  3. 需要侦听器监听输入信息的变化

    采用侦听器监听用户名的变化

    调用后台接口进行验证

    根据验证的结果调整提示信息

  4. 需要修改触发事件

    v-model.lazy

<!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">
		<div>
			<span>用户名:</span>
			<span> <input type="text" v-model.lazy='uname'>
			</span>
			<span>{{tip}}</span>
		</div>
	</div>

	<script type="text/javascript" src="js/vue.js"></script>
	<script type="text/javascript">
		var vm = new Vue({
			el:'#app',
			data:{
				uname:'',
				tip:''
			},
			methods:{
				checkName:function(uname){
					//调用接口,可以选用定时任务的方式模拟接口调用
					var that = this;//所以先用that缓存this
					setTimeout(function(){
						//模拟接口调用
						//setTimeout中的this是windows
						if(uname == 'admin'){
							that.tip = '用户名已经存在,请更换一个'
						}else{
							that.tip = '用户名可以使用'
						}
					},2000);
				}
			},
			watch:{
				uname:function(val){
					//调用后台接口验证用户名的合法性
					this.checkName(val);
					//修改提示信息
					this.tip = '正在验证……';
				}
			},
		});
	</script>
</body>
</html>
           

生命周期

主要阶段

vue基础学习记录(一)工具准备
vue基础学习记录(一)工具准备

图书管理

vue基础学习记录(一)工具准备
vue基础学习记录(一)工具准备

替换数组返回值一般要赋值给新数组

使用索引修改的数组数据不会显示在页面,响应式

但是使用索引修改的对象数据可以显示在页面,非响应式,控制台修改数据页面也不变化

修改响应式数据可以用于修改数组和对象数据

vue基础学习记录(一)工具准备

图书列表

  • 实现静态列表效果
  • 基于数据实现模板效果
  • 处理每行的操作按钮

添加图书

  • 实现表单静态效果
  • 添加图书表单域数据绑定
  • 添加按钮事件绑定
  • 实现添加业务逻辑

修改图书

  • 修改信息填充到表单
  • 修改后重新提交表单
  • 重用添加和修改方法

删除图书

  • 删除按钮绑定事件处理方法
  • 实现删除业务逻辑

箭头函数中的

this

等于定义该函数的父级作用域中的

this

初始表格页面

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style type="text/css">
		.grid{
			margin:auto;
			width: 500px;
			text-align: center;
		}
		.grid table{
			width: 100%;
			border-collapse: collapse;
		}
		.grid th,td{
			padding: 10;
			border: 1px dashed orange;
			height: 35px;
			line-height: 35px;
		}
		.grid th{
			background-color: orange;
		}
		.grid .book{
			padding-bottom:10px;
			padding-top:5px;
			background-color: #F3DCAB;
		}
	</style>
</head>
<body>
	<div id="app">
		<div class="grid">
		<div>
				<h1>图书管理</h1>
				<div class="book">
					<div>
						<label for="id">编号</label>
						<input type="text" id="id">
						<label for="name">名称</label>
						<input type="text" id="name">
						<button>提交</button>
					</div>
				</div>
			</div>
			<table>
				<thead>
					<tr>
						<th>编号</th>
						<th>名称</th>
						<th>时间</th>
						<th>操作</th>
					</tr>
				</thead>
				<tbody>
					<tr>
						<td>1</td>
						<td>JavaScript</td>
						<td>2018-01-01</td>
						<td>删除</td>
					</tr>
					<tr>
						<td>1</td>
						<td>JavaScript</td>
						<td>2018-01-01</td>
						<td>删除</td>
					</tr>
					<tr>
						<td>1</td>
						<td>JavaScript</td>
						<td>2018-01-01</td>
						<td>删除</td>
					</tr>
				</tbody>
			</table>
		</div>
	</div>

	<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">

			var vm = new Vue({
				el:'#app',
				data:{
					id:'',
					name:'',
					books:[{
						id: 1,
						name: '三国演义',
						date: ''
					},{
						id: 2,
						name: '水浒传',
						date: ''
					},{
						id: 3,
						name: '红楼梦',
						date: ''
					},{
						id: 4,
						name: '西游记',
						date: ''
					}]
				},
				
			
		});
	</script>
	
</body>
</html>
           
vue基础学习记录(一)工具准备

完整

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style type="text/css">
		.grid{
			margin:auto;
			width: 500px;
			text-align: center;
		}
		.grid table{
			width: 100%;
			border-collapse: collapse;
		}
		.grid th,td{
			padding: 10;
			border: 1px dashed orange;
			height: 35px;
			line-height: 35px;
		}
		.grid th{
			background-color: orange;
		}
		.grid .book{
			padding-bottom:10px;
			padding-top:5px;
			background-color: #F3DCAB;
		}
		.grid .total{
			height: 30px;
			line-height: 30px;
			background-color: #F3DCAB;
			border-top: 1px solid #C2D89A;
		}
	</style>
</head>
<body>
	<div id="app">
		<div class="grid">
			<div>
				<h1>图书管理</h1>
				<div class="book">
					<div>
						<label for="id">编号</label>
						<input type="text" id="id" v-model="id" :disabled="flag">
						<label for="name">名称</label>
						<input type="text" id="name" v-model="name">
						<button @click="handle" disabled="submitFlag">提交</button>
					</div>
				</div>
			</div>
			<div class="total">
				<span>图书总数:</span>
				<span>{{total}}</span>
			</div>
			<table>
				<thead>
					<tr>
						<th>编号</th>
						<th>名称</th>
						<th>时间</th>
						<th>操作</th>
					</tr>
				</thead>
				<tbody>
					<tr :key='item.id' v-for='item in books'>
						<td>{{item.id}}</td>
						<td>{{item.name}}</td>
						<td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
						<td>
							<a href="" @click.prevent='toEdit(item.id)'>修改</a>
							<!---禁止a标签的默认行为,不会跳转--->
							<span></span>
							<a href="" @click.prevent='deleteBook(item.id)'>删除</a>
						</td>
					</tr>
				</tbody>
			</table>
		</div>
	</div>

	<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript">

			Vue.directive('focus', {
		      inserted: function (el) {
		        el.focus();
		      }
		    });
		    Vue.filter('format', function(value, arg) {
		      function dateFormat(date, format) {
		        if (typeof date === "string") {
		          var mts = date.match(/(\/Date\((\d+)\)\/)/);
		          if (mts && mts.length >= 3) {
		            date = parseInt(mts[2]);
		          }
		        }
		        date = new Date(date);
		        if (!date || date.toUTCString() == "Invalid Date") {
		          return "";
		        }
		        var map = {
		          "M": date.getMonth() + 1, //月份 
		          "d": date.getDate(), //日 
		          "h": date.getHours(), //小时 
		          "m": date.getMinutes(), //分 
		          "s": date.getSeconds(), //秒 
		          "q": Math.floor((date.getMonth() + 3) / 3), //季度 
		          "S": date.getMilliseconds() //毫秒 
		        };
		        format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
		          var v = map[t];
		          if (v !== undefined) {
		            if (all.length > 1) {
		              v = '0' + v;
		              v = v.substr(v.length - 2);
		            }
		            return v;
		          } else if (t === 'y') {
		            return (date.getFullYear() + '').substr(4 - all.length);
		          }
		          return all;
		        });
		        return format;
		      }
		      return dateFormat(value, arg);
		    })

			var vm = new Vue({
				el:'#app',
				data:{
					flag: false,
					submitFlag: false,
					id:'',
					name:'',
					books:[]
				},
				methods:{
					handle:function(){
						if(this.flag == true){
							//编辑操作
							//根据当前的id去更新数组中对应的数据
							this.books.some((item) => {
									if(item.id == this){
										item.name = this.name;
										//完成更新操作后,需要终止循环
										return true;
									}
							});
							this.flag = false;
						}else{
							//添加图书
							var book = {};
							book.id = this.id;
							book.name = this.name;
							book.date = '';
							this.books.push(book);
							//清空表单
							this.id = '';
							this.name = '';
						}
						//提交成功后清空表单
						this.id = '';
						this.name = '';
					},
					toEdit:function(id){
						//禁止修改id
						this.flag = true;
						console.log(id)
						//根据id查询要编辑的数据
						var book = this.books.filter(function(item){
							return item.id == id;
						});

						console.log(book)
						//把获取到的信息填充到表单
						this.id = book[0].id;
						this.name = book[0].name;
					},
					deleteBook:function(id){
						//删除图书
						//根据id从数组中查找元素索引
						var index = this.books.findIndex(function(item){
							return item.id == id;
						});
						//根据索引删除数组元素
						this.books.splice(index,1);
						//方法二:
						//通过filter方法进行删除
						//排除要删除的剩下就是删除后的内容,所以判断返回id不相等的那部分就是删除后的内容
						//this.books = this.books.filter(function(item){
						//return item.id != id;
						//});
						}
				},
				computed: {
			        total: function(){
			          // 计算图书的总数
			          return this.books.length;
			        }
			      },
			      watch: {
			        name: function(val) {
			          // 验证图书名称是否已经存在
			          var flag = this.books.some(function(item){
			            return item.name == val;
			          });
			          if(flag) {
			            // 图书名称存在
			            this.submitFlag = true;
			          }else{
			            // 图书名称不存在
			            this.submitFlag = false;
			          }
			        }
			      },
				 mounted: function(){
			        // 该生命周期钩子函数被触发的时候,模板已经可以使用
			        // 一般此时用于获取后台数据,然后把数据填充到模板
			        var data = [{
			          id: 1,
			          name: '三国演义',
			          date: 2525609975000
			        },{
			          id: 2,
			          name: '水浒传',
			          date: 2525609975000
			        },{
			          id: 3,
			          name: '红楼梦',
			          date: 2525609975000
			        },{
			          id: 4,
			          name: '西游记',
			          date: 2525609975000
			        }];
			        this.books = data;
			      }
							
			
		});
	</script>
	
</body>
</html>
           

组件化开发

组件注册

vue基础学习记录(一)工具准备
vue基础学习记录(一)工具准备

名称有要求

数据通过return返回值,每个组件数据独立

vue基础学习记录(一)工具准备

局部组件只能在注册他的父组件中使用

组件命名方式

vue基础学习记录(一)工具准备

如果使用驼峰式命名组件,在使用组件时候,只能在字符串模板中用驼峰的方式使用

继续阅读