2021.11.28 vue render渲染函数的基本约束 (11)

render渲染函数的基本约束

VNode必须唯一组件树中的所有VNode 必须是唯一的。这意味着,下面的渲染函数是不合法的:

render(createElement) {
  let my_el = createElement('h1',
    {
      on: {
        click: (e) => {
          this.msg += 'ok'
        }
      }
    },
    this.msg)
  return createElement('div', [my_el, my_el])
}

如果你真的需要重复很多次的元素/组件,你可以使用工厂函数来实现。运行一次createElement方法, 就会创造一个新的VNode

render: function (createElement) {
  return createElement('div',
    Array.apply(null, { length: 20 }).map(function () {
      return createElement('h1', '111')
    })
  )
}

js替换模板功能

js替换模板功能之if/for指令

只要在原生的JavaScript 中可以轻松完成的操作,Vue 的渲染函数就不会提供专有的替代方法。比如,在模板中使用的v-if 和v-for:

标准的V-for指令

<body>
  <div id='app'>
    <h1 v-for='item in items'>{{item}}</h1>
  </div>

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        items: [1, 2, 3]
      }
    })
  </script>
</body>

这些都可以在渲染函数中用 JavaScript 的 if/else 和 map 来重写:

render(h) {
  if (this.items.length) {
    return h('div', this.items.map(item => {
      return h('h1', item)
    }))
  } else {
    return h('p', '没有找到items')
  }
}

js替换模板功能之v-model指令

<!--v-model基本使用-->
......
<input type="text" v-model='name'>
......
data: {
   name: 'yzh'
},
<!-- v-bind和input事件实现v-model-->
......
<input type="text" :value='name' @input='fn'>
......
data: {
  name: 'yzh'
},
methods: {
  fn(e) {
    console.log(e);
    this.name = e.target.value
  }
}

使用render函数时,实现v-model双向数据绑定

components: {
  cpn: {
    data() {
      return { value: '1234' }
    },
    methods: {
      handleClick() {
        this.value = '改变value'
      }
    },
    render(h) {
      let that = this
      console.log(this);
      return h('div', [
        h('input', {
          domProps: {
            value: this.value
          },
          on: {
            input: function (e) {
              that.value = e.target.value
            }
          }
        }),
        h('h1', 'value:' + this.value),
        h('button', {
          attrs: { type: 'button' },
          domProps: { innerHTML: 'btn' },
          on: {
            click: this.handleClick
          }
        })
      ])
    }
  }
}

js替换模板功能之事件和按键修饰符

对于 .passive、.capture和 .once这些事件修饰符, Vue提供了相应的前缀可以用于on:

修饰符前缀
.passive&
.capture!
.once~
.capture.once 或 .once.capture~!

修饰符对应的处理函数也是可用的

过滤器

局部过滤器

Vue.js允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind 表达式 。过滤器应该被添加在JavaScript 表达式的尾部,由“管道”符号指示:

<body>
  <div id='app'>
    <cpn></cpn>
  </div>

  <template id="cpn">
    <div>
      {{msg|gl}}
      <h1>{{num|jg}}</h1>
      <test :msg="msg|gk"></test>
    </div>

  </template>

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              msg: 'hello world',
              num: 1000
            }
          },
          filters: {
            gl(value) {
              if (!value) return ''
              value = value.toString()
              return value.charAt(0).toUpperCase() + value.slice('1')
            },
            gk(value) {
              console.log(value);
              if (!value) return ''
              return value.toString().split('').shift().toUpperCase()
            }
          }
        }
      }
    })
  </script>
</body>

全局过滤器

Vue.filter(“过滤器名称”,fn)

<body>
  <div id='app'>
    <cpn></cpn>
    {{info|aa}}
    <cpn1></cpn1>
  </div>

  <template id="cpn">
    <div>
      <h1>{{msg|aa}}</h1>
    </div>
  </template>
  <script src='./js/vue.js'></script>
  <script>
    Vue.filter('aa', function (value) {
      if (!value) return ''
      return value.toString().charAt(0).toUpperCase() + value.slice(1)
    })

    const app = new Vue({
      el: '#app',
      data: {
        info: 'aaaaa'
      },
      components: {
        cpn1: {
          template: '<div>{{info|aa}}</div>',
          data() {
            return { info: 'bbb' }
          }
        },
        cpn: {
          template: '#cpn',
          data() {
            return { msg: 'hello world' }
          }
        }
      }
    })
  </script>
</body>

当全局过滤器和局部过滤器重名时,会采用局部过滤器。

Vue.filter('aa', function (value) {
  if (!value) return ''
  return value.toString().charAt(0).toUpperCase() + value.slice(1)
})
......
filters: {
  aa(value) {
    if (!value) return ''
    return value.toString().charAt(1).toUpperCase() + value.slice(1)
  }
}
......

串联过滤器

过滤器函数总接收表达式的值(之前的操作链的结果) 作为第一个参数。

<body>
  <div id='app'>
    <cpn></cpn>
  </div>

  <template id="cpn">
    <div>
      <h1>{{msg|aa|bb}}</h1>
    </div>
  </template>
  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        info: 'aaaaa'
      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return { msg: 'hello world' }
          },
          filters: {
            aa(value) {
              if (!value) return ''
              return value.toString().charAt(0).toUpperCase() + value.slice(1)
            }, //Hello world1
            bb(value) {
              console.log(value);
              if (!value) return ''
              return value.toString().charAt(1).toUpperCase() + value.slice(1)
            }
          }
        }
      }
    })
  </script>
</body>

在这个例子中,aa被定义为接收单个参数的过滤器函数,表达式msg的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数bb,将 aa的结果传递到bb 中。

过滤器是 JavaScript函数,因此可以接收参数:

 <h1>{{msg|aa('val1',info)}}</h1>

这里,aa被定义为接收三个参数的过滤器函数。其中msg 的值作为第一个参数,普通字符串’val1’ 作为第二个参数,表达式info 的值作为第三个参数。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值