Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

05 监听子属性和新加的属性 #7

Open
xwjie opened this issue Jan 9, 2018 · 0 comments
Open

05 监听子属性和新加的属性 #7

xwjie opened this issue Jan 9, 2018 · 0 comments

Comments

@xwjie
Copy link
Owner

xwjie commented Jan 9, 2018

实现监听子属性以及新加的属性

测试页面

测试文件 Xiao\example\render-data-child.html

<!DOCTYPE html>
<html>
<head>
	<title>Xiao框架之helloworld</title>
	<script src="../dist/xiao.js"></script>
	<style>
	</style>
</head>
<body>

<div id="demo1">
</div>

<script>

	var app = new Xiao({
		template: '<h1>变量1:{{message}}。<br/>变量2:{{submsg.msg}}。</h1>',
		data: {
			message: '当你看到这句话的时候,表示框架工作正常',
			submsg: {
				msg:'终于好了',
			},
			another: '这个变量没有在模板里面'
		} 
	});
	
	app.$mount("#demo1");

	var count = 1;

	setInterval(function(){
		app.message = `第${count}次修改了数据`;
		app.submsg.msg = `第${count}次修改了data里面的子节点数据`;
		count++;
	}, 2000);

	setTimeout(function(){
		console.log('隔了3秒后修改了模板无关的变量数据');
		app.another = "修改了她不应该重新渲染";
	}, 3000);

</script>

</body>
</html>

实现过程

设置 get 方法的时候,递归 监听 value 。记住,此时需要把依赖关系登记起来。

  // 监听子属性
  let childOb = observe(val)

和 设置 set 方法的时候:

      // 监听新设置进来的数据
      childOb = observe(newVal) 

最终代码

/**
 * Define a reactive property on an Object.
 */
export function defineReactive(
  obj: Object,
  key: string,
  val: any,
  shallow?: boolean
) {
  const property = Object.getOwnPropertyDescriptor(obj, key)

  if (property && property.configurable === false) {
    return
  }

  // xwjie 这里应该可以考虑优化,如果和模板没有关系,dep不需要创建
  const dep = new Dep()

  log(`[observer]定义观察者,属性:${key}`)

  // cater for pre-defined getter/setters
  const getter = property && property.get
  const setter = property && property.set

  // 监听子属性
  let childOb = observe(val)

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      // log('[observer]get方法被调用,属性:' + key)
      const value = getter ? getter.call(obj) : val

      if (Dep.target) {
        dep.depend()

        // 子属性的依赖关系也要登记起来
        if (childOb) {
          childOb.dep.depend()
        }
      }

      return value
    },

    set: function reactiveSetter(newVal) {
      // log('[observer]set方法被调用,属性:' + key)
      const value = getter ? getter.call(obj) : val

      /* eslint-disable no-self-compare */
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }

      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }

      // 监听新设置进来的数据
      childOb = observe(newVal) //!shallow &&

      dep.notify()
    }
  })
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant