响应式数据
响应式数据:如果内存中的数据变化了 页面UI也会动态跟着刷新 这种数据就是响应式数据
响应式数据设计原理:
vue2.0 采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue3.0 --使用es6 proxy 代理了data对象
响应式数据实现原理:
<div id="app">
<!-- <h1 v-html="title">{{msg}}</h1> -->
<h1 v-html="title"></h1>
<p>{{msg}}</p>
<button @click="fn">change1</button>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
title: "hello",
msg: "666"
},
methods: {
fn() {
for (let i = 0; i < 10000; i++) {
this.title = i
}
}
}
})
</script>
<div id="myapp">
<h1 id="title"></h1>
<p id="msg"></p>
</div>
<script>
function MyVue(option) {
let _myvm = {}
//劫持
let arr = Object.keys(option.data) //["title","msg"]
// _myvm[arr[0]]=option.data[arr[0]]
// _myvm[arr[1]]=option.data[arr[1]]
for (let i = 0; i < arr.length; i++) {
Object.defineProperty(_myvm, arr[i], {
set(v) {
//劫持
option.data[arr[i]] = v
//响应-刷新页面
let title = document.querySelector(option.el + " #title")
let msg = document.querySelector(option.el + " #msg")
title.innerHTML = _myvm["title"]
msg.innerHTML = _myvm["msg"]
},
get() {
return option.data[arr[i]]
}
})
_myvm[arr[i]] = option.data[arr[i]]
}
return _myvm
}
var myvm = new MyVue({
el: "#myapp",
data: {
title: "mytitle66666",
msg: "mymsg666666",
obj: {
age: 10,
name: "karen"
},
arr: [10, 230, 5]
}
})
双向数据绑定
双向数据绑定:代码改变UI,UI也能改变代码
双向数据绑定的实现: 2种方式
1.自己实现,vue可以自己实现(没必要) 微信开发可以自己实现(只能自己实现) 利用input事件,用户交互的时候,获取用户输入的值,然后把值绑定到data容器中
2.系统指令:v-model
vue实现数据双向绑定的原理:
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue数据双向绑定实现:
//利用 Object.defineProperty 自己实现双向数据绑定
<body>
<div id="app">
<input type="text" id="txt">
<p id="show"></p>
</div>
</body>
<script type="text/javascript">
var obj = {}
Object.defineProperty(obj, 'txt', {
get: function () {
return obj[txt]
},
set: function (newValue) {
document.getElementById('txt').value = newValue
document.getElementById('show').innerHTML = newValue
}
})
document.addEventListener('keyup', function (e) {
obj.txt = e.target.value
})
</script>
过滤器
filter主要用于数据展示之前的处理 过滤器只能用在v-bind或者插值表达式中
<div id="app">
<p>{{a}}</p>
<p>{{timerformatter(birth)}}</p>
<p>{{birth|tool|tool2}}</p>
<p>{{birth|tool3(100,200)}}</p>
<a :href="url|tool4">baidu</a>
<!-- <p v-text="birth|tool3"></p> -->
<button @click="change1">change1</button>
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
a:"测试",
birth:"2007-02-03",
url:"www.baidu.com"
},
methods:{
change1(){
this.a="66666"
},
timerformatter(str){
console.log("调用了函数timerformatter--methods")
let age=new Date().getFullYear()-new Date(str).getFullYear()
return age+"岁"
}
},
filters:{
tool(str){
console.log("调用了函数tool--filters")
let age=new Date().getFullYear()-new Date(str).getFullYear()
return age+"岁"
},
tool2(str){
if(parseInt(str)>18){
return "可以喝酒:"+str
}else{
return "禁止进入:"+str
}
},
tool3(arg1,arg2,arg3){
console.log(arg1,arg2,arg3)
return "hello"
},
tool4(url){
return "http://"+url
}
}
})
</script>