前端学习笔记(八)前端框架之vue基础

引言

静态页面

最初的网页以HTML为主,是纯静态网页,网页是只读的,信息流只能从服务端到客户端单项流通,开发人员也只关心页面的样式和显示内容。

异步刷新

1995年,网景工程师Brendan Eich 花了10天时间设计了JavaScript语言。
随着JavaScript的诞生,我们可以操作页面的DOM元素及样式,页面有了一些动态的效果,但是依然是以静态为主

ajax横空出世

和Ajax的巨大影响力相比,它的历史却简短得多, 2005年2月,Adaptive Path公司的Jesse James Garrett最早提出这个概念,它出现在Garrett的文章"Ajax:A new approach to Web Applications"中,这篇文章描述了混合使用XHTML,CSS,javascript,DOM,XMLHttpRequst进行Web开发将会成为一种新的趋势。2005之后,ajax逐渐被前端开发人员所重视,因为不用刷新页面就可以更新页面的数据和渲染效果。
此时的开发人员不仅仅要编写HTML样式,还要懂ajax与后端交互,然后通过JS操作Dom元素来实现页面动态效果。比较流行的框架如jQuery就是典型代表。

MVVM,关注模型和视图

什么是MVVM

M:即Model,模型,包括数据和一些基本操作
V:即View,视图,页面渲染结果
VM:即View-Model,模型与视图间的双向操作(无需开发人员干涉)

在MVVM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到View中。而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中。而MVVM中的VM要做的事情就是把DOM操作完全封装起来,开发人员不用再关心Model和View之间是如何互相影响:

  1. 只要Model发生了改变,View上自然就会表现出来。
  2. 当用户修改了View,Model中的数据也会跟着改变。

把开发人员从繁琐的DOM操作中解放出来,把关注点放在如何操作Model上。
在这里插入图片描述

MVVM 的发展

2008年,google的Chrome发布,随后就以极快的速度占领市场,超过IE成为浏览器市场的主导者。

2009年,Ryan Dahl在谷歌的Chrome V8引擎基础上,打造了基于事件循环的异步IO框架:Node.js。基于时间循环的异步IO单线程运行,避免多线程的变量同步问题JS可以编写后台diamante,前后台统一编程语言node.js的伟大之处不在于让JS迈向了后端开发,而是构建了一个庞大的生态系统。

2010年,NPM作为node.js的包管理系统首次发布,开发人员可以遵循Common.js规范来编写Node.js模块,然后发布到NPM上供其他开发人员使用。目前已经是世界最大的包模块管理系统。

而后在node基础上又涌现出一大批框架
在这里插入图片描述
vue作为国内优秀的前端框架之一,小猿非常乐意去学习并掌握它。

vue

vue的概述

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

前端框架三巨头:Vue.js、React.js、AngularJS,vue.js以其轻量易用著称,vue.js和React.js发展速度最快。

渐进式:可以选择性的使用该框架的一个或一些组件,这些组件的使用也不需要将框架全部组件都应用;而且用了这些组件也不要求你的系统全部都使用该框架。

vue所解决的问题

在这里插入图片描述
vue 所解决问题的本质是将赋值部分和逻辑部分进行分离,既做到m和v分离并实现双向操作。

vue的基本操作

使用vue就需要导入vue基础js文件。
在这里插入图片描述

插值表达式

数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值,Mustache 标签将会被替代为对应数据对象上属性的值。无论何时,绑定的数据对象上属性发生了改变,插值处的内容都会更新。

 <!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>quickstart</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>
	<body>
		<div id="app">
			{{message}}
			{{number+1}}
			{{true? "yes":"no"}}
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el:"#app", //有vue接管id为app的数据区域
			data:{
				message:"hello vue!!!", // 处处不要加分号
				number: 1000
			}
		});
	</script>
</html>   

插值表达式属 Vue 实例的数据作用域下作为 JavaScript 会被解析器被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}
vuejs常用的指令
v-on

v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码

v-on:click
<!DOCTYPE html>
		<meta charset="utf-8" />
		<title>v-on:click</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>
	<body>
		<div id="app">
			{{message}}  
			<button  v-on:click="fun1('vue-on')" >vue的onclick</button>
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el:"#app", //有vue接管id为app的数据区域
			data:{
				message:"hello vue!!!", // 处处不要加分号
				number: 1000
			},
			methods:{
				fun1:function (message) {
					alert("hello vue!!!");
					this.message = message;
				}
			}
		});
		
	</script>
