vue框架
- 构建用户界面的渐进式框架
- 采用自底层向上增量开发的设计
- 核心库只关注视图层
- 当与单文件组件和vue生态系统支持的库结合使用时,也完全能够为复杂的单页应用程序提供驱动
- vue通过api 来进行统一性的管理,可以让整个团队的代码都用统一的风格和方法标准去运作
- 在封装组件时通过Props和Event 两个标准性的原则去调用
一个todo-list应用集成了两个事件,两条data数据就能完成了,通过Template 里的Html模版能清楚的观察到绑定信息,数据联动和实时改动:
- v-model 里的msg和实例data里存放的数据进行了绑定
- @keyup.enter = "push" 对键盘事件keyup进行舰艇,同时用enter 修饰符进行enter按键进行监听,当触发methods里的push函数,想这个list列表里添加一条object数据
- 通过v-for指令循环出整个list里的数据,循环出相对应的节点数
- 点击每个节点的时候执行deleteItem事件,删除对应的节点
<template>
<!-- todo-list模版 -->
<div id="todo-list">
<!-- 定义input输出标签,双向绑定输出数据msg,对keyup进行监听绑定按钮事件push事件 -->
<input type="text" v-model.trim="msg" @keyup.enter="push">
<ul>
<!-- v-for指令循环整个list里面的数据 -->
<li v-for="(item,index) in list" :key="index" @click="deleteItem(index)">
{{index}}{{item.name}}
</li>
</ul>
</div>
</template>
<script>
export default {
name:'todo-list',
data(){
return(
{
msg:"",
list:[],
}
)
},
methods:{
push(){
//向list数组中push新输入的input的msg信息
this.list.push({name:this.msg});
this.msg = ""
},
deleteItem(index){
//删除所对应的index节点
this.list.splice(index,1) }
}
}
</script>对于往时操作dom写法与当前vue数据驱动区别:
- 数据渲染,会通过第三方的模版引擎,如artTemplate,Jade等等,渲染完成之后再append到根元素中
- vue只是通过一个v-for指令循环所有对应的节点,先前只要再Html中写好循环模版
- 执行事件,需要选取DOM元素,对DOM元素addEventListener事件进行函数监听
- Vue直接通过你的Template集成模版在需要发生事件的元素上直接绑定事件,只要执行一个v-on结合你需要绑定的事件,所有原生的事件都直接
- 需要存储数据时,需要定一堆变量,有局部变量和全局变量,导致后续的变量难以维护,甚至可能会导致变量名冲突,作用域调用错误,无法准确定位到正确的数据源
- Vue通过data选项,用每个属性去保存渲染的数据和临时过度的数据,用统一data选项去保存,让使用者一目了然
- 所有执行的函数,无论是事件所需要执行的,还是封装所需要调用的函数,通过函数式声明在script标签内写入,代码量大了,也会存在变量名冲突 和无法准确的定位方法
- Vue通过Methods选项专门为事件所执行的函数和所封装需要调用的函数,就像垃圾桶一样,有一个准确的可投放的位置,需要找到执行和所需要调用的函数,直接可以准确定位到Methods选项
- 平时我们要对有些数据进行一些处理,比如说 去除有后空格,按键的空位,都要通过js去过滤或者判断
- Vue提供大量的修饰符封装了这些过滤和判断,让开发少写代码,把时间投入业务,只需要用.修饰符
用户进行某个操作 -> 反馈到VM处理(可导致Model变动) -> VM层改变,通过绑定关系直接更新页面对应位置的数据
可以简单理解:数据驱动不是操作节点的,而是通过虚拟的抽象数据来直接更新页面。主要这点,数据驱动框架才得以有较快的运行速度
VUE模式
通过 {{ }} 绑定文本节点,data里的动态数据与Props静态数据进行一个映射关系,当data中的属性或者Props中的属性有变动,以上两者里的每个数据都是行为操作需要的数据或者模版view需要渲染的数据,一旦其中一个属性发生变化,则所有关联的行为操作和数据渲染的模版上的数据同一时间进行同步变化,这种数据驱动的模式更渐变于大型应用开发。只要合理的组织数据和代码,就不会显得后续皮软
事件驱动
事件驱动一定程度弥补了数据驱动的不足
在DOM操作:通过特定的选择器查找到需要操作的节点 -> 给节点添加相应的事件监听
响应用户操作:用户执行某事件(点击,输出,后退等) -> 调用JavaScript来修改节点
缺点:系统会越来越庞大,频繁找节点和修改节点,效率过低
数据驱动
读取模版,同时获得数据,并简历VM(view-model)的抽象层 -> 在页面进行填充
MVVM对应三个层
M-Model 可以理解为 数据层
V-View 视图
VM-ViewModel 视图模型(虚拟层) 可以与V层进行数据绑定; (V 和M 双向互动)
data选项
当一个实例创建的时候,Vue会将其响应系统的数据放在data选项中,当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。初始定行的行为代码也都会随着响应系统进行一个映射,而data中的数据在实例中可以任意改变,不受任何影响,前提必须数据要跟逻辑相辅相成
<template>
<div>
<p v-if="boolean">true</p>
<p v-for="value in obj ">{{vallue}}</p>
<p v-for="item in list">{{item}}</p>
<p>{{StringMsg}}</p>
<p>{{NumberMsg}}</p>
</div>
</template>
<script>
export default {
data(){//data数据
return {
obj:{a:'1',b:'2',c:'3'}, //对象obj,用v-for遍历
list:["a","b","c"], //数组list,用v-for遍历
boolean:true, //布尔值,用v-if判断
StringMsg:"hello world", //字符串对象
NumberMsg:2.4 //数字对象 }
}
}
</script>
动态数据data 和 静态数据Props 对比:
相同点:
- 两者选项里都可以存放各种类型的数据,当行为操作改变时,所有行为操作所用到的和模版所渲染的数据同事都会发生同步变化
不同点
- data被称为动态数据的原因,在各自实例中,在任何情况下,都可以随意改变它的数据类型和数据结构,不会被任何环境所影响
- props被称为静态数据的原因,在各自实例中,一旦初始化被定义好类型时,基于Vue的单向数据流,在数据传递时始终不能改变它的数据类型
- 更为关键的是,对数据单向流的理解,props的数据都是通过父组件或者更高级的组件数据或者字面量的方式进行传递的,不允许直接操作改变各自实例中的props数据,而是需要通过别的手段,改变传递源中的数据
在运行代码时,data选项已经进入了Vue的响应系统。model(数据层)和View(视图层)进行了对应的响应任何数据类型都可以定义
当用户发生点击操作的时候,同事可以把StringMsg,NumberMsg的数据对调,充分说明了 “无论值和类型都可以进行随意转换”。
总结:
- data里的数据是灵活的
- 可以定义任何数据类型
- 可以改变任何数据类型
- 当数据变化时,视图和行为绑定的数据都会同步改变
视图与数据映射
data数据:
<template>
<div>
<p>{{StringMsg}}</p>
<p>{{NumberMsg}}</p>
<button @click="changeData">改变数据</button>
</div>
</template>
<script>
export default {
data(){
return{
StringMsg:"hello world",
NumberMsg:24
}
},
methods:{
changeDate(){
this.StringMsg=24,
this.NumberMsg="hello world"
}
}
}
</script>
此.vue就是一个实例,在data定义了两种数据,String类型,Number类型,同时还在methods定义了changeDate() 事件
Props
使用props传递数据作用域是孤立的,它是父组件通过模版传递而来,想接受父组件传来的数据,需要通过props来进行接受
子组件需要显示的声明接受父组件传递来的数据的{ 数量,类型,初始值 }
简单的接受可以通过数组的类型来接受 props:['props']
父组件:
<!-- 父组件 -->
<template>
<div>
<!-- 在父组件html中写入子组件demo -->
<!-- 分别将父组件的数据msgData mathData绑定,传递给子组件 -->
<demo :msg="msgData" :math="mathData"></demo>
</div>
</template>
<script>
//引入子组件Demo
import Demo from './demo.vue';//
export default {
data(){
//设置父组件的data数据
return {
msgData:"父传给子",
mathData:2
}
},
conponents:{
Demo
}
}
</script>
子组件
<!-- 子组件 -->
<template>
<div class="demo">
<p>{{msg}}</p>
<p>{{math}}</p>
</div>
</template>
<script>
export default {
name:'demo',
props:['msg','math']//接受父组件传递的值
}
</script>
: == v-bind
:msg = msgData
//msg 第一个参数必须要与子组件的props同名 : props:['msg']
//msgData 则是父组件中需要向子组件传递的数据
在子组件需要通过显示定义好需要从父组件中接受那些数据,同样的在父组件中,在子组件模版中v-bind来传递子组件中需要显示接受的数据
props可以显示定义一个或者一个以上的数据,对于接受的数据,可以是各种数据类型,同样可以传递一个函数