Vue---起步
一、Vue是渐进式框架
只关注视图层(view),一点一点去使用。
二、vue中的两个核心点
1. 响应的数据绑定
当数据发生改变 -> 自动更新视图。
利用Object.definedProperty中的setter/getter代理数据,监控对数据的操作,发生了改变就立即重新渲染。不兼容ie8。关于Object.definedProperty()方法。
单向绑定就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新。如果用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。
实现数据绑定的做法有以下几种:
发布者-订阅者模式(backbone.js):顾名思义,就是有订阅者和发布者,两者的功能,订阅是请求在某些事件(event)到达时可以通知它并执行对应的动作(action),而发布则相对的是向订阅告知事件(event)已经到达,你可以执行对应的动作(action)了。
脏值检查(angular.js)
数据劫持(vue.js):vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调。
2. 组合的视图组件
ui页面映射为组件树
划分组件可维护,可重用,可测试
三、虚拟DOM
运行js是很快的,但是大量的DOM操作却很慢,用js的做法是当某一个数据发生改变的时候,拼接我们的结构,用innerHtml一次性再渲染一遍。更新数据时重新渲染整个页面,即没有改变数据的地方也重新渲染了DOM 节点,造成很大的资源浪费。
利用在内存中生成与真实DOM对应的数据结构,这个在内存中生成的结构成为虚拟DOM。当数据发生改变时,只渲染改变的地方,而不是重新渲染整个DOM树。
第一步:模板
<ul id="my-id"> <li v-for='item in list'>{{item}}</li> </ul>
第二步:compile,模板调用内部的渲染函数。把模板中的标签拿出来调用createElement去生成这些标签。
第三步:render,形成虚拟dom树。也就是一个对象
第四步:create,编译成一个真实的dom。
四、MVVM模式
M:Model 数据模型
V:view 视图模板
VM:view-Model 视图模型
数据在M层,页面呈现在V层,相互独立的。VM层联系V和M。把数据绑定并呈现在V层;V与用户交互,页面发生改变,VM监听发生改变的事件,改变M层数据,再重新渲染V层。
五、Vue实例
通过vue这个构造函数创建根实例。需要传入选项对象,包含挂载元素,数据,模板,方法等等。
<div id="demo"> <span v-on:click = "clickHandle">{{ message }}</span> </div> <script> var data = { message: 'hello pp' } var vm = new Vue({ el: '#demo', data: data, methods: { clickHandle: function() { alert('点击啦'); }, } }) </script>
1.每个vue实例都会代理其data对象的所有属性,这些被代理的属性是响应的,但新添加的属性不具备响应。
2.vue实例自身的属性和方法
以$开头,如$el $data ...在控制台打印出vm对象如下:
六、vue是声明式渲染
声明式:只需要声明在哪里,做什么,无需关心如何实现。
命令式:需要具体代码表达在哪里,做什么,如何实现。
七、指令
指令是一种特殊的自定义行间属性;当表达式改变时相应的将某些行为应用到DOM上;在vue中,指令以v-开头。
vue中的内置指令:
1. v-text
<span v-text="msg"></span> <!-- 和下面的一样 --> <span>{{msg}}</span>
2. v-html
<div v-html="html"></div> -------js------- var data = { html:'<b>加粗</b>' }
在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html
,永不用在用户提交的内容上。
3.v-show
根据表达式真假,切换元素的 display
CSS 属性。当条件变化时该指令触发过渡效果。
<div id="demo"> <h1 v-show="ok">Hello!</h1> </div> <script> var data = { ok: false } var vm = new Vue({ el: '#demo', data: data }) </script>
v-show与v-if的区别
1)v-show
指令与v-if指令都是根据条件展示元素。用法大致一样,不同的是带有 v-show
的元素始终会被渲染并保留在 DOM 中,只是简单地切换元素的 CSS 的display属性
。
2) v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
2)v-show
不支持 <template>
元素,也不支持 v-else
。
4.v-if
<h1 v-if="ok">Yes</h1> <h1 v-else>No</h1>
5.v-else
使用方法如上。
限制:前一兄弟元素必须有 v-if
或 v-else-if
6.v-else-if
限制:前一兄弟元素必须有 v-if
或 v-else-if
。必须使用特定语法 alias in expression
<div v-if="type === 'A'">
A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div>
7.v-for
必须使用特定语法 alias in expression。
<div id="demo"> <div v-for="item in items"> <li>{{item.text}}</li> </div> </div> <script> var data = { items: [ {text: 'pp'}, {text: 'haha'} ] } var vm = new Vue({ el: '#demo', data: data }) </script>
8.v-on
绑定事件监听器。缩写@
9.v-bind
动态地绑定一个或多个特性,或一个组件 prop 到表达式。缩写:
10.v-model
在表单控件或者组件上创建双向绑定。
11.v-pre
跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
<span v-pre>{{ 不会被编译 }}</span>
12.v-cloak
13.v-once
只渲染元素和组件一次。
八、模板
分为html模板,字符串模板,模板render函数
1.html模板
基于DOM的模板,模板都是可解析的有效的HTML
插值类型:
1)文本插值:使用"Mustache"语法(双大括号){{value}}。
作用:替换实例上的属性值,当值改变时,插值内容会自动更新。
2)原生的html:双大括号输出的是文本,不会解析html。
3)属性:使用v-bind来绑定属性,可以响应变化。
<!-- 模板 --> <div id="demo" v-bind:custom="abc"> //绑定属性;可以简写成 :custom="abc" <div>{{html}}</div> //不解析html <div v-html="html"></div> //会解析html,将html插入了div中
</div> <script> let obj = { html:"<div>hello</div>" abc:1 } var vm = new Vue({ el:"#demo", data:obj }); </script>
4)使用javascript表达式:写简单的表达式,不要写语句。不建议这么写,以后使用计算属性。
{{3+1}}
{{ true ? "yes" : "no" }}
2.字符串模板
1)模板会替换挂载元素,挂载元素的内容都将会被忽略;
<div id="demo"> <span>haha</span> //被忽略 </div> <script> let obj = { abc:1 } var str='<div>hello vue,{{abc}}</div>'; var vm = new Vue({ el:"#demo", data:obj, template:str }); </script>
2)字符串模板的根节点只能有一个;比如下面的写法会报错。
var str='<div>hello vue,{{abc}}</div><span>pp</span>';
3)也可以将html做成一个片段,不放在字符串里,而是写在一个script标签中,设置type="x-template";
<script type="x-template" id="temp"> <div>hello vue,{{abc}}</div> </script> <script> let obj = { abc:1 } var vm = new Vue({ el:"#demo", data:obj, template:"#temp" }); </script>
3.模板-render函数
render 选项对象的属性
createElement(标签名,[数据对象],子元素); 其中子元素为文本或数组。
<div id="demo"></div> <script> var data = { } var vm = new Vue({ el: '#demo', data: data, render(createElement) { return createElement( "ul", [ createElement('li', 1), createElement("li", 2) ] ) } }) </script>
如何给标签添加class:
<style> .red{ color:red; } </style> <div id="demo"> <span v-bind:class='{red:addClass}'>haha</span> </div> <script> let obj = { addClass:true }; var vm = new Vue({ el:"#demo", data:obj }); </script>
也可以通过模板render函数来添加class:
<style> .red{ color:red; } </style> <div id="demo"></div> <script> let obj = { }; var vm = new Vue({ el:"#demo", data:obj, render(createElement) { return createElement( "ul", { class: { red: true } }, [ createElement("li", 11), createElement("li", 22) ] ) } }); </script>
其他操作:
class:{} //绑定class,和v-bind:class一样的API style:{} //绑定样式,和v-bind:style一样的API attrs:{} //添加自定义行间属性 domProps:{} //DOM元素属性 on:{} //绑定事件 nativeOn:{} //监听原生事件 directives:{} //自定义命令 scopedSlots:{} //slot作用域 slot:{} //定义slot名称 key:"key" //给元素添加唯一标识 ref:"ref" //引用信息
举个栗子:
var vm = new Vue({
el:"#demo",
data:obj,
render(createElement){
return createElement(
"ul",
{
class:{
bg:true
},
style:{
fontSize : '50px'
},
attrs:{
abc:"abc"
},
domProps:{
innerHTML:"<li>我是html</li>"
}
},
[
createElement("li",1),
createElement("li",2),
createElement("li",3)
]
);
}
});
关于vue应该掌握的:
基础:vue实例,模板语法,计算属性,class和style绑定,条件和列表渲染,事件处理器,表单控件绑定,组件。
进阶:vue插件编写,mixin混合,过渡效果,自定义指令,vue-router路由系统的使用,vueX状态管理器。
构建工具:javascript运行环境nodejs,模块管理和打包工具webpack,vue-cli脚手架配置。