</html> 
v-on:keydown

检测按键事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>v-on:keydown</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>
	<body>
		<div id="app">
			{{message}}
			{{number+1}}
			<input type="text" v-on:keydown="fun($event)">
			<hr/>
			traditional<input type="text" onkeydown="showKeyCode()" >
		</div>
	</body>
	<script>
		//view model
		//$event为vue中的事件对象,与传统对象中的event对象一致
		new Vue({
			el: "#app",
			data:{
				message: "vue Input",
				number: 1000
			},
			methods: {
				fun(event){
					var keyCode = event.keyCode;
					if(keyCode<48 || keyCode>57){
						event.preventDefault();
					}
				}
			}
		})
		//传统js代码
		function showKeyCode() {
			var keyCode = event.keyCode;
			if(keyCode<48 || keyCode>57){
				event.preventDefault();
			}
		}
	</script>
</html>
v-on:mouseover

鼠标移入事件

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title>v-on:mouseover</title>
		<style>
			#div ,#div2 {
				background-color: red;
				width: 400px;
				height: 300px;
			}
		</style>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>

	<body>
		<div id="app">
			<div @mouseover="fun1" id="div">
				<textarea @mouseover="fun2($event)">这是一vue个文件域</textarea>
			</div>
		</div>
		<hr/>
		<hr/>
		<hr/>
		<hr/>

		<div  >
			<div onmouseover="fun3()"  id="div2" >
				<textarea onmouseover="fun4()">这是一个传统文件域</textarea>
			</div>
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el: "#app",
			data:{
				message: "vue Input",
				number: 1000
			},
			methods: {
				fun1:function(){
					alert("这是vueDIV域!!!");
				},
				fun2:function(event){
					alert("这是vue文件域!!!");
					event.stopPropagation();
				}
			}
		});
		//传统方法
		function fun3(){
			alert("这是传统DIV域!!!");
		}
		function fun4() {
			alert("这是传统文件域!!!");
			event.stopPropagation();
		}
	</script>
</html>
v-on书写形式
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
事件修饰符

Vue 允许为 v-on 在监听键盘事件时添加按键修饰符,事件修饰符有以下种类

.enter
.tab
.delete (捕获 "删除""退格")
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta

下面是示例代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>v-on:事件修饰符</title>
		<style>
			#div ,#div2 {
				background-color: red;
				width: 400px;
				height: 300px;
			}
		</style>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>
	<body>
	<form action="http://www.baidu.com" onsubmit="return checkform()">
		<input type="submit" value="Go">
	</form>
	<br/>
	<br/><br/>
	<br/>
		<div id="app">
		<!--典型的事件修饰符,所对应的事件是prevent-->
			<form  v-on:submit.prevent action="http://www.baidu.com" >
				<input type="submit" value="Go">
			</form>
			<br/>
			<br/>
			<div @click="fun">
				<a  @click.stop href="http://www.baidu.com">BAIDU</a>
			</div>
			<br/>
			<br/>
			<br/>
			<div >
			<!--典型的事件修饰符,所对应的事件是stop-->
				<div @mouseover="fun1" id="div">
					<textarea @mouseover.stop="fun2($event)">这是一vue个文件域</textarea>
				</div>
			</div>

		</div>
	</body>
	<script>
		//view model
		function checkform() {
			return false;
		}

		new Vue({
			el: "#app",
			data:{
				message: "vue Input",
				number: 1000
			},
			methods: {
				fun1:function(){
					alert("这是vueDIV域!!!");
				},
				fun2:function(event){
					alert("这是vue文件域!!!");
					/*event.stopPropagation();*/
				},
				fun:function () {
					alert("www.baidu.com");
				}
			}
		});
	</script>
</html>
v-text与v-html
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>v-text与v-html</title>
		<script src="js/vuejs-2.5.16.js"></script>
	</head>
	<body>
		<div id="app">
			<div v-html="message" id="div1"></div>
			<div v-text="message"  id="div2"></div>
		</div>

		<div   id="div3"></div>
		<div id="div4"></div>

	</body>
	<script>
		//view model
		new Vue({
			el: "#app",
			data:{
				message: "hello python",
				number: 1000
			}
		});
		window.onload=function () {
			document.getElementById("div3").innerHTML="<h1>hello python</h1>";
			document.getElementById("div4").innerText="<h1>hello python</h1>";
		}
	</script>
