Vue 起步(一)

                                                     Vue 起步

Vue 作为MVVM框架,极大的减少了 对 dom 元素的操作。

一、数据的双向绑定,2s之后hello vue 变为 bye vue

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">{{message}}</div>
		<script type="text/javascript">
			var app = new Vue({
				el: '#app',
				data: {
				     message: 'hello Vue'
				}
			});
			setTimeout(function(){
				 app.$data.message='bye world';
			},2000)
		</script>
	</body>
</html>

二、利用jquery 实现传统的 todolist  demo

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>todolist jquery</title>
		<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
	</head>
	<body>
		<div>
			<input id="input" type="text" />
			<button id="btn">提交</button>
			<ul id="list"></ul>
		</div>
		<script>
			//m v p 设计模式,很多时候都是在操作dom,面向dom开发
			function Page() {
			}
			$.extend(Page.prototype, {
				init: function() {
					this.bindEvents();
				},
				bindEvents: function() {
					var btn = $("#btn");
					btn.on("click", $.proxy(this.handleBtnClick, this))
				},
				handleBtnClick: function() {
					//alert('123');
					//获取input输入框的值
					var input = $("#input");
					var inputValue = input.val();
					//获取ul元素
					var ul = $("#list");
					//构造li ,将li添加到ul中国
					ul.append("<li>" + inputValue + "</li>");
					input.val('');	
				}
			});
			var page = new Page();
			page.init();
		</script>
	</body>

</html>

三、使用vue 实现 todolist  demo

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>TodoList</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>

	<body>

		<div id="app">
			<!-- v-model 双向绑定 -->
			<input type="text" v-model="inputValue" />
			<!--
           	作者:offline
           	时间:2019-03-22
           	描述:v-on 绑定一个事件
           -->
			<button v-on:click="handleBtnClick">提交</button>

			<ul>
				<!--	<li>第一课的内容</li>
		     	<li>第二课的内容</li>-->
				<!--<li v-for="item in list">{{item}}</li>-->

				<!--1.父组件将获取到的item和index通过v-bind的形式传递给子组件-->
				<!--5.父组件 通过@delete监听子组件的点击时间,监听到了子组件的点击事件之后调用父组件的
			          	handleItemDelete函数
			          -->
				<todo-item v-bind:content="item" v-bind:index="index" v-for="(item,index) in list" @delete="handleItemDelete">

				</todo-item>
			</ul>

		</div>

		<script type="text/javascript">
			//定义全局组件
			//			Vue.component("TodoItem",{
			//				props:['content'],  
			//				template:"<li>{{content}}</li>"
			//			});

			//局部组件
			var TodoItem = {
				//2.子组件通过props接收到父组件传来的item和index参数
				props: ['content', 'index'],
				//3.当子组件被点击的时候,触发子组件的点击事件函数
				template: "<li @click='handleItemClick'>{{content}}</li>",
				methods: {
					handleItemClick: function() {
						//4.子组件触发点击事件之后,通过emit函数通知父组件,并回传list数组的下标
						this.$emit("delete", this.index);
					}
				}
			};

			//mvvm 框架 数据和视图双向绑定,面向数据开发
			var app = new Vue({
				el: '#app',
				data: {
					list: ['第一课的内容', '第二课的内容', '3333'],
					inputValue: ''
				},
				methods: {
					handleBtnClick: function() {
						if(this.inputValue) {
							this.list.push(this.inputValue);
							this.inputValue = '';
						}
					},
					//6.父组件拿到子组件回传的index下标进行移除操作
					handleItemDelete: function(index) {
						this.list.splice(index, 1);
					}
				},
				//上面定义的局部组件需要在此将它加入到vue组件中
				components: {
					TodoItem: TodoItem
				}
			});
		</script>
	</body>
</html>

 vue的每个组件其实也是vue的实例,vue的实例有很多实例属性和实例方法,在调用的时候加上$符号来区别用户自定义的属性和方法。

