计算属性与侦听器

1. computed 选项

模板不支持表达式, 模板尽量精简, 把表达式定义到 computed 里面, 可以处理跟data相关的计算.

例子1:

点击按钮的时候,a更新,并触发页面上的 aDouble 的dom更新.

js:

  1. var bs = bui.store({
  2. scope: "page", // 用于区分公共数据及当前数据的唯一值
  3. data: {
  4. a: 2,
  5. },
  6. methods: {
  7. changeA: function (e) {
  8. this.a++;
  9. }
  10. },
  11. computed: {
  12. aDouble: function () {
  13. // a 改变的时候,会触发乘法,并更新到dom
  14. return this.a * 2
  15. }
  16. }
  17. })

html:

  1. <!-- 绑定事件,点击改变 a的值,并且会触发 aDouble 跟着一起改变 -->
  2. <div class="bui-btn" b-click="page.changeA">点击1次,a+1,结果乘以2</div>
  3. <div class="container-xy">
  4. a: <b b-text="page.a" ></b>
  5. 结果: <b b-text="page.aDouble"></b>
  6. </div>

例子2:

通过b-modelfirstName,lastName 渲染出来, 并且当input输入修改的时候,会触发fullName的修改. fullName 支持两种方式设置.

  • function
  • object

区别: function方式,fullName的修改不会重新赋值到 firstName, lastName. 如果要实现双向联动绑定, 则采用object方式, 以对象的方式. 查看例子3.

js:

  1. var bs = bui.store({
  2. scope: "page", // 用于区分公共数据及当前数据的唯一值
  3. data: {
  4. firstName: "Hello",
  5. lastName: "BUI",
  6. },
  7. computed: {
  8. fullName: function() {
  9. var val = this.firstName + ' '+ this.lastName;
  10. return val;
  11. }
  12. },
  13. })

html:

  1. <ul class="bui-list">
  2. <li class="bui-btn bui-box clearactive">
  3. <label class="bui-label">姓: </label>
  4. <div class="span1">
  5. <div class="bui-value"><input type="text" value="" placeholder="请输入" b-model="page.firstName"></div>
  6. </div>
  7. </li>
  8. <li class="bui-btn bui-box clearactive">
  9. <label class="bui-label">名: </label>
  10. <div class="span1">
  11. <div class="bui-value"><input type="text" value="" placeholder="请输入" b-model="page.lastName"></div>
  12. </div>
  13. </li>
  14. </ul>
  15. <!-- firstName,lastName改变就会触发 fullName 的绑定 -->
  16. <div class="container-xy">
  17. 结果: <b b-text="page.fullName"></b>
  18. </div>

例子3:

双向联动修改, bs.fullName = "BUI Best" 设置以后, 会把firstName,lastName 重新赋值.

js:

  1. var bs = bui.store({
  2. scope: "page", // 用于区分公共数据及当前数据的唯一值
  3. data: {
  4. firstName: "Hello",
  5. lastName: "BUI",
  6. },
  7. computed: {
  8. // 2. 双向联动 fullName 改变,会触发各自改变 firstName,lastName,
  9. fullName: {
  10. get: function () {
  11. return this.firstName + ' ' + this.lastName
  12. },
  13. set: function (newValue) {
  14. var names = newValue.split(' ')
  15. this.firstName = names[0]
  16. this.lastName = names[names.length - 1]
  17. }
  18. }
  19. },
  20. })

例子4:

登录按钮的状态, 当firstName,lastName 有值的时候, 登录按钮可以点击; disabled 状态为false, 当没有值的时候, disabled 为 true 不能点击.
disabled computed 绑定在登录按钮的b-class上, 有值没值的时候, 会去修改class有没有 disabled 样式名.

js:

  1. var bs = bui.store({
  2. scope: "page", // 用于区分公共数据及当前数据的唯一值
  3. data: {
  4. firstName: "",
  5. lastName: "",
  6. },
  7. computed: {
  8. disabled: function() {
  9. // 注意: 这里需要先缓存下来值再进行判断.
  10. var firstName = this.firstName,
  11. lastName = this.lastName;
  12. if( firstName && lastName ){
  13. return false;
  14. }else{
  15. return true;
  16. }
  17. }
  18. },
  19. })

html:

  1. <ul class="bui-list">
  2. <li class="bui-btn bui-box clearactive">
  3. <label class="bui-label">姓: </label>
  4. <div class="span1">
  5. <div class="bui-value"><input type="text" value="" placeholder="请输入" b-model="page.firstName"></div>
  6. </div>
  7. </li>
  8. <li class="bui-btn bui-box clearactive">
  9. <label class="bui-label">名: </label>
  10. <div class="span1">
  11. <div class="bui-value"><input type="text" value="" placeholder="请输入" b-model="page.lastName"></div>
  12. </div>
  13. </li>
  14. </ul>
  15. <div class="container-xy">
  16. <div b-class="page.disabled" class="bui-btn primary round">登录</div>
  17. </div>

注意: disabled方法里面, 有个注释提醒, 为何要先缓存? 因为经常我们习惯性的直接去判断? 比如:

  1. if( this.firstName && this.lastName ){
  2. return false;
  3. }else{
  4. return true;
  5. }

当初始值 firstNamelastName 为空的时候, if 只拿到 firstName 不正确, 就会跳到 true, 导致 lastName 改变的时候,不会重新执行判断条件. 这在computed是经常见到的错误, 如果你希望这些值都会改变 disabled, 那应该先进行缓存.

效果预览

查看效果

2. watch 选项

watch 可以用来监听 data 里面的键值的变化以后处理其它事情. watch函数返回当前监听变量的新值跟旧值newVal,oldVal. 比方下面的例子.

例子4:

  1. var bs = bui.store({
  2. scope: "page", // 用于区分公共数据及当前数据的唯一值
  3. data: {
  4. a: 2,
  5. b: 1,
  6. },
  7. methods: {
  8. changeA: function (e) {
  9. this.a++;
  10. }
  11. },
  12. watch: {
  13. a: function (newVal,oldVal) {
  14. this.b = this.a * 2;
  15. }
  16. }
  17. })

html:

  1. <!-- 绑定事件,点击改变 a的值,并且会触发 b 跟着一起改变 -->
  2. <div class="bui-btn" b-click="page.changeA">点击1次,a+1,结果乘以2</div>
  3. <div class="container-xy">
  4. a: <b b-text="page.a" ></b>
  5. 结果: <b b-text="page.b"></b>
  6. </div>

computed 的例子也可以用watch实现.

  1. var bs = bui.store({
  2. scope: 'page',
  3. data: {
  4. firstName: 'Hello',
  5. lastName: 'BUI',
  6. fullName: 'Hello BUI'
  7. },
  8. watch: {
  9. firstName: function (val) {
  10. this.fullName = val + ' ' + this.lastName
  11. },
  12. lastName: function (val) {
  13. this.fullName = this.firstName + ' ' + val
  14. }
  15. }
  16. })

除了 watch 选项之外,您还可以使用命令式的 bs.watch 方法。可以实现分离式监听.

  1. bs.watch("firstName",function(val){
  2. this.fullName = val + ' ' + this.lastName
  3. })
  4. bs.watch("lastName",function(val){
  5. this.fullName = this.firstName + ' ' + val
  6. })

效果预览

查看效果