</html>

v-text与v-html 的区别
在这里插入图片描述

v-bind

插值语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind指令。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>v-if and v-show</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>
	<body>
		<div id="app">
			<font :size="size1"  v-bind:color="yl1"  v-if="flag"  >小猿</font><br/>
			<font v-bind:size="size2"  :color="yl2" v-show="flag" >加油学习</font><br/>
			<button  @click="toggle">button</button>
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el: "#app",
			data: {
				yl1: "green",
				yl2: 'red',
				size1: 5,
				size2: 10,
				flag : true
			},
			methods: {
				toggle: function () {
					this.flag = !this.flag;
				}
			}
		});
		
	</script>
</html>
v-bind书写方式
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
v-model

v-model指令实现复选框的双向绑定

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title>v-text与v-html在v-bind上的使用</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>

	<body>
		<div id="app">
			<form action="www.baidu.com" method="get">
				<input type="text" name="username" v-model="user.username" /><br/>
				<input type="text" name="password" v-model="user.password"/><br/>
				<input type="submit" value="submit" class="button" >
			</form>
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el: "#app",
			data:{
				user:{
					username: "feitian",
					password: "123456"
				}
			}
		});
	</script>
</html>
v-for

遍历数组

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>v-for遍历对象</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>
	<body>
		<div id="app">
			<ul>
				<li v-for="(item,index) in array"  >{{index}} :{{item}}</li>
			</ul>
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el: "#app",
			data: {
				array: [1,2,3,4,5]
			},
			methods: {
			}
		});
	</script>
</html>

遍历对象内容

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>v-for</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>
	<body>
		<div id="app">
			<ul>
				<li v-for="(key,value) in product" >{{key}}:{{value}}</li>
			</ul>
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el: "#app",
			data: {
				product: {
					id: 12,
					name: "server",
					price: 100000
				}
			},
			methods: {
			}
		});
	</script>
</html>

遍历对象数据

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title>v-for遍历对象</title>
		<script src="../js/vuejs-2.5.16.js"></script>
	</head>

	<body>
		<div id="app">
			<table border="1">
				<tr>
					<td>序号号</td>
					<td>编号</td>
					<td>名称</td>
					<td>价格</td>
				</tr>
				<tr v-for="(product,index) in products" >
					<td>{{index}}</td>
					<td >{{product.id}}</td>
					<td>{{product.name}}</td>
					<td>{{product.price}}</td>
				</tr>
				
			</table>
		</div>
	</body>
	<script>
		//view model
		new Vue({
			el: "#app",
			data: {
				products: [{id: 12, name: "server", price: 100000},
					{id: 14, name: "mobile", price: 3000},
					{id: 18, name: "television", price: 2000},
					{id: 17, name: "router", price: 300},
					{id: 10, name: "printer", price: 2900},]
			},
			methods: {
			}
		});
		
	</script>

</html>

vue计算属性

computed计算属性的应用场景:可以应用在插值或者指令表示式复杂的时候。可以将一些属性数据经过方法处理之后返回,这样就可以在某些地方
替代插值表达式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuejs测试</title>
    <script src="../js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
    <h2>
        你的生日是:
        {{new Date(birthday).getFullYear()}}-{{new Date(birthday).getMonth()+1}}-{{new Date(birthday).getDay()}}
    </h2>
    <hr>
    <h2>
        你的生日是:
        {{birth}}
    </h2>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            birthday:1429032123201
        },
        computed:{
            birth(){
                const date = new Date(this.birthday);
                return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDay();
            }
        }
    });
</script>
</body>
</html>

vue watch

在vue实例中数据属性;因为在页面中修改而产生了变化;可以通过watch监控获取其改变前后的值。如果是修改的对象数据属性,可以开启深度监控获取修改后最新的对象数据。如:person.name。

watch使用场景:可以监控视图中数据的变化而做出响应;如:下拉框列表中,当如果选择了对于的下拉框选项之后,要根据最新的值去加载一些其它数据的话。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuejs测试</title>
    <script src="../js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model="message">
    <hr><br>
    <input type="text" v-model="person.name"><br>
    <input type="text" v-model="person.age"><button @click="person.age++">+</button>
    <h2>
        姓名为:{{person.name}};年龄为:{{person.age}}
    </h2>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            message:"黑马",
            person:{"name":"heima", "age":13}
        },
        watch:{
            message(newValue, oldValue){
                console.log("新值:" + newValue + ";旧值:" + oldValue);
            },
            person: {
                //开启深度监控;监控对象中的属性值变化
                deep: true,
                //可以获取到最新的对象属性数据
                handler(obj){
                    console.log("name = " + obj.name + "; age=" + obj.age);
                }
            }
        }
    });