三、vue 的 生命周期钩子

 

 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>vue生命周期钩子</title>
	    
	    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			
		</div>
		
		<script type="text/javascript">
			//生命周期函数就是vue实例在某一个时间节点自动执行的函数,并且vue的
			//生命周期函数并不放在vue实例的methods对象中。
			var app = new Vue({
				el:"#app",
				beforeCreate: function(){
					console.log(" 基础的初始化 ");
				},
				created: function(){
					console.log("created");
				},
				beforeMount: function(){
					console.log("beforeMount");
				},
				mounted: function(){
					console.log("mounted")
				},
//				调用app.$destroy()方法时函数被调用
				beforeDestroy: function(){
				  console.log("beforeDestroy");
				},
				destroyed: function(){
                  console.log("destroyed");				
				},
				//数据被修改的时候被调用
				beforeUpdate: function(){
				  console.log("beforeUpdate");	
				},
				updated:function  () {
					console.log("updated");
				},
				template:"<div>{{test}}</div>",
				data:{
					test: "hellllllllllll......"
				}
			});
			
			setTimeout(function() {
				app.$data.test = 'worlddddddddd.....';
			},2000);
//		    setInterval(function(){
//		    	alert('123');
//		    },5000)
		</script>
	</body>
</html>

 

四、vue的 v-text  、v-html、计算属性

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>v-text,v-html,计算属性</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>

	<body>
		<div id="app">
			<div id="a">{{test+' lee'}}</div>
			<div id="b" v-text="test + ' lee' "></div>
			<div id="c" v-html="test +' lee'"></div>
			<div v-text="firstName"></div>
			<div v-html="lastName"></div>
			<div>计算属性:{{fullName}}</div>
			<!--<div>methods方法计算属性:{{fullName()}}</div>-->
		</div>
		<script type="text/javascript">
			var app = new Vue({
				el: "#app",
				data: {
					test: '<h1>dzx</h1>',
					firstName: "d",
					lastName: "zx",
					fullName: "dzx"
				},
				//计算属性,解决属性冗余,
				computed: {
					fullName: function() {
						console.log("计算 了一次");
						//计算属性具有缓存的作用,当计算的值被修改的时候才会重新计算。
						return this.firstName + " " + this.lastName;
					}
					//计算属性的get set用法
					//					fullName:{
					//						get:function(){
					//							return this.firstName+" "+this.lastName;
					//						},
					//						set: function(value){
					//							var arr = value.split(" ");
					//						    this.firstName = arr[0];
					//						    this.lastName = arr[1];
					//						}
					//					}
				},
				//普通方法
				//				methods:{
				//					fullName:function(){
				//						return this.firstName+" "+this.lastName;
				//					}
				//				},

				//watch 监听 某个属性的变化,进而改变另外一个 属性的值
				//				watch:{
				//					firstName:function(){
				//						this.fullName =  this.firstName+" "+this.lastName;
				//					},
				//					lastName:function(){
				//						this.fullName = this.firstName+" "+this.lastName;
				//					}
				//				}
			});
		</script>
	</body>

</html>

 五、样式绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>样式绑定</title>
	    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	 <style type="text/css">
	 	
	 	.activated{
	 		color: red;
	 	}
	 	
	 	.activatedOne{
	 		font-size: 20px;	
	 	}
	 			 	
	 </style>
	</head>
	<body>
		<div id="app">
			<div @click="handleDivClick" :class="{activated: isActivated}">
				{{msg}}
			</div>
		</div>
		
		
		
		<script type="text/javascript">
			var app = new Vue({
				el: "#app",
				data:{
					msg:"hello world",
					isActivated: false
				},
				methods:{
					handleDivClick: function  () {
						this.isActivated = !this.isActivated;
					}
				}
				
			});
		</script>
		
		
		<div id="app1">
			<div  @click="handleDivClick" :class="[activated,activatedOne]">
				{{msg}}
			</div>
		</div>
		
		<script type="text/javascript">
			
			var app1 = new Vue({
				el:"#app1",
				data:{
					msg:"hello world",
					activated:"",
					activatedOne: "",
				},
				methods:{
                  handleDivClick: function  () {
                  	 this.activated = this.activated ==='activated'?'':'activated';
                     this.activatedOne = this.activatedOne === 'activatedOne'?'':'activatedOne';
                  }
				}
				
				
			})
			
			
		</script>
		
		<div id="app2">
			<div :style="[styleObj,{fontSize:'20px'}]" @click="handleDivClick">
				{{msg}}
			</div>
		</div>
		
		<script type="text/javascript">
			
			var app2 = new Vue({
				el:"#app2",
				data:{
					msg:"hello world",
					activated:"",
					activatedOne: "",
					styleObj:{
						color: "blue"
					}
				},
				methods:{
					handleDivClick:function  () {
						this.styleObj.color = this.styleObj.color==="blue"?"red":"blue";
					}
				}
			})
			
			
		</script>
	</body>
