0
点赞
收藏
分享

微信扫一扫

每天一点VUE(DAY 4-VUE2篇)

Ad大成 2022-04-18 阅读 65

1、修改数组的内容出现的问题

2、手写Vue检测数据的原理

/*这里的缺点是:
    1:没有做数据代理
    2:没有做深度的检测,如果对象里面有对象,或者对象里面的数组有对象
      就无法添加getter和setter
*/	
    var people =  {
		name:"potkiss",
		height:90,
		age:80,
		friend:{
			name:'kk'
		},
		family:[{name:'father'},{name:'mother'}]
	};
	let a = new Observe(people);
	let vm = {}
	vm._data = data = a
	console.log(vm)
	function Observe(re){
        //遍历构造函数的属性
		Object.keys(re).forEach((item,index)=>{
        //this指向的是实例对象,给这个this添加属性
			Object.defineProperty(this,item,{
				get(){
                    //这里可以像数组一样获取对象的值
					return re[item]
				},
				set(val){
					console.log(`${val}被改了,开始解析模版,生成虚拟dom,进行比较`)
					re[item] = val
				}
			})
		})
	}

3、Vue.set()和vue实例的$set()

    /*这样操作后的数据是可以被vue检测到的,
    是有getter和setter的,能后引发后面的一系列动作,
    缺点:不能在Vue下或者Vm根下添加数据
    */	
    <div id="block">
			{{name}}<br>
			{{height}}<br>
			年龄:{{hobb.age}}<br>
			爱好<br>
			{{hobb.name}}<br>
			家人<br>
			<ul v-for="(item,index) in family" :key="index">
				<li>{{item.name}}</li>
			</ul>
		<button type="button" @click="change001">点击添加年龄值</button>
		<button type="button" @click="change002">点击添加家庭成员</button>
	</div>

	<script type="text/javascript">
	Vue.config.productionTip = false
	let vm = new Vue({
			el:'#block',
			data:{
				name:"potkiss",
				height:190,
				hobb:{
					name:'写代码',
				},
				family:[{name:'father'},{name:'mother'}]
			},
			methods:{
				change001(){
                    /*注意:Vue.set()和vm.$set()方法,
                        都无法在data或者Vm上直接添加数据,
                        只能在data或者vm上面的某一个对象上追加,
                        只有用set()方法追加的数据才可以被VUe检测到
                        才可以进行后面的解析模版,等一系列操作。
                    */
					 Vue.set(this.hobb,'age','99') //属于Vue上的方法
					this.$set(this.hobb,'age','99')    //属于Vm上的方法
				},
				change002(){
                    /*
                        第一个在数组的第二位置追加了一个元素
                        第二个吧数字的第一位替换了,
                        这样操作后的数组里面的对象是有getter和setter的
                        但是不建议这样做,操作数组我们可以用后面的7个常用
                        操作数字的方法。
                    */
					 Vue.set(this.family,2,{name:'potkiss'})  //属于Vue上的方法
					this.$set(this.family,0,{name:'potkiss'})  //属于Vm上的方法
				}
			}
			
		})
	</script>
	

4、操作数组的数据发生改变

    /*
        (1)注意只有下面的这7个可以改变数组的顺序的方法才可以,
        像filter就不行,如果想用filter就吧过滤好的数组用
        下面的7个方法替换即可。
        
        (2)这七个方法其实已经不是原本的Array上的方法了,
(你可以在控制台输入这两条语句let a =[];vm.family.shift === b.shift;然后看结果是不是false)
        而是Vue给重新打包分装好的,当我们使用这5个方法时,
           1、调用原本Array上的原本的方法,
           2、解析模版,生成虚拟DOM,diff对比,渲染。。。 
        
    */    
    <div id="block">
		家人<br>
		<ul v-for="(item,index) in family" :key="index">
			<li>{{item.name}}</li>
		</ul>
		<button type="button" @click="change001">点击添加年龄值</button>
	</div>
	</body>
	<script type="text/javascript">
	Vue.config.productionTip = false
	let vm = new Vue({
			el:'#block',
			data:{
				family:[{name:'mother',age:20},{name:'father',age:80}]
			},
			methods:{
				change001(){
                     this.family.splice(0,2,{name:'potkiss'}) //替换数组的某长度元素,{第几位开始,到第几位,换成啥}
					 this.family.pop() //移除最后一个
					 this.family.push({name:'potkiss'}) //后面追加一个
					 this.family.shift() //删除第一个
					 this.family.unshift({name:'potkiss'}) //前面追加一个
					 this.family.sort(function(a,b){return b.age-a.age}) //排序,参数必须是一个函数,这里是由大到小排列
					 this.family.reverse() //翻转数组
				}
			}
		})
	</script>

