vue笔记(二)(未完待续...)

vue笔记(二)

4.两种数据绑定

数据驱动:当数据发生变化的时候,用户的界面发生相应的变化,开发者不需要手动去修改dom,vue框架会自动的根据数据渲染页面。这也是声明式渲染的概念。

1.响应式数据

只能由代码改变UI或者只能由UI改变代码,其核心原理是数据劫持

对响应式的理解:核心原理是数据劫持,即通过object.defineProperty,vue在初始化数据时,会传入一个data对象,内部会默认对data对象进行遍历,使用object.defineProperty将这些属性全部转换为getter/setter。vue内部会对数据进行劫持操作,进而追踪依赖,在属性被访问和修改时通知变化。vue3.0版本用的是代理对象(new Proxy())来做响应式的,我们访问数据访问的是代理对象的数据。

//vue响应式数据实现的基本原理:
var data={}
var temp=""//临时存储空间
Object.defineProperty(data,"msg",{
   set(v){
      temp=v//设置data对象的msg属性时,将临时存储空间存储为msg的值v
      h1.innerHTML=v//将页面显示的数据更改为设置的值v
   },
   get(){
      return temp//获取data对象的msg属性时,返回临时存储空间temp的值,即是设置的msg属性值
   }
})
data.msg=100;//改变data对象的msg属性值
2.双向数据绑定

如果数据源改变,页面就相应的改变,并且页面的数据改变(用户交互),数据源的数据也改变------- 双向数据绑定

实现方式:在响应式的基础上利用input事件,监听输入框,当用户与页面交互时,获取输入的值,并将值绑定到data容器中。

vue提供的系统指令:v-model ----- 其本质上是一个语法糖

vue实现双向数据绑定的原理:
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
//利用object.defineProperty实现双向数据绑定
<body>
    <div id="app">
      <input type="text" id="txt">
      <p id="show"></p>
    </div>
</body>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'txt', {
        get: function () {
            return obj
        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
    })
</script>
==========================
//利用input事件实现
<div id='app'>
		    <input type="text" :value="msg" @input="input1"/> 
			<button @click="send">发送</button>
			<button @click="change1">change1</button>
		</div>
		<script>
			new Vue({
				el: '#app',
				data: {
					msg:"1234"
				},
				methods:{
					send(){
						console.log(this.msg)
					},
					change1(){
						this.msg="abcd"
					}
					input1(e){//input事件:当input输入框的value值改变时会被触发
					 	this.msg=e.target.value
					 }
				}
			})
		
		</script>
		
		==================
		//vue的v-model实现方式 -----本质是语法糖
			<div id='app'>
			<input type="text" v-model="msg"/>
			<button @click="send">发送</button>
			<button @click="change1">change1</button>
		</div>
		<script>
			new Vue({
				el: '#app',
				data: {
					msg:"1234"
				},
				methods:{
					send(){
						console.log(this.msg)
					},
					change1(){
						this.msg="abcd"
					}
				}
			})
		</script>

5.vue简介

vue是由阿里的尤雨溪开发的渐进式前端框架。是目前最流行的框架之一。

vue是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,vue采用自底向上增量开发的设计。vue的核心库只关注视图层,容易学习,容易与其他库或者已有的项目整合。另一方面,vue完全有能力驱动采用单文件组件和vue生态系统支持的库开发的复杂单页应用。vue的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件。

前端三大框架:

​ Vue.js、React.js、Angular.js

  • vue.js:数据驱动和组件化开发,轻量级,分层渐进式框架;
  • React.js:数据驱动和组件化开发,灵活性很高;
  • Angular.js 1.0版本数据驱动 ,2.0加上了组件化开发,重量级框架;大型企业OA办公

对vue渐进式的理解:

渐进式可以理解为主张最少。
Angular是主张较多的框架,使用angular必须使用它的模块机制,必须使用它的依赖注入- 必须使用它的特殊形式定义组件。它带有较强的排它性,很难在项目的某个部分单独使用angular开发。
React,它的主张主要是函数式编程的理念,是软性的侵入。
Vue是渐进的,没有强主张。项目的某个部分可以单独使用vue实现,它不会对整个项目产生干涉,具有很好的兼容适应性。也可以使用vue全家桶进行整个项目的开发。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mc3HcbGg-1634041049565)(E:\新建文件夹\OneDrive\桌面\图片\vue.jpg)]

vue全家桶的概念:

  • vue.js:vue的核心库
  • vue-cli vue官方脚手架,用于搭建vue开发环境
  • vueRouter:vue官方的路由管理器
  • vuex:vue应用程序开发的状态管理模式
  • vue-resource:网络请求
  • UI框架

6.MVC和MVVM

1.MVC:

在实际应用开发场景中,开发者常用的一种设计模式是MVC(比如egg.js中的MVC设计模式):

  • M(Model):数据模型层。是应用程序中用于处理应用程序数据逻辑的部分,模型对象负责在数据库中存取数据。
  • V(View):视图层。是应用程序中处理数据显示的部分,视图是依据模型数据创建的。
  • C(Controller):控制层。是应用程序中处理用户交互的部分,控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。
2.MVVM:
  • M(Model):模型层。就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model。
  • V(View):视图层。就是展现出来的用户界面。
  • VM(ViewModel):视图模型层。就是与界面(view)对应的Model。因为,数据库结构往往是不能直接跟界面控件一一对应上的,所以,需要再定义一个数据对象专门对应view上的控件。而ViewModel的职责就是把model对象封装成可以显示和接受输入的界面数据对象。

7.条件渲染

v-if和v-show

当指令绑定的变量为true时,该标签显示,为false时,标签不显示

区别:

  • v-if是将元素从dom中删除
  • v-show是通过操作元素的display属性实现隐藏和显示
visibility: hidden; 不脱离文档流的
display:none        脱离文档流
v-if                删除节点
v-show              display:none	

底层设计的区别导致v-if和v-show的使用场景有区别
v-if具有较高的切换消耗,会导致页面回流,所以常用于不常切换的业务中
v-show具有较高的性能消耗,节点不显示在页面上,但是依然存在于dom树中,所以常用于需要频繁被切换显示的场景。
  <div id="app">
			<div v-if="flag">666</div>
			<div v-show="flag">777</div>
		</div>
		<script type="text/javascript">
			new Vue({
				el: "#app",
				data: {
					flag:false
				}
			})
v-if和v-else的使用:
<div v-if="flag==1">111</div>	
<div v-else-if="flag==2">666</div>
<div v-else>222</div>

8.循环渲染

指令:v-for

语法:

<div id='app'>
			
			<!-- <div>{{arr[0]}}</div>
			<div>{{arr[1]}}</div>
			<div>{{arr[2]}}</div>
			<div>{{arr[3]}}</div> -->
			<div v-for="el in arr">				
				<h1>{{el}}</h1>
				<h2>666666</h2>
			</div>
			<div v-for="el in arr2">
				<div v-if="el.id!=124">
					<h1>{{el.text}}</h1>
					<h2>时间:{{el.ctime}}</h2>
				</div>				
			</div>
		</div>
		<script>
			new Vue({
				el: '#app',
				data: {
					arr:["hello","vue","js","css"],
					arr2:[{id:"123",text:"内容1",ctime:"2021-10-12 14:28"},
					{id:"124",text:"内容2",ctime:"2021-10-11 14:28"},
					{id:"125",text:"内容3",ctime:"2021-10-10 14:28"}
					]
				}
			})
			
		</script>
		
		
		
//v-for会将绑定该指令的标签的子元素都克隆相应的次数

v-if和v-for同时使用会导致的问题:

在老版本的vue中,允许v-if和v-for放在同一个标签中,没有先后顺序的要求,但是v-for会先被执行。

在新版本的vue中,v-if和v-for写在同一个标签中可能会导致出现语法错误。

渲染过程:对arr每一项先做map循环判断v-if给出的条件,再做一遍for 循环渲染。