</html>

六、v-if 和 v-show 的使用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>v-if,v-show</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		
		<div id="app">	
		<!--v-if 相当于 是对 dom元素的 删除 和 添加-->
		<div v-if="show">hello world</div>	
		
		<!--
        	作者:offline
        	时间:2019-03-24
        	描述:v-if v-else-if v-else 在使用的时候一定要放在一起,中间不能有其他的元素
        	隔断,否则浏览器编译报错
        -->
		<div v-if="x === 'a'">this is a </div>
		<div v-else-if="x === 'b'">this is b</div>
		<div v-else>this is other</div>
		
		<!--
        	作者:offline
        	时间:2019-03-24
        	描述:给input 输入框添加一个唯一标识key,这样可以防止在改变show的时候
        	将清空之前输入框中的值
        -->
		<div v-if="show">
			用户名:<input type="text" key="username"/>
		</div>
		<div v-else>
			邮箱: <input type="text" key="password"/>
		</div>
		<!--
        	作者:offline
        	时间:2019-03-24
        	描述:v-show则是没有真正的将dom元素进行删除添加操作,仅仅只是对style样式的
        	display属性的改变。来让dom元素实现显示和隐藏。因此在 频繁显示和隐藏的功能上
        	我们更加推荐使用v-show
        -->
		<div v-show="show">hello world!!</div>
			
		</div>
		
		<script type="text/javascript">
			
			var vm = new Vue({
			 el:"#app",
			 data:{
			  show: false,
			  x: "a"
			 }
			});
			
			
		</script>
		
	</body>
</html>

 七、v-for 的用法

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>v-for</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>

	<body>

		<div id="app">
			<!--数组的操作 push、 pop、 shift、 unshift、 splice、 sort、 reverse-->
			<!--当我们使用app.list[3] = {id:"004",title:"redis"} 向数组中添加元素的时候
				发现页面上面不会动态 的更新,我们需要用 上面的数组操作函数才行。
				app.list.splice(1,1,{id:"004",title:"redis"})
				或者我们直接更改整个 list的引用对象即可。
			-->
			<template v-for="(item,index) of list" :key="item.id">
				<div>
					{{item.title}}---{{index}}
				</div>
				<span>
               	{{item.title}}
               </span>
			</template>

			<!--
            	作者:offline
            	时间:2019-03-24
            	描述:v-for 也可以用来循环遍历对象
            	当我们直接使用app.userInfo.address ="北京"时发现对象 确实
            	新增了一个address属性,但是页面上也没有动态更新显示,
            	我们可以直接更改 整个对象的引用地址。
             	app.userInfo = {
                 		name:"Dell",
				    	age:28,
				    	gender:"male",
				    	address:"北京"
            	}
            -->
			<div v-for="(item,key,index) of userInfo">
				{{item}}---{{key}}---{{index}}
			</div>
			
			<button @click="insertAddress">给用户添加一个属性</button>
		</div>

		<script type="text/javascript">
			var app = new Vue({
				el: "#app",
				data: {
					list: [{
							id: "001",
							title: "hadoop"
						},
						{
							id: "002",
							title: "spark"
						},
						{
							id: "003",
							title: "flink"
						}
					],
					userInfo: {
						name: "Dell",
						age: 28,
						gender: "male"
					}
				},
				methods:{
					insertAddress:function(){
						//还有一种最简单的方式就是使用 vue 的全局set 函数直接修改或添加属性到
						//数组或者对象中
						//vue 全局set 方法
						Vue.set(this.userInfo,"address","北京");
						Vue.set(this.list,"1",{id:"0020",title:"spark0"});
						
						//vue 实例 set方法
						this.$set(this.userInfo,"address1","湖北");
						this.$set(this.list,"2",{id:"0030",title:"spark3"});
					}
				}
			});
		</script>
	</body>

