• VUE 入门笔记


    前端的MVVM概念今年来也算是如火如荼,了解完 MVVM的概念,也该找个去尝试下
    首先我先试了下 国内小而美的 VUE

    • 试着照着文档敲出入门文件,内容都在注释里
    <!doctype html>
    <html>
    
    <head>
    	<title>VUE 入门</title>
    	<style>
    		body{display:flex;flex-wrap: wrap;align-items:flex-end;}
    		body>div{box-shadow:0 0 3px #000;margin:8px;padding:8px;}
    	</style>
    </head>
    
    <body>
    	<!-- 插值也能插在 dom 的属性里 -->
    	<div id="app" content="{{message}}">
    		<h4>基础插值</h4>
    		<!-- 基础文本插值 -->
    		<p>{{message}} </p>
    		<!-- 单次插值,之后不再变化 -->
    		<p>{{* message}} </p>
    		<!-- 可用来输出HTML 只对可信内容进行 HTML 插值 -->
    		<p>{{{message}}}</p>
    		<!-- 双向绑定 -->
    		<!-- 按键修饰符 可绑定按钮事件 也可使用别名以及自己配置别名 -->
    		<input type="text" v-model="message" v-on:keyup.13="show" />
    	</div>
    	
    	<!-- 渲染列表 -->
    	<div class="list">
    		<h4>列表渲染</h4>
    		<ul>
    			<!-- 直接使用表达式 -->
    			<input type="text" v-model="query" placehorder="筛选">
    			<li v-if="item.show" id='item{{$index + 1}}' v-for="item in items | filterBy query" track-by="id">
    				<h4>{{item.title}}</h4>
    				<p>{{item.content}}</p>
    				<!-- 遍历对象,不同JS引擎结果不一样 -->
    				<h5 v-for="value in item">
    					{{$key}} : {{value}}
    				</h5>
    			</li>
    		</ul>
    		<!-- v-for 可接收一个整数 -->
    		<span v-for="n in 10">{{n + 1}}</span>
    	</div>
    	<!-- 绑定方法 -->
    	<div class="show">
    		<h4>按钮事件绑定</h4>
    		<span>{{message}}</span><br/>
    		<input type="text" v-model="name" /><br/>
    		<!-- 监听事件 -->
    		<!-- 可通过内联JavaScript语句传值. $event -->
    		<a href="http://www.baidu.com" v-on:click="showMessage('hello',$event)">点击 alert</a>
    		<!-- 
    			事件修饰符 v-on:event.stop.prevent.capture.self
    			详情查阅 Vue api
    		 -->
    		<a href="http://www.baidu.com" @click.stop.prevent="editMessage">更改内容</a><br/>
    	</div>
    	<!-- CLASS 切换 -->
    	<div class="toggle">
    		<h4>v-show与v-if 以及class切换</h4>
    		<style>
    			.toggle div.show{height:100px;}
    			.toggle div.hide{height:0;}
    		</style>
    		<!-- checkbox 绑定 -->
    		<input type="checkbox" v-model="ok">按钮切换
    		<template v-if="ok">
    			<button @click="toggle">切换</button>
    		</template>
    		<template v-else>
    			<button @click="colorToggle">颜色切换</button>
    		</template>
    		<article>
    			<section>
    				v-show 与 v-if 还是有区别的;
    				当 OK为 false 时,
    			</section>
    			<section v-show="ok">
    				v-show 仅仅是将其隐藏;如果频繁切换,可采用v-show.不会进行大量的DOM操作
    			</section>
    			<section v-if="ok">
    				而 v-if 是直接移除该 dom,如果操作很少, v-if 可更好	
    			</section>
    			
    		</article>
    		<div :class="{'show':show,'hide':hide}" style="transition:0.4s;" :style="style">	
    		</div>
    	</div>
    	<div class="input">
    		<h4>表单绑定</h4>
    		<!-- debounce 设置延迟 适合非快速更新视图的情况 -->
    		<input v-model="message" debounce="500"/>
    		<input type="checkbox" v-model="checked" /><br/>
    		<input id="LiLei" type="checkbox" v-model="names" value="LiLei"/>
    		<label for="LiLei">LiLei</label>
    		<input id="HanMei" type="checkbox" v-model="names" value="HanMei"/>
    		<label for="HanMei">HanMei</label>
    		<input id="Lucy" type="checkbox" v-model="names" value="Lucy"/>
    		<label for="Lucy">Lucy</label>
    		<input type="radio" value="one" v-model="radio"/>ONE
    		<input type="radio" value="two" v-model="radio"/>TWO
    		<select v-model="select" multiple>
    			<option selected>1</option>
    			<template v-for="n in 5">
    				<option>{{n + 2}}</option>
    			</template>
    		</select>
    		<div>
    			<p>
    				message:{{message}};
    			</p>
    			<p>
    				checkbox:{{checked}};
    			</p>
    			<p>
    				选中的名字有{{names}}
    			</p>
    			<p>
    				单选被选中的值为:{{radio}}
    			</p>
    			<p>
    				select 选中的值为:{{select}}
    			</p>
    		</div>
    	</div>
    	<div id="transition" style="min-height:300px;">
    		<h4>动画</h4>
    		<style>
    			.div1{background:#555;50px;height:50px;}
    			/* 该动画会一直存在 */
    			.expand-transition{transition:.4s ease;}
    			/* 该样式在进入的时候添加 */
    			.expand-enter{height:0;}
    			/* 该样式在退出的时候添加 */
    			.expand-leave{height:0;}
    			.div2{background:red;50px;height:50px;}
    			.flash-enter{animation:flash-in 1.4s;}
    			.flash-leave{animation:flash-out 1.4s;}
    			@keyframes flash-out{0%{opacity:1}30%{opacity:0;}40%{opacity:0.2;}100%{opacity:0;}}
    			@keyframes flash-in{0%{opacity:0}30%{opacity:1;}40%{opacity:0.2}100%{opacity:1;}}
    		</style>
    		<button @click="div1Toggle">DIV1 框架消失</button>
    		<!-- 指定动画名称 style 应当添加以该 动画名为首的样式 -->
    		<div v-if="show" class="div1" :transition="transitionName"></div>
    		<div v-if="show" class="div2" transition="flash"></div>
    	</div>
    </body>
    <script src="./vue.js"></script>
    <script>
    'use strict';
    Vue.config.debug = true;
    var vue1 = new Vue({
    	//	通过ID访问元素
    	//	vue1.$el === document.getElementById('app') => true
    	el: '#app',
    	data: {
    		//	每个 Vue 实例都会代理其 data 对象里的所有属性
    		//	因此可通过 vue1.message 访问该属性 
    		message: 'Hello Vue.js!!!'
    	},
    	//	生命周期勾子 created compiled ready destroyed 等 详情查阅 Vue api
    	created: function() {
    		//alert('我被创建了');
    	},
    	methods: {
    		show: function() {
    			alert(this.message);
    		}
    	}
    });
    
    //	监视该 实例下的  message 
    vue1.$watch('message', function(newVal, oldVal) {
    	//	改变后的值
    	console.log(newVal);
    	//	改变前的值
    	console.log(oldVal);
    });
    
    var vue2 = new Vue({
    	//	通过类名访问元素
    	el: '.list',
    	data: {
    		query:"",
    		items: [{
    			id: 1,
    			title: '标题1',
    			content: '内容1',
    			show: true,
    		}, {
    			id: 2,
    			title: '标题2',
    			content: '内容2',
    			show: true,
    		}, {
    			id: 3,
    			title: '标题3',
    			content: '内容3',
    			show: false
    		}]
    	},
    });
    /*
    	可对 vue2.items 直接进行数组操作,操作后可触发页面上内容的刷新
    	push()
    	pop()
    	shift()
    	unshift()
    	splice()
    	sort()
    	reverse()
    	数组替换
    	==========================
    	以下两种都不会被 vue检测到数组变化
    	1. 直接用索引设置元素,如 vm.items[0] = {};
    	2. 修改数据的长度,如 vm.items.length = 0。
    	可采用 vue2.items.$set(0,{...}) 或  vue2.items.$remove(vue2.items[index])
    	去更新数组
    */
    
    
    var vue3 = new Vue({
    	el: '.show',
    	data: {
    		first_name: 'Li',
    		last_name: 'Lei'
    	},
    	//	TODO
    	//	当 first_name 与 last_name 有更改时,都会重新计算
    	computed: {
    		name: function(event) {
    			//	方法内的 this 指向 vue3
    			//	event 是原生 DOM 事件 
    			return this.first_name + this.last_name;
    		},
    		fullname: {
    			//	getter
    			get: function() {
    				return this.first_name + this.last_name;
    			},
    			//	setter
    			//	vue3.fullname = 'Han Mei' 即可调用该 setter
    			set: function(newValue) {
    				var names = newValue.split(' ');
    				this.first_name = names[0];
    				this.last_name = name[1];
    			}
    		}
    	},
    	methods: {
    		showMessage: function(msg, event) {
    			console.log(msg);
    			//	阻止默认事件
    			event.preventDefault()
    			console.log(event);
    			console.log(this.name);
    			console.log(vue2.items[0].title);
    		},
    		editMessage: function() {
    			var content = prompt('请输入姓');
    			this.first_name = content;
    			//	更改 vue1 里的内容
    			vue1.message = content;
    		}
    	}
    });
    
    var vue4 = new Vue({
    	el: ".toggle",
    	data: {
    		hide: false,
    		style: {
    			background: '#555',
    			 '100px'
    		},
    		styleStatus: true,
    		ok: false
    	},
    	methods: {
    		toggle: function() {
    			console.log(this.hide)
    			if (this.hide) {
    				this.hide = false;
    			} else {
    				this.hide = true;
    			}
    		},
    		colorToggle: function() {
    			if (this.styleStatus) {
    				this.styleStatus = false;
    				this.style = {
    					background: 'red',
    					 '200px'
    				}
    			} else {
    				this.styleStatus = true;
    				this.style = {
    					background: '#555',
    					 '100px'
    				};
    			}
    		},
    	},
    	computed: {
    		show: function() {
    			return this.hide ? false : true;
    		}
    	}
    });
    /*
    	前端发展到现在,一直遵循着 html css 以及 js 分离;
    	为了以后维护的时候能更方便;
    	然而 Vue 却在 html 里 却将 事件 通过 v-on 严格的绑定在 视图(HTML)上
    	我觉的除了官方的解释(模版与JS方法紧耦合,容易查找对应的JS;无需自己再手动 绑定事件与清理dom),
    	对使用者也是更加容易了;
    	可以将公用的 js 函数 提取出来,
    	然后通过不同的 Vue 实例去调用函数.以后有优化JS 时直接去优化该函数,
    	而且 视图 和 js 的紧耦合,可以使之更倾向于 组件化
    */
    
    var vue5 = new Vue({
    	el: '.input',
    	data: {
    		message: '',
    		checked: '',
    		names: [],
    		radio: '',
    		select: ''
    	}
    });
    
    var vue6 = new Vue({
    	el: '#transition',
    	data: {
    		show: true,
    		//	指定动画名称
    		//	若该值为空, 默认采用 v-transition,v-enter,v-leave
    		transitionName: 'expand'
    	},
    	methods: {
    		div1Toggle: function() {
    			if (this.show) {
    				this.show = false;
    			} else {
    				this.show = true;
    			}
    		}
    	}
    });
    Vue.transition('expand', {
    	beforeEnter: function(el) {
    		el.textContent = 'beforeEnter'
    	},
    	//	enter 及 leave 都可添加回调函数
    	enter: function(el,done) {
    		el.textContent = 'enter'
    		//	enter 后5秒再执行 afterEnter
    		setTimeout(done,5000);
    	},
    	afterEnter: function(el) {
    		el.textContent = 'afterEnter'
    	},
    	enterCancelled: function(el) {
    		// handle cancellation
    	},
    
    	beforeLeave: function(el) {
    		el.textContent = 'beforeLeave'
    	},
    	leave: function(el) {
    		el.textContent = 'leave'
    	},
    	afterLeave: function(el) {
    		el.textContent = 'afterLeave'
    	},
    	leaveCancelled: function(el) {
    		// handle cancellation
    	}
    });
    </script>
    </html>
    
    
    
    • 了解完基础用法,开始做个 todo 页面
    <!doctype html>
    <html>
    <head>
    	<title> 简单 TODO  </title>
    	<style>
    		body{background:#d9d9d9;}
    		#todo{800px;margin:10px auto;background:#fff;box-shadow:0 0 3px rgba(0 0 0 255);transition:.4s ease;padding:16px;}
    		#todo>input{100%;padding:8px 0;height:32px;outline:none;font-size:18px;border:0;border-bottom:1px solid #d9d9d9;overflow:hidden;}
    		.bar{padding:16px 0;}
    		#todo>a{18%;display:inline-block;}
    		h1{text-align:center;}
    		ul{list-style:none;100%;padding:0;}
    		ul>li{height:48px;line-height:48px;overflow:hidden;border-bottom:1px solid #999;}
    		li>a{transform:rotate(45deg);font-weight:bold;color:red;float:right;font-size:32px;display:none;}
    		li>span{margin-left:32px;transition:.4s;}
    		li>input{position:relative;outline:none;}
    		li>input:before{content:'';18px;height:18px;background:#fff;border:1px solid #d9d9d9;top:-2px;position:absolute;z-index:1;}
    		li.checked>input:after{content:'';12px;height:6px;border-left:3px solid #999;border-bottom:3px solid #999;top:2px;left:2px;position:absolute;z-index:2;transform:rotate(-45deg);}
    		li.checked>span{text-decoration:line-through;color:#555;}
    		li:hover>a{display:inline-block;cursor:pointer;}
    		.fade-transition{transition:.4s ease}
    		.fade-enter,.fade-leave{height:0;}
    		.bar>span{color:#999;}
    		.bar>span:nth-child(n+2){margin-left:32px;padding:4px 8px;}
    		.bar>span:nth-child(n+2):hover{color:#555;transition:.4s;cursor:pointer;}
    		.bar>span.active{box-shadow:0 0 4px #222;}
    	</style>
    </head>
    <body>
    	<h1>待办事项</h1>
    	<div id="todo">
    		<input v-model="todo" type="text" v-on:keyup.enter="add" placeholder="请输入待办事项"/>
    		<div class="bar">
    			<span>共有 {{items.length}} 条代办事项</span>
    			<span @click='all' :class="{active:filter.all}">全部事项</span>
    			<span @click='undone' :class="{active:filter.undone}">未完成</span>
    			<span @click='done' :class="{active:filter.done}">已完成事项</span>
    		</div>
    		<ul>
    			<template v-for="item in items | orderBy 'todoid' | filterBy filter.status ">
    				<li transition="fade" :class="{'checked':item.status}">
    					<input type="hidden" v-model='item.todoid'>
    					<input type="checkbox" @click='status($index)' v-model='item.status'>
    					<span>{{item.content}}</span>
    					<!-- 获取INDEX -->
    					<a v-on:click="remove($index)">+</a>
    				</li>
    			</template>
    		</ul>
    	</div>
    </body>
    <script src="./vue.js"></script>
    <script>
    	var todoList = new Vue({
    	el: '#todo',
    	data: {
    		test:false,
    		filter:{
    			all:true,
    			done:false,
    			undone:false,
    			status:'',
    		},
    		todoid:'1',
    		items: [],
    		todo:''
    	},
    	methods: {
    		remove: function(index) {
    			this.items.splice(index, 1);
    		},
    		add: function() {
    			if (this.todo.trim()) {
    				this.items.push({
    					content: this.todo,
    					todoid:this.todoid,
    					status:false
    				});
    				this.todoid ++ ;
    				localStorage.todoId = JSON.stringify(this.todoid);
    			}
    			this.todo = "";
    		},
    		status:function(index){
    			if(this.items[index].status){
    				this.items[index].status = false;
    			}else{
    				this.items[index].status = true;
    			}
    		},
    		all:function(){
    			this.filter = {
    				all:true,
    				done:false,
    				undone:false,
    				status:'',
    			}
    		},
    		undone:function(){
    			this.filter = {
    				all:false,
    				done:false,
    				undone:true,
    				status:false,
    			}
    		},
    		done:function(){
    			this.filter = {
    				all:false,
    				done:true,
    				undone:false,
    				status:true,
    			}
    		}
    	},
    });
    todoList.$watch('items',function(newValue,oldValue){
    	localStorage.todo = JSON.stringify(newValue);
    	//	内部值变化时,也能获取到变化
    },{deep:true});
    if(localStorage.todo){
    	todoList.items = JSON.parse(localStorage.todo);
    	todoList.todoid = JSON.parse(localStorage.todoId);
    }
    </script>
    </html>
    
  • 相关阅读:
    无题
    【HNOI 2002 】营业额统计
    P1589
    【网络流24题】最长递增子序列
    【NOI2008】志愿者招募
    【NOI2015】软件包管理器
    P1347
    【BZOJ 3262三维偏序】陌上花开
    数论六·模线性方程组
    数论五·欧拉函数
  • 原文地址:https://www.cnblogs.com/linjilei/p/5450903.html
Copyright © 2020-2023  润新知