</script>
</body>
</html>

vue 组件

在项目往往需要重用某个模块(头部、尾部、新闻。。。)的时候,可以将模块抽取成组件,其它页面中注册组件并引用。

小案例quickstart

小栗子是通过局部注册组件完成组件的使用,但在小栗子中加入了全局注册方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuejs测试</title>
    <script src="../js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
    <!--使用组件-->
    <mycounter></mycounter>
    <counter></counter>
    <counter></counter>
    <counter></counter>

</div>
<script type="text/javascript">
    //定义全局组件
    Vue.component("mycounter",{
        template:'<button v-on:click="count++">你点了我 {{ count }} 次,我记住了.</button>',
        data(){
            return {count:0}
        }
    });


    //定义局部组件
    const counter = {
        template:"<button @click='num++'>你点击了{{num}}次</button>",
        data(){
            return {num:0}
        }
    };
    //全局注册组件:在所有的vue实例中都可以使用组件
    //参数1:组件名称,参数2:具体的组件
    //Vue.component("counter", counter);
    var app = new Vue({
        el:"#app",
        components:{
            //为K:V 形式
            counter: counter
        }
    });
</script>
</body>
</html>
父组件将字符串更新传递到子组件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuejs测试</title>
    <script src="../js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
    <!--使用组件-->
    <introduce :title="msg"></introduce>
</div>
<script type="text/javascript">

    //定义组件
    const introduce = {
        template:"<h2>{{title}}</h2>",
        //定义接收父组件的属性
        props:["title"]
    };

    //全局注册组件:在所有的vue实例中都可以使用组件
    //参数1:组件名称,参数2:具体的组件
    Vue.component("introduce", introduce);

    var app = new Vue({
        el:"#app",
        data:{
            msg:"父组件的msg属性数据内容"
        }
    });
</script>
</body>
</html>
父组件将数组更新传递到子组件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuejs测试</title>
    <script src="../js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
    <!--使用组件-->
    <my-list :items="lessons" ></my-list>
</div>
<script type="text/javascript">

    //定义组件
    const myList = {
        template:`
            <ul>
            <li v-for="item in items" :key="item.id">{{item.id}}--{{item.name}}</li>
</ul>
        `,
        //定义接收父组件的属性
        props:{
            items:{
                //数据类型,如果是数组则是Array,如果是对象则是Object
                type:Array,
                //默认值
                default:[]
            }
        }
    };

    var app = new Vue({
        el:"#app",
        data:{
            msg:"父组件的msg属性数据内容",
            lessons:[
                {"id":1, "name":"Java"},
                {"id":2, "name":"c++"},
                {"id":3, "name":"python"}
            ]
        },
        components:{
            myList
        }
    });
</script>
</body>
</html>
在子组件中点击对应按钮实现父组件中数据的改变
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuejs测试</title>
    <script src="../js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
    <h2>num = {{num}}</h2>
    <!--使用组件-->
    <counter @plus="numPlus" @reduce="numReduce" :snum="num"></counter>
</div>
<script type="text/javascript">
    //定义组件
    const counter = {
        template:`
            <div>
            <button @click='incrNum'>+</button>
            <button @click='decrNum'>-</button>
            </div>
        `,
        props:["snum"],
        methods:{
            //递增
            incrNum(){
                //调用到父组件中的方法
                return this.$emit("plus");
            },
            decrNum(){
                //调用到父组件中的方法
                return this.$emit("reduce");
            }
        }
    };
    //全局注册组件:在所有的vue实例中都可以使用组件
    //参数1:组件名称,参数2:具体的组件
    //Vue.component("counter", counter);
    var app = new Vue({
        el:"#app",
        components:{
            counter: counter
        },
        data:{
            num:0
        },
        methods:{
            numPlus(){
                this.num++;
            },
            numReduce(){
                this.num--;
            }
        }
    });
</script>
</body>
</html>

本小结的vue的基础知识就回顾到这里,下一节开始复习vue的异步请求操作和有关vue生命周期的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值