2. 视图 -- Highway MVVM

通过new Highway可创建视图实例

const app = new Highway({
    $el: $('#app'),
    $scope: {
      name: 'hello world'
    }
  });

2.1 属性/方法

  • $el: 元素。
  • $template:模板字符串。
  • $scope:初始化数据。
  • $willmount:生命周期函数,编译前调用。不常用
  • $mount:生命周期函数,编译完成条用。常用
  • didmount mount之后。不常用
  • $destory:销毁函数,调用销毁当前实例。
  • $willunmount:生命周期函数,销毁前调用。不常用
  • $unmount:生命周期函数,销毁完成后调用。常用
  • didunmount unmount之后。不常用
<!-- examples/views/prop-function.html -->

<div id="app">
</div>

<script id="template" type="text/template">
  <div>i will destory after {{timeout}} seconds</div>
</script>

const app = new Highway({
  $el: $('#app'),
  $template: $('#template').html(),
  $scope: {
    timeout: 3
  },
  $willmount() {
    console.log('>>>::$willmount');
  },
  $mount() {
    console.log('>>>::$mount');

    this.$interval(() => {
     const timeout = this.$scope.$get('timeout') - 1;
     if (timeout >= 0) {
        this.$scope.$set('timeout', timeout);
     } else {
        this.$destroy();
     }
    }, 1000);
  },
  $didmount() {
    console.log('>>>::$didmount');
  },
  $willunmount() {
    console.log('>>>::$willunmount');
  },
  $unmount() {
    console.log('>>>::$unmount');
  },
  $didunmount() {
    console.log('>>>::$didunmount');
  },
});

2.2 绑定

2-2-1. 双向绑定

2-2-1-1. 安全

采用{{ property }}或者不指定{{ }}

<!-- examples/views/data-bind.html -->

// html
<p>{{msg}}</p> // '&lt;script&gt;alert(1)'

// js
const app = new Highway({
  $el: $('#app'),
  $scope: {
    msg: '<script>alert(1)'
  }
});
2-2-1-2. 非安全

采用{{{ property }}}

<!-- examples/views/data-bind.html -->

<p>{{{msg}}}</p> // '<script>alert(1)'

2-2-2. 单向绑定

模板引擎,编译时根据 scope scope更新,以便节约内存,提高性能

2-2-2-1. 安全

采用[[ property ]]

<!-- examples/views/data-bind.html -->

<p>[[msg]]</p> // '&lt;script&gt;alert(1)'
2-2-2-1. 非安全

采用[[[ property ]]]

<!-- examples/views/data-bind.html -->

<p>[[[msg]]]</p> // '<script>alert(1)'

2.4 作用域

使用$scope作为MVVM框架中的Model

<!-- examples/views/scope.html -->

<div id="app">
  <input type="text" hi-value="name"/>
  <p>{{name}}</p>
</div>  

const app = new Highway({
  $el: $('#app'),
  $scope: {
    name: 'highway'
  }
});

2-4-1. $get

使用 scope. get(prop)方法获取属性值,缩写为$get

<!-- examples/views/get.html -->

<div id="app">
  <input type="text" hi-value="user.name"/>
  <button hi-on:click="showMe">showMe</button>
</div>  

const app = new Highway({
  $el: $('#app'),
  $scope: {
    user: {
      name: 'highway'
    }
  },
  showMe() {
    // equal to this.$scope.$get
    alert(this.$get('user.name'));
  }
});

如是嵌套属性,可通过属性分割符”.”获取,例如this. scope. get(‘user.name’),$set类同

如是数组属性,可通过[int]数组下标获取,例如this. scope. get(‘students[2].name’),$set类同

2-4-2. $set

使用 scope. set(prop, value)方法获取属性值,缩写为$get

<!-- examples/views/set.html -->

<div id="app">
  <input type="text" hi-value="user.name"/>
  <button hi-on:click="changeMe">changeMe</button>
</div>  

const app = new Highway({
  $el: $('#app'),
  $scope: {
    user: {
      name: 'highway'
    }
  },
  changeMe() {
    // equal to this.$scope.$set
    this.$set('user.name', 'xiage');
  }
});

2-4-3. $watch

使用 scope. watch(prop, handler)监控属性变化,缩写为$watch,返回unwather句柄,调用可解除监听

<!-- examples/views/watch.html -->

<div id="app">
  <input type="text" hi-value="name"/>
  <p>{{name}}</p>
  <p>{{logs}}</p>
</div>  

const app = new Highway({
  $el: $('#app'),
  $scope: {
    name: 'highway'
  },
  $mount() {
    const unwatcher = this.$watch('name', (newVal, oldVal) => {
      this.$set('logs', `value changed, newVal is: ${newVal}, oldVal is: ${oldVal}`);
    });

    // remove wather
    //unwatcher();
  }
});

2-4-4. $unwatch

使用 scope. unwatch(prop, [handler])监控属性变化,可缩写为$unwatch,如handler不指定,则移除prop上所有的监听器

<!-- examples/views/unwatch.html -->

<div id="app">
  <input type="text" hi-value="name"/>
  <p>{{name}}</p>
  <p>{{logs}}</p>
  <button hi-on:click="unwatch">unwatch</button>
</div>

const app = new Highway({
  $el: $('#app'),
  $scope: {
    name: 'highway'
  },
  $mount() {
    this.$watch('name', (newVal, oldVal) => {
      this.$set('logs', `value changed, newVal is: ${newVal}, oldVal is: ${oldVal}`);
    });
  },
  unwatch() {
    this.$unwatch('name');
  }
});

2-4-5. 常量

单引号或双引号标记的值为常量,并不会从$scope值取值

<!-- examples/views/const.html -->

<div id="app">
  <input type="text" hi-value="user.name"/>
  <p>{{user.name}}</p>
  <p>{{'user.name'}}</p>
  <p>{{"user.name"}}</p>
</div>

const app = new Highway({
  $el: $('#app'),
  $scope: {
    user: {
      name: 'highway'
    }
  }
});

2-5. 类定义

可通过Highway.extend抽取为自定义类

<!-- examples/views/klass.html -->

<div id="app-0"></div>
<div id="app-1"></div>

<script id="t-app" type="text/template">
  <p>i am {{name}}</p>
</script>

const App = Highway.extend({
  $template: $('#t-app').html(),
  $scope: {
    name: 'highway'
  }
});

const app0 = new App({
  $el: $('#app-0')
});

const app1 = new App({
  $el: $('#app-1')
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值