这样会导致:arr 数组新增一项数据时,会对每一项再做一遍v-if 循环,然后for 循环渲染。

解决方案:将v-for写在最外层的标签上

<div id='app'>
			<div v-for="(el,index) in arr">
				<h1 v-if="index!=1">{{el}}</h1>							
			</div>
		</div>
		<script>
			new Vue({
				el: '#app',
				data: {
					arr:["a","b","c"]
				}
			})
		</script>
		
//如果if和for套在一层,数据容器发生变化时,if会重新判断一遍
嵌套的写法 数据容器变化时 if只判断新增的数据
这样当arr 数组某一项数据发生变化时,只对新增的数据进行v-if 判断,节约渲染效率

这样会引起新的问题:外层for的div会也创建一个挂载到DOM中

解决方案:微信小程序采用block元素,vue采用template标签。该标签会在渲染后被移除,其实就是dom操作中的fragment

	<div id='app'>
			<template v-for="(el,index) in arr">
				<h1 v-if="index!=1">{{el}}</h1>							
			</template>
		</div>
		<script>
			new Vue({
				el: '#app',
				data: {
					arr:["a","b","c"]
				}
			})
		</script>
		
		
		==========
	DOM:
			var fnode=document.createDocumentFragment()//冰容器
			for(let i=0;i<10000;i++){
			var s=document.createElement("span")
			s.innerHTML=new Date()
			fnode.appendChild(s)
		 document.body.appendChild(s)
		 }
		 document.body.appendChild(fnode)
v-for中key的意义:

data中for循环的容器数据个数发生变化时,会跟for中的vm节点个数作比较
如果数据多了,会在vm节点后面增加对应数量的节点,并不会重新创建所有节点,然后vm去更新对应的DOM
然后就去刷新数据到界面: 按照for的数据容器中的数据顺序来渲染如果用户以前操作过旧节点,那么新数据顺序可能会出现跟旧节点顺序不匹配的效果(旧节点跟旧数据没有对应起来)

解决方案:for循环时把数据跟创建的节点利用给元素绑定唯一key值(key只能绑定唯一的值,一般来说是后端获取的id)

原理:因为vue在刷新页面组件时,会把旧节点跟新vm节点做比较,如果要增加节点,并不会删除旧节点,而是复用
这样会导致节点跟数据没有绑定关系而重新渲染,用key可以将数据与节点绑定起来。

	<div id="app">
			<h1>活动:1分钟内从1万件商品中选择你喜欢10件送给你</h1>
			<button type="button" @click="add">加载新的商品</button>
			<button>提交</button>
			<div>
				<div v-for=" (item,index) in arr" :key="item.id">
				<input type="checkbox" name="goods"/>	
				 {{item.name}}=={{item.info}}
				</div>
			</div>
		</div>
		
		<script type="text/javascript">
			new Vue({
				el:"#app",
				data:{
					arr:[
						{id:10001,name:"鞋子1",info:"这个鞋子好1"},
						{id:10002,name:"鞋子2",info:"这个鞋子好2"},
						{id:10003,name:"鞋子3",info:"这个鞋子好3"},
						{id:10004,name:"鞋子4",info:"这个鞋子好4"}
					],
					count:5
				},
				methods:{
					add(){
						//网络请求 然后把新商品添加到arr中
						//假装网络请求了新数据	
						var result=this.count++				
						this.arr.unshift({id:result,name:"鞋子"+result,info:"这个鞋子好"+result})
					}
				}
			})
       </script>	

",info:“这个鞋子好2”},
{id:10003,name:“鞋子3”,info:“这个鞋子好3”},
{id:10004,name:“鞋子4”,info:“这个鞋子好4”}
],
count:5
},
methods:{
add(){
//网络请求 然后把新商品添加到arr中
//假装网络请求了新数据
var result=this.count++
this.arr.unshift({id:result,name:“鞋子”+result,info:“这个鞋子好”+result})
}
}
})


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值