<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>BRACKETS 入门</title>
<meta name="description" content="Brackets 互动式入门指引。">
<link rel="stylesheet" href="main.css">
<script src="./vue.js"></script>
<script src="./text.js"></script>
<style>
.class1{
width: 100px;
height: 50px;
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<!-- <div v-html='name' :class='{class1:result}'></div>
<div v-if="result">
{{name | myFilter('你好啊')}}
</div>
<input type="checkbox" v-model='result' @click="show">
<template v-if='result'>
<div>{{updateDate}}</div>
</template>
<div v-show='result'>v-show</div>-->
<div>{{age2}}</div>
</div>
<script>
var data={name:'123',result:false,value:'2020',age:'18'}
var v=new Vue({
el: '#app',
data: data,
methods:{
show:function(){
//alert('ddd'+this.value)
var that=this;
setInterval(function(){
that.name=that.name+1;
},500)
}
},
computed:{
updateDate:function(){
},
age2:{
set:function(value){
this.age=value;
},
get:function(){
return this.age+'当今';
}
}
},
filters:{
myFilter:function(str,str2){
return str.split('').reverse().join(',')+this.data.value
}
}
})
var s=v.$watch('name',function(){
console.log('我在变化')
})
</script>
</body>
</html>
看源码$watch:
Vue.prototype.$watch = function (
expOrFn,
cb,
options
) {
var vm = this;
if (isPlainObject(cb)) {
return createWatcher(vm, expOrFn, cb, options)
}
options = options || {};
options.user = true;
var watcher = new Watcher(vm, expOrFn, cb, options);
if (options.immediate) {
try {
cb.call(vm, watcher.value);
} catch (error) {
handleError(error, vm, ("callback for immediate watcher \"" + (watcher.expression) + "\""));
}
}
return function unwatchFn () {
watcher.teardown();
}
};
方法一:
var watcher = new Watcher(vm, expOrFn, cb, options);
Watcher源码:
var Watcher = function Watcher (
vm,
expOrFn,
cb,
options,
isRenderWatcher
) {
this.vm = vm;
if (isRenderWatcher) {
vm._watcher = this;
}
vm._watchers.push(this);
// options
if (options) {
this.deep = !!options.deep;
this.user = !!options.user;
this.lazy = !!options.lazy;
this.sync = !!options.sync;
this.before = options.before;
} else {
this.deep = this.user = this.lazy = this.sync = false;
}
this.cb = cb;
this.id = ++uid$2; // uid for batching
this.active = true;
this.dirty = this.lazy; // for lazy watchers
this.deps = [];
this.newDeps = [];
this.depIds = new _Set();
this.newDepIds = new _Set();
this.expression = expOrFn.toString();
// parse expression for getter
if (typeof expOrFn === 'function') {
this.getter = expOrFn;
} else {
this.getter = parsePath(expOrFn);
if (!this.getter) {
this.getter = noop;
warn(
"Failed watching path: \"" + expOrFn + "\" " +
'Watcher only accepts simple dot-delimited paths. ' +
'For full control, use a function instead.',
vm
);
}
}
this.value = this.lazy
? undefined
: this.get();
};
重点在: this.vm = vm;
if (isRenderWatcher) {
vm._watcher = this;
}
vm是Vue的继承实例
vm._watcher=this,当前的this是Watcher实例;也就是后边返回的watcher对象
因此vue实例也能访问_watcher进而调用Watcher实例的teardown函数,这里不建议这样调用因为根据变量命名来看是不建议外部调用的。
v._watcher.teardown();
方法二:
return function unwatchFn () {
watcher.teardown();
}
返回的是一个函数,函数体 watcher.teardown();是什么?继续看源码
*/
Watcher.prototype.teardown = function teardown () {
if (this.active) {
// remove self from vm's watcher list
// this is a somewhat expensive operation so we skip it
// if the vm is being destroyed.
if (!this.vm._isBeingDestroyed) {
remove(this.vm._watchers, this);
}
var i = this.deps.length;
while (i--) {
this.deps[i].removeSub(this);
}
this.active = false;
}
};
看注释// remove self from vm's watcher list 移除自身的来自vm的所有监听器 vm是谁? vm是Vue的的父类实例 即Vue.prototype
因此我们只需执行$watch()返回的函数即可,s();