Vue基础
一、渐进式框架二、两个核心点相应的数据绑定视图组件三、虚拟DOM四、MVVM模式五、Vue实例六、声明渲染七、指令八、模板
·
一、渐进式框架
二、两个核心点
- 响应的数据绑定
当数据发生改变时,自动更新视图。
是利用Object.defineProperty中的getter和setter代理数据。
var obj = {};
Object.defineProperty(obj,"a",{
value:10, //obj.a值为10
writable:false, //表示不可写
enumerable:false, //表示不可遍历
configurable:false, // 表示不可配置,即不能改变writable:false或者enumerable:false
get(){ // 当读取obj.a时会自动调用该函数,不管是什么都返回1000
return 1000;
},
set(){ // 当写入obj.a时会自动调用该函数,不管写什么都写入2000
return 2000;
}
});
Vue监控的数据变化就是监控的getter和setter得变化。变化就去重新渲染。
2. 视图组件
UI页面映射出一个组件树
组件可重用,可维护性好。
三、虚拟DOM
要改变一个DOM节点,才能把视图重新渲染出来。但这样会发生重排重绘,十分耗费性能。
虚拟DOM就是使用js去模拟一个节点。把js封装出来,变为一个真实的DOM。(使用js对象的嵌套形式模仿出一个html文档),通过底层的算法可以让重排重绘只发生在局部。优化页面。
// 模仿实现
function VElement(tagName,prop,children){ //参数为( "",{},[] )
// 判断是不是一个VElement的一个实例
if ( !(this instanceof VElement) ) {
return new VElement(tagName,prop,children);
}
// 假如用户没有属性prop,就没有给参数prop,进行兼容性处理
if( Object.prototype.toString.call(prop) === "[object Array]" ){
children = prop;
prop = {};
}
this.tagName = tagName;
this.prop = prop;
this.children = children;
var count = 0; // 用于记录虚拟节点个数
this.children.forEach(function(child,index){
if(child instanceof VElement){
// 如果子节点是一个虚拟节点,让总节点数加上子节点的子子节点数
count += child.count;
}
count ++;
});
this.count = count;
}
var dom = VElement("div",[VElement("div",["Vue牛逼"])]);
console.log(dom);
// 结果 虚拟DOM 相当于:<div><div>Vue牛逼</div></div>
// VElement {
// tagName: 'div',
// prop: {},
// children: [ VElement { tagName: 'div', prop: {}, children: [Object], count: 1 } ],
// count: 2 }
VElement.prototype.render = function(){
//rander函数将虚拟DOM转换为真实DOM
var dom = document.createElement(this.tagName);
var children = this.children;
var prop = this.prop;
for(var item in prop){
dom.setAttribute(item,prop[item]);
}
children.forEach( function(child,index){
if(child instanceof VElement){
var childDom = child.render();
}else{
var childDom = document.createTextNode(child);
}
dom.appendChild(childDom);
} );
return dom;
};
console.log(dom.render());
// 结果
// <div>
// <div>Vue牛逼</div>
// </div>
Vue底层时使用深度遍历优先算法转化为dom节点的
四、MVVM模式
M:model 数据模型
V:视图模板
VM:视图模型
VM层是中间层,连接数据模型和视图模板,由Vue实现。由vm代替以前的dom操作,只操作vm层
五、Vue实例
- 数据绑定
- 计算属性与侦听器
- 属性绑定
- 条件渲染 v-if v-show
- 列表渲染 v-for
- 绑定事件 事件修饰符 表单
<!DOCTYPE html>
<html>
<head>
<title>Vue</title>
</head>
<body>
<div id="demo">
{{name}} <!-- 数据绑定 -->
{{changeName}} <!-- 绑定计算属性的changeName -->
<!-- 通过v-bind:命令绑定属性名 -->
<!-- 其中class和style比较特殊,要使用数组形式:v-bind:class="[class1]" -->
<!-- 也可以通过对象的形式:v-bind:class="{class1:classBoolean}",其中class1是class名,而classBoolean才是绑定的变量,为true时才将class1绑定上 (实现添加或删除class) -->
<span v-bind:data="message" v-bind:id="id">{{name}}</span>
<!-- v-show 控制节点显示或隐藏,ifshow是绑定的数据,为true时显示,false时内部设为display:none -->
<!-- v-if也是控制节点显示隐藏,但v-if为false时,是删除节点 -->
<!-- 频繁切换时,考虑重拍重绘,v-if会更浪费性能 -->
<div v-show='ifshow'>条件渲染演示</div>
<!-- items是一个数组,会被v-for遍历,item就是遍历的结果 -->
<span v-for="item in items">{{item.title}}</span>
<!-- v-on绑定事件,click为事件名,click1为回调函数,写在methods内 -->
<button v-on:click="click1">点击</button>
<!-- 事件修饰符,在事件的回调函数后添加一个.enter,代表只有按下回车键才会触发该事件 -->
<input type="text" name="" v-on:keyup.enter="keyup1">
表单,初始化时,会将value的值默认填入input框
<input type="text" name="" v-model="value">
</div>
<script type="text/javascript" src="https://vuejs.org/js/vue.js"></script>
<script type="text/javascript">
//在vue当中,需要一个dom节点挂载Vue,并且vue语法只在此节点内生效
var vm = new Vue({
el: "#demo", // el对应dom节点的id,就把Vue挂载在了dom节点上了
data:{ // 数据绑定 所有数据都会绑定到实例vm上
name:"tanjw",
message : 123,
id:"demo1",
ifshow:false,
items:[{
title:"18"
},{
title:"20"
}],
value:123
},
// 当name变化时,就会在computed内找一些相关属性
computed:{ // 计算属性,内部写一些函数
changeName: function(){ // 当通过控制台改变vm实例name时,changName也会随着变化,监控name的变化
return "my name is " + this.name;
}
},
methods:{
// 专门处理异步回调函数
click1:function(){
console.log(this);
},
keyup1:function(){
console.log(this.value);
})
</script>
</body>
</html>
- 生命周期(1最后五分钟)
六、模板
- html模板
- 字符串模板
- render函数
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="demo">
{{message}}
<!-- 双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,需要使用 v-html 指令: -->
<div v-html="message"></div> <!-- 这是两层div -->
<!-- 当使用message时,{{id}}并没有被当做一个绑定数据,而是一个字符串,这就是v-html模板的不足 -->
<div v-html="message1"></div> <!-- 这是两层div -->
<!-- 为弥补次不足,Vue又引入了字符串模板,写在template中 -->
<!-- 但template的内容会覆盖掉整个被挂载的div -->
</div>
<!-- 一般会把template单独拿出来,如下 -->
<script type="x/template" id="template1">
<div>hello Vue{{id}}</div>
</script>
<script type="text/javascript" src="https://vuejs.org/js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#demo",
data:{
message:"<div>hello Vue</div>", //当绑定的数据是一个节点时,在浏览器并没有被解析成为一个节点,而是一个字符串
// 显而易见,我希望<div>hello Vue</div>要被解析成为一个节点
message1:"<div>hello Vue{{id}}</div>",
id:"true"
},
template:"#template1",
// render()函数模板,创建一个虚拟节点
render(creatElement){
var dom = creatElement("",{},[]);
// 或者写成
creatElement("div",{
attrs:{id:"1"},
class:{ // class特殊,所以单独拿出来写
vue1:true
},
domProps:{ // 会覆盖掉第三位的[]参数,优先级最高
innerHTML:"任意"
}
},["任意"]);
return dom; //return dom 就相当于调用了render函数,会将此节点渲染到页面
// 不管以何种方式底层都是调用了render函数
// 但直接使用虽然会增加性能,但无法使用v-if v-for等指令,但可以通过原生JavaScript的if-else和map重写render函数
}
});
</script>
</body>
</html>
更多推荐
已为社区贡献1条内容
所有评论(0)