</html>

 八、组件使用细节

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>组件使用细节</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>

	<body>

		<div id="app">
			<table>
				<tbody>
					<!--<row></row>
					<row></row>
					<row></row>-->
					<!--因为在tbody中必须时tr标签,浏览器才能识别
					所以我们不能直接写成定义的row组件,需要用到is属性-->
					<tr is="row"></tr>
					<tr is="row"></tr>
					<tr is="row"></tr>
				</tbody>

			</table>

		</div>
		<script type="text/javascript">
			Vue.component("row", {
				data: function(){
					return {
						content:"this is a row"
					}
				},
				template: "<tr><td>{{content}}</td></tr>"
			
			});

			var app = new Vue({
				el: "#app"
			});
		</script>

     <div id="app1">
     	<!--
         	作者:offline
         	时间:2019-03-24
         	描述:ref的用法
         	1.当ref 作用在普通标签上面的时候,
         	this.$refs.引用名称  获取到的是这个dom元素
         	2.当red作用在 vue组件上面的时候,
         	this.$refs.引用名称 获取到的是组件实例的引用对象
         -->
     	<div ref="my" @click="clickDiv">hello my lala lala !!!</div>
     	
     	<counter ref="one" @change="handleChange" ></counter>
     	<counter ref="two"  @change="handleChange" ></counter>
     	<div>{{total}}</div>
     </div>

     <script type="text/javascript">
     
     //定义一个counter子组件
     Vue.component("counter",{
     	 data: function() {
     	 	return {
     	 		number:0
     	 	}
     	 },
     	 template:"<div @click='handlerSubClick'>{{number}}</div>",
     	 methods:{
     	 	handlerSubClick:function  () {
     	 		this.number++;
     	 		this.$emit("change")
     	 	}
     	 }
     });
     
     var app1 = new Vue({
     	el:"#app1",
     	data:{
     		total:0
     	},
     	methods:{
     		clickDiv: function(){
     			alert(this.$refs.my.innerHTML);
     		},
     		handleChange:function  () {
     			//获取子组件的引用对象中的 number值
     			this.total = this.$refs.one.number+this.$refs.two.number;
     		}
     	}
     });
     </script>
	</body>
</html>

九、父子组件传值 

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>父子组件传值</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>

	<body>

		<div id="app">
			<!--
            	作者:offline
            	时间:2019-03-24
            	描述:父组件通过属性的形式向子组件传值
            	,子组件通过事件通知的形式向父组件传值
            -->
			<counter :count="3" @change="add"></counter>
			<counter :count="2" @change="add"></counter>
			<div>{{total}}</div>
		</div>

		<script type="text/javascript">
			var counter = {
				props: ['count'],
				data: function() {
					return {
						number: this.count
					}
				},
				template: "<div @click='handleClick'>{{number}}</div>",
				methods: {
					handleClick: function() {
						this.number += 2;
						this.$emit("change", 2);
					}
				}
			};

			var app = new Vue({
				el: "#app",
				components: {
					counter: counter
				},
				data: {
					total: 5
				},
				methods: {
					add: function(step) {
						this.total += step;
					}
				}
			});
		</script>

	</body>

</html>

十、组件参数校验与非props特性

 

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>组件参数校验与非props特性</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>

	<body>

		<div id="app">
		<child content="hello world"></child>
		</div>
		<script type="text/javascript">
			Vue.component("child",{
				props:{
					//参数校验,只接受string或者number型的值
					content:{
						type:String,
						required:true,
						default:"default value",  //默认值
						validator:function(value){  //自定义校验器
							return value.length>5;
						}
					}
				},
				template:"<div>{{content}}</div>"
			});

			var app = new Vue({
				el: "#app",
				data: {
				},
				methods: {
				}
			});
		</script>
	</body>
</html>

 十一、给组件绑定原生事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>组件参数校验与非props特性</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>

		<div id="app">
			<!--
        	作者:offline
        	时间:2019-03-24
        	描述:给组件 绑定原生事件,只需要加一个native 关键字即可
        -->
			<child @click.native="handleClick"></child>
		</div>
		<script type="text/javascript">
			Vue.component("child", {
				template: "<div>hello</div>"
			});

			var app = new Vue({
				el: "#app",
				data: {},
				methods: {
					handleClick: function() {
						alert("123");
					}
				}
			});
		</script>
	</body>

</html>

十二、 非父子组件之间的传值

 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>非父子组件之间的传值(Bus总线/发布订阅/观察者模式)</title>
	    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
			<div id="app">
			
			<child content="Dell"></child>
			<child content="Lee"></child>
		</div>
		<script type="text/javascript">
			
			//使每个组件bus属性上面都挂载一个vue实例
			Vue.prototype.bus = new Vue();
			
			
			Vue.component("child", {
				props:{
					content:String
				},
				data:function(){
					return {
						selfContent:this.content
					}
				},
				template: "<div @click='handleClick'>{{selfContent}}</div>",
				methods:{
					handleClick:function  () {
						//alert(this.content);
						this.bus.$emit('change',this.selfContent);
					}
				},
				mounted:function  () {
					var this_ = this;
					this.bus.$on('change',function(msg){
						 alert(msg);
						 this_.selfContent = msg;
					});
				}
			});

			var app = new Vue({
				el: "#app",
				data: {},
				methods: {
					handleClick: function() {
						alert("123");
					}
				}
			});
		</script>
		
		
		
	</body>
</html>

十三、在vue中使用插槽 

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>

	<body>

		<div id="app">

			<body-content>
				<!--
                	作者:offline
                	时间:2019-03-24
                	描述:组件中的dom元素就相当于插槽
                -->
				<div class="header" slot="header">header</div>
				<div class="footer" slot="footer">footer</div>
			</body-content>

		</div>

		<script type="text/javascript">
			Vue.component("body-content", {
				//通过slot标签就可以使用插槽,如果父组件中的插槽,指定了slot属性,这里使用的时候
				//通过slot标签的name属性就可以选择使用插槽
				template: `<div><slot name='header'>
				           <h1>default value</h1>
				           </slot>
					<div class='content'>content</div>
					<slot name='footer'></slot></div>`
			});

			var app = new Vue({
				el: "#app"

			});
		</script>

	</body>

</html>

十四、 vue中的作用域插槽

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>vue中的作用域插槽</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>

	<body>

		<div id="app">
			<child>
				<template slot-scope="props">
					<h1>{{props.item}}</h1>
				</template>
			</child>
			
			<child>
				<template slot-scope="props">
					<h2>{{props.item}}</h2>
				</template>
			</child>
			
			<child>
				<template slot-scope="props">
					<h3>{{props.item}}</h3>
				</template>
			</child>
		</div>

		<script type="text/javascript">
			Vue.component("child", {
				data: function() {
					return {
						list: [1, 2, 3, 4]
					}
				},
				template: `<div>
				         <ul>
				         <slot v-for="item of list" :item=item>
				          </ul>
				          </div>`
			});
			var app = new Vue({
				el: "#app"
			});
		</script>

	</body>

</html>

十五、动态组件与v-once指令

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>

	<body>

		<div id="app">
			<!--
            	作者:offline
            	时间:2019-03-24
            	描述:动态组件,component 标签,type是child-one 页面上
            	就显示child-one ,是child-two就显示child-two
            -->
			<component :is="type"></component>
			<!--<child-one v-if="type==='child-one'">
			</child-one>
			
			<child-two v-if="type==='child-two'">
			</child-two>-->
        
             
          <button @click="handleClick">change</button>
		
		</div>

		<script type="text/javascript">
			Vue.component("child-one", {
//				v-once使组件内容不变的情况下只加载一次,提高性能
				template:"<div v-once>child-one</div>"
			});
			Vue.component("child-two", {
				template:"<div v-once>child-two</div>"
			});
			var app = new Vue({
				el: "#app",
				data:{
					type:"child-one"
				},
				methods:{
					handleClick:function  () {
					this.type= this.type==='child-one'?'child-two':'child-one';	
					}
				}
			});
		</script>

	</body>

</html>

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章