5、v-model的表单获取,(细节满满)


	<!-- 这里给submit事件添加了一个阻止默认行为的属性 -->
	<form id="block" @submit.prevent="sub">
		<!-- 这里的trim是删除输入字符前后的空格 -->
		姓名:<input type="text" v-model.trim="UserInfo.name"><br>
		<!-- 这里的trim是删除输入字符前后的空格 -->
		密码:<input type="password" v-model.trim="UserInfo.password"><br>
		<!-- 这里type为number是为了让用户只可以输入数字,v-model后面的number是让用户输入的内容强制变为数字类型的数据 -->
		年龄:<input type="number" v-model.number="UserInfo.age"><br>
		性别:
		<!-- 这里的name可以让多个单选框只可以选中一个,但是要注意还要写一个value的值,才可以获取到,不然获取到的就是空字符串 -->
		男<input type="radio" name="sex" value="male" v-model="UserInfo.sex">
		女<input type="radio" name="sex" value="female" v-model="UserInfo.sex"><br>
		爱好:
		<!-- 这里也是,一定要写value,不然v-model获取到的就是checked这个属性,又因为三个绑定了同一个字段,所以会同时操作三个 -->
		<!-- 还要注意下面的数据要是数组,不然就还是获取的checked这个属性的值 -->
		吃饭:<input type="checkbox" v-model="UserInfo.hobby"  value="eat">
		喝酒:<input type="checkbox" v-model="UserInfo.hobby" value="drink">
		抽烟:<input type="checkbox" v-model="UserInfo.hobby"  value="smoke"><br>
		地址:
		<!-- 注意这里要绑定在select上 -->
		<select v-model="UserInfo.address">
			<option value="" >选一个</option>
			<option  value="xj">新疆</option>
			<option  value="bj">北京</option>
			<option  value="lz">兰州</option>
		</select><br>
		<!-- 这里的lazy是当用户失去焦点后获取输入的值 -->
		<textarea  cols="30" rows="10" v-model.lazy="UserInfo.text"></textarea><br>
		<!-- 这里直接获取的checked的值 -->
		<input type="checkbox" v-model="UserInfo.check" >协议<br>
		<button>提交</button>
	</form>


<script type="text/javascript">
Vue.config.productionTip = false
let vm = new Vue({
		el:'#block',
		data:{
			UserInfo:{
				name:'',
				password:'',
				age:null,
				sex:'',
				hobby:[], //注意这个数据类型
				address:'',
				text:'',
				check:true
			}
		},
		methods:{
			sub(){
				//把所有数据放在一个对象里面就可以一次性获取,并且方便后面添加属性,因为Vue.set()不能再根上添加
				console.log(this.UserInfo);
			}
		}
	})
</script>

6、filters过滤器的使用

<body>
		<div id="block">
			1: {{comTime}}<br>
			2: {{getTime()}}<br>
			3 {{time | filterTime("abc") | cutString | CutString}}<br>
			<div id="block2">
				<!-- 这里的cutString也可以用是因为block2包含在block1中的 -->
				4: {{time | filterTime("abc") | cutString }}<br>
				5: {{time | filterTime("abc") | CutString}}<br>
			</div>
		</div>
	</body>
	<script type="text/javascript">
	Vue.config.productionTip = false
	//全局的filter,别的组件也可以用
	Vue.filter('CutString',function(value){
		return value.slice(0,1);
	})
	let vm = new Vue({
			el:'#block',
			data:{
				time:'1650216828381'
			},
			methods:{
				getTime(){
					return dayjs(Date.now()).format('YY-MM-DD HH-MM-SS')
				}
			},
			computed:{
				comTime(){
					return dayjs(Date.now()).format('YY-MM-DD HH-MM-SS')
				}
			},
			filters:{
				filterTime(value,can){
					console.log(value,can)
					return dayjs(Date.now()).format('YY-MM-DD HH-MM-SS')
				},
				cutString(value){
					/*
						功能:只显示前4位,
						问题:别的Vue实例(组件)不能用
						解决:在实例前面弄全局的过滤器,注意,一次只能弄一个
					*/
					return value.slice(0,4);
				}
			}
		})
		let vm2 = new Vue({
			el:'#block2',
		})
	</script>

7、5个不常用的内部指令

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>内部指令</title>
	</head>
	<style>
		[v-cloak]{
			display: none;
		}
	</style>
	<body>
		<div id="block">
			<div>{{data}},world</div>
			<!-- v-text的特别的地方是会替换这个元素的全部文本,不能拼接 -->
			<div v-text="data">world</div>
			<!-- v-html可以解析有标签的结构,
				但是有危险,可能会被xss攻击,一般不建议用!!!,
				比如我写一个跳转的链接,通过这种可以解析
				html的地方输入出去,比如评论,当有人点击了我的评论
				然后会把点击的用户的本地没有HTTP-ONLY的cookie
				给截取到发给劫持者的服务器,然后劫持者接可以为所欲为了
			 -->
			<div v-html="data2"></div>
			<!--v-cloak这个属性是如果页面引入的js加载太慢了,
				没有渲染VUE时会出现,页面开始渲染了就消失了,
				可以配合css,实现在页面还没渲染之前隐藏动态元素
			-->
			<div v-cloak>{{data3}}</div>
			<!-- v-once指的是这个动态数据值渲染一次,渲染完就是静态数据了 -->
			<div v-once >初始值{{n}}</div>
			<div >{{n}}</div>
			<button @click="n++">点击++</button>
			<!-- 有v-pre的元素,vue在渲染页面时会跳过,加快渲染进度, -->
			<div v-pre>静态的数据</div>
		</div>
		<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
	</body>
	<script type="text/javascript">
	Vue.config.productionTip = false
	
	let vm = new Vue({
			el:'#block',
			data:{
				data:'hello',
				data2:'<h2>hello</h2>',
				data3:'potkiss',
				n:0
			}
		})
		
	</script>
</html>
举报

相关推荐

0 条评论