MVVM框架主要包括三个部分,View(视图 DOM) ViewModel(通讯 链接视图和数据的中间件) Model (数据 JavaScipt对象)
当数据发生变化 ViewMdel 能够观察到数据这种变化,通知到对应的视图做自动更新,当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,实现了数据的双向绑定;
针对具有复杂交互逻辑的前端应用
提供基础架构抽象
通过Ajax数据持久化,保证前端用户体验
数据驱动 + 组件化的前端开发 社区完善
如果没有 ViewModel 数据和视图发生改变 就需要手动改变(容易出错),使用了vue.js后,省去了手动操作DOM变化的部分,只需要改变数据,Vue.js 通过 Directives指令 对Dom做一层封装,当数据发生变化,会通知指令修改对应的DOM,数据驱动DOM变化,DOM是数据的自然映射;还会对操作做些监听,当修改视图的时候,Vue.js监听到视图的变化,从而改变数据;
上面图片来自 Vue.js官网
原理:有一份数据a.b 在一个Vue对象实例化的过程中,会给 a.b 这份数据 通过es5的 Object.defineProperty(直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象)添加getter,setter,同时会对模板做编译,解析生成指令对象,每个指令对象都会关联 一个Watcher,当我们对对应的指令做操作时 就会触发getter ;再次改变a.b的值,会触发setter。会通知对应关联的Watcher,当Watcher发生改变时,由于指令是对DOM的封装,所以会调用原生DOM的方法更新视图,从而完成数据改变视图更新;
上图 左侧是一个页面 被拆分成小的区块,每个区块对应一个组件,组件可以嵌套,最终组合成完成页面;
页面上每个独立的可视/可交互区域视为一个组件
每个组件对应一个工程目录,组件所需要的各种资源在这个目录下就近维护
页面不过是组件的容器,组件可以嵌套自由组合形成完整的页面
基本语法:
var wm = new Vue({
el:"#app" ,//配置模板(界面)
data:{
//配置数据
title:'哈哈哈哈哈 小菜鸡'
},
})
el:是 DOM 元素中的 id;
data 用于定义属性
{{ }} 用于输出对象属性和函数返回值
案例代码:实现一个简易商品管理功能 (可复制到编辑器中运行)
{{title}}
商品名称:
商品数量:
-
名称:{{item.name}} 库存:{{item.stock}}
页面效果:
methods:用于定义的函数,可以通过 return 来返回函数值
v-model:来实现双向数据绑定
v-for:循环语句,后面会详细讲解;
指令是带有 v- 前缀的特殊属性,指令用于在表达式的值改变时,将某些行为应用到 DOM 上
示例:判断文字颜色,如果true 颜色为红色 false为绿色
我是帽子
v-bind 指令可以缩写:
我是帽子
{{msg}}
用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值
{{messsage}}
修饰符是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定
{{messsage}}
注意,不是输入框不能输入字符串,是这个数据是数字
相当于调用了event.stopPropagation()方法
相当于调用了event.preventDefault()方法,比如表单的提交、a标签的跳转就是默认事件
message
不管点击几次,只是执行一次
button class="color" @click.once="showMessage">点击我
过滤器是对即将显示的数据进行进一步的筛选处理,然后显示,并没有改变原来的数据,只是在原有数据基础上产生新的数据;过滤器分 全局过滤器和局部过滤器
Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化。由"管道符"指示, 格式如下:
{{数据属性名称 | 过滤器名称}}
{{数据属性名称 | 过滤器名称(参数值)}}
语法:
Vue.filter('过滤器名称', function (value1[,value2,...] ) {
//逻辑代码
})
示例:把 hellovue 变成大写 (传递一个参数的全局过滤器)
{{messsage | capitalize}}
语法:
new Vue({
filters: {
'过滤器名称': function (value1[,value2,...] ) {
// 逻辑代码
}
}
})
示例:
{{n1 | param(n2,n3)}}
下面代码 v-if 指令将根据表达式 show 的值(true 或 false )来决定是否插入 p 元素
哈哈哈哈
我可能要隐藏
可以用 v-else 给v-if添加一个 else块
OK
No
1
2
3
No number
注意:v-else,v-else-if必须跟在v-if 或者v-else-if之后
v-for指令需要以 site in sites形式的特殊语法,sites是源数据数组,site是数据组元素迭代的别名
v-for渲染列表:
- {{site.name}}
可以提供第二个的参数为键名
- {{key}}:{{message}}
运行结果:
第三个参数为索引
- {{index}}:{{key}}:{{message}}
用v-for实现九九加法表:
{{m}}+{{n}}={{m+n}}
运行结果:
原始字符串:{{message}}
反转后字符串:{{reversedMessage}}
说明:上面案例中 声明了一个计算属性 reversedMessage ,提供的函数将用作属性 vm.reversedMessage 的 getter ,vm.reversedMessage 依赖于 vm.message,在 vm.message 发生改变时,vm.reversedMessage 也会更新
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter
{{ reversedMessage }}
在运行 vm.site = '哈哈哈 你好呀'; 时,setter 会被调用, vm.message 和 vm.explain 也会被对应更新
可以使用methods来代替computed 效果是一样的,computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性
通过watch来响应数据的变化,
计数器:{{ count }}
实现简单购物车:
序号
名称
价格
购买数量
操作
{{iphone.id}}
{{iphone.name}}
{{iphone.price}}
{{iphone.count}}
总价:${{totalPrice()}}
errorClass 是始终存在的,isActive 为 true 时添加 activeClass 类
哈哈哈哈哈哈
也可以吧样式绑定到一个对象上:
哈哈哈哈哈哈
{{count}}
...
...
.enter
.tab
.delete (捕获 "删除" 和 "退格" 键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta