网站开发系统绿色版,装修的网站都有哪些,网站系统维护一般要多久,手机网站建设 小程序Vue#xff1a;模板 MVVM 模板插值语法指令语法 MVVMdefineProperty数据代理 模板
Vue实例绑定一个容器#xff0c;想要向容器中填入动态的值#xff0c;就需要使用模板语法。模板语法分为插值语法和指令语法。
插值语法
插值语法很简单#xff0c;使用{{}}包含一… Vue模板 MVVM 模板插值语法指令语法 MVVMdefineProperty数据代理 模板
Vue实例绑定一个容器想要向容器中填入动态的值就需要使用模板语法。模板语法分为插值语法和指令语法。
插值语法
插值语法很简单使用{{}}包含一个表达式Vue会把表达式的结果替代这个值渲染到HTML中。
示例
div idrooth3hello{{name}}/h3
/div
script typetext/javascriptnew Vue({el:#root,data:{name:jack,}})
/script以上代码最终会生成hellojack标题{{name}}被替换为了data.name。
此外任意表达式都可以填入{{}}中比如
div idrooth3hello{{1 1}}/h3h3hello{{x y ? a : b}}/h3
/div比如{{1 1}}最终会变成2三元表达式会进行计算或者说函数调用也可以在{{}}内部执行。
另外的{{}}内的表达式可以读取到Vue示例的data下的所有属性。 指令语法
插值语法能处理的情况是非常有限的比如标签属性。
现在有一个a标签要动态的指定url如果使用插值语法可能写出如下内容
div idroota href{{addr.url}}{{addr.name}}/a
/div
script typetext/javascriptnew Vue({el:#root,data:{addr:{name:百度,url:http://www.baidu.com,}}})
/script但是这是一个错误的语法{{}}作为标签属性时不会被解析。
此时就要使用指令语法v-bind指令可以将一个属性值解析为表达式。
div idroota v-bind:hrefaddr.url{{addr.name}}/a
/div以上代码中herf属性前面加上了v-bind:那么后面的内部不再被解析为字符串而是当作表达式处理此时addr.url就会被解析了。
一个v-bind只能作用于其后面的那个属性比如以下情况
div idroota v-bind:hrefaddr.url idaddr.name{{addr.name}}/a
/div在idname中addr.name不会被当作表达式而是当作字符串因为其前面没用v-bind指令。
v-bind指令可以简写为一个冒号:。
div idroota :hrefaddr.url{{addr.name}}/a
/div数据绑定
刚才的v-bind称为单向数据绑定简单来说就是如果Vue实例中的属性值改变了那么HTML的内容也会改变。但是如果HTML的内容改变了Vue实例的内容不会改变。
示例
div idroot单向数据绑定input typetext :valueinnerbr/
/div
script typetext/javascriptnew Vue({el:#root,data:{inner:hello world}})
/script这是一个输入框输入框的value属性被绑定为了inner的内容。 初始时inner和输入框的内容相同尝试修改inner的值 修改后输入框的内容也随之改变了。
但是如果修改输入框的内容 此时inner的内容不会改变这就是单向数据绑定Vue实例的值会影响HTML但是HTML不会影响Vue实例。
指令v-model可以使用双向数据绑定
div idroot双向数据绑定input typetext v-model:valueinnerbr/
/div此时修改输入框也会反过来修改Vue实例的值 但是不是所有标签都可以使用v-model只有可以输入元素类似表单的元素可以使用其他标签使用会导致报错并且标签会丢失。
v-model:也可以简写因为v-model:后面的属性往往是value表示元素内容所以可以省略:value直接写为v-model
div idroot双向数据绑定input typetext v-modelinnerbr/
/divMVVM
MVVM是一种软件开发模型在Vue设计时参考了这个模型其分为三个组成部分
Model模型View视图ViewModel视图模型 Model就是一个JavaScript的表达式简单来说就是数据比如在{{}}中包含一个表达式在v-bind后面的 内部的表达式这些表达式都会产生一个值变成具体的数据。
View对应上图中最左侧的DOM它表示一个可以被用户看到的页面这个页面通过Vue解析产生。
ViewModel是上图的中间部分它表示Vue实例对象这也是整个MVVM的核心其分为两个区域。
首先是Data Bindings数据绑定它接收Model产生的值并把它填入到View视图中这样就产生了最终的页面。这对应了之前的v-bind指令或者{{}}插值他们都是接收JavaScript表达式产生的值并填入到元素中。
另一个是DOM Listeners元素监听它监听页面中的元素当元素发生变化时返过来影响Model内部的值。这对应的了v-model双向数据绑定当DOM元素发生更改时修改Vue.data的内容。
在Vue中JavaScript表达式可以看到Vue实例的所有属性和方法包括原型链。
输出一下Vue实例
const vm new Vue({el:#root,data:{name:hello world,num: 123}
})
console.log(vm)由于Vue实例在MVVM中对应VM所以接收时常把变量命名为vm。
输出结果 可以看到name、num这两个属性最后都进入到了Vue实例中构造时会把data下面的所有属性都添加到Vue实例中这就是为什么在{{}}内部可以看到data下面的数据
仔细看name、num的属性值是(...)这涉及到数据代理的问题。 defineProperty
Object.defineProperty可以给一个对象添加指定的值并且可以进行属性的复杂配置。
语法
Object.defineProperty(对象, 属性, {配置对象})对象被修改的对象属性要添加的属性{配置对象}添加属性相关的配置
例如给一个对象张三添加一个age属性
let person {name:张三,sex:男,
}Object.defineProperty(person,age,{value:18,enumerable:true, //控制属性是否可以枚举默认值是falsewritable:true, //控制属性是否可以被修改默认值是falseconfigurable:true //控制属性是否可以被删除默认值是false
})在配置对象中value就是配置的属性值剩下三个属性用于对元素做一些限制。
比如说enumerable控制元素是否可以被遍历如果为false那么for in语法就无法获取到这个值或者通过keys方法无法获得属性名。
后两个比较好理解就是能否修改与删除。
这些都不是重点在配置对象中还可以配置函数其中set和get方法非常重要。
get方法在该属性被读取时调用并且读取元素值时返回指定值。
Object.defineProperty(person,age,{get(){console.log(有人读取age属性了)return 123}
})输出结果 此时可以看到age属性的值变成了(...)表示暂时未知。当访问person.age调用了get函数并拿到了返回值123。
注意get方法和value属性不能同时设置。
set方法在该属性被设置时调用接收一个参数value这就是要设置的值。
实例
Object.defineProperty(person,age,{set(value){console.log(有人修改了age属性值是,value)number value}
})输出结果 在修改值时调用了对应的set函数。
注意set不能和writable属性一起指定。
基于这两个特性它可以完成一个功能让一个对象外部的变量与该属性完全同步。
let number 18
let person {name:张三,sex:男,
}Object.defineProperty(person,age,{get(){return number},set(value){number value}
})以上代码实现了person.age与变量number的完全同步。当每次读取age时返回number的值每次设置age时把number一起修改。
基于以上操作就可以完成数据代理。 数据代理
数据代理通过一个对象代理对另一个对象中属性的操作
示例
let A {x:100}
let B {}Object.defineProperty(B,x,{get(){return A.x},set(value){A.x value}
})以上就是一个数据代理A.x与B.x是完全同步的操作B.x对应的A.x也会修改任何时候A.x B.x。
现在再回看之前Vue实例中name和num的变量值为(...)这其实就是一个数据代理。
在Vue实例的底部可以看到四个方法 这四个方法分别就是name和num的get和set此处将vm.name和vm.num进行了数据代理代理到data.name和data.num这样可以保证vm和构造时传入的data完全同步。
而传入data时有可能传了个匿名对象data本身也要进行保存其实vm把data保存为了一个vm._data的对象。 真正被代理的其实是vm._data如果不做这层代理那么用户访问数据时就要写{{ _data.name }}、{{ _data.num }}这样有点麻烦因此做了依次数据代理将他直接放到vm下这样就可以直接访问了。
另外的可以发现在_data中这两个属性的值也是(...)看着很想数据代理但这并不是。这是数据劫持当_data的数据发生改变就要渲染到HTML页面中这个过程是由数据劫持完成的。