v-if 和 v-for

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

  1. <ul v-if="items.length">
  2. <li v-for="item in items">{{ item.name }}</li>
  3. </ul>
  4. <p v-else>No items found.</p>

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

  1. <script>
  2. export default {
  3. props:{
  4. items:{
  5. type:Array,
  6. },
  7. },
  8. data(){
  9. return {
  10. }
  11. },
  12. render(h){
  13. if(this.items.length){
  14. return h('ul',this.items.map(ele =>{
  15. return h('li',{
  16. key:ele,
  17. //尽管存在prop和事件,但是有时候我们仍可能需要在JS里直接访问一个子组件,那么此时,我们可以通过 ref 特性为子组件赋予一个ID引用:
  18. ref:'li',
  19. refInFor:true,
  20. }, ele)
  21. }))
  22. }else{
  23. return h('p','No items found')
  24. }
  25. }
  26. }
  27. </script>

v-model

渲染函数中没有与 v-model 的直接对应——你必须自己实现相应的逻辑:
管网中子组件的代码

  1. props: ['value'],
  2. render: function (createElement) {
  3. var self = this
  4. return createElement('input', {
  5. domProps: {
  6. value: self.value
  7. },
  8. on: {
  9. input: function (event) {
  10. self.$emit('input', event.target.value)
  11. }
  12. }
  13. })
  14. }

父组件实现v-model

  1. <template>
  2. <div id="app">
  3. <mode :value = "value" v-model="value"></mode>
  4. {{ value }}
  5. </div>
  6. </template>
  7. <script>
  8. const mode = ()=> import('./components/mode')
  9. export default {
  10. name: 'App',
  11. components: {
  12. mode
  13. },
  14. data(){
  15. return{
  16. value:''
  17. }
  18. }
  19. }
  20. </script>

事件&案件修饰符

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

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

例如:

  1. on: {
  2. '!click': this.doThisInCapturingMode,
  3. '~keyup': this.doThisOnce,
  4. '~!mouseover': this.doThisOnceInCapturingMode
  5. }

对于所有其它的修饰符,私有前缀都不是必须的,因为你可以在事件处理函数中使用事件方法:

修饰符 处理函数中的等价操作
.stop event.stopPropagation()
.prevent event.preventDefault()
.self if (event.target !== event.currentTarget) return
按键:
.enter, .13
if (event.keyCode !== 13) return (对于别的按键修饰符来说,可将 13 改为另一个按键码)
修饰键:
.ctrl, .alt, .shift, .meta
if (!event.ctrlKey) return (将 ctrlKey 分别修改为 altKeyshiftKey 或者 metaKey)

这里是一个使用所有修饰符的例子:

  1. on: {
  2. keyup: function (event) {
  3. // 如果触发事件的元素不是事件绑定的元素
  4. // 则返回
  5. if (event.target !== event.currentTarget) return
  6. // 如果按下去的不是 enter 键或者
  7. // 没有同时按下 shift 键
  8. // 则返回
  9. if (!event.shiftKey || event.keyCode !== 13) return
  10. // 阻止 事件冒泡
  11. event.stopPropagation()
  12. // 阻止该元素默认的 keyup 事件
  13. event.preventDefault()
  14. // ...
  15. }
  16. }

自定义指令

注意此处生成的是HTML代码是让html元素使用vue的自定义指令并不是如何实现指定所需要的效果
案例:

  1. <script>
  2. // 效果
  3. // <template>
  4. // <div>
  5. // <input type="text" v-slice:5.number="content">
  6. // {{ content }}
  7. // </div>
  8. // </template>
  9. export default {
  10. data(){
  11. return {
  12. content:"12456",
  13. }
  14. },
  15. directives:{
  16. // 自定义指令 v-slice:5.number
  17. // 实现输入框中只能输入数字且长度有自定义指令的参数定义
  18. 'slice':{
  19. bind (el, binding, vnode) {
  20. const vm = vnode.context;
  21. let { value, expression, arg, modifiers } = binding;
  22. if(modifiers.number) {
  23. value = value.replace(/[^0-9]/g, '');
  24. }
  25. el.value = value.slice(0, arg);
  26. vm[expression] = value.slice(0, arg);
  27. el.oninput = function (e) {
  28. let inputVal = el.value;
  29. if(modifiers.number) {
  30. inputVal = inputVal.replace(/[^0-9]/g, '');
  31. }
  32. el.value = inputVal.slice(0, arg);
  33. vm[expression] = inputVal.slice(0, arg);
  34. }
  35. },
  36. update (el, binding, vnode) {
  37. const vm = vnode.context;
  38. let { value, arg, expression, modifiers } = binding;
  39. if(modifiers.number) {
  40. value = value.replace(/[^0-9]/g, '');
  41. }
  42. el.value = value.slice(0, arg);
  43. vm[expression] = value.slice(0, arg);
  44. },
  45. }
  46. },
  47. // 使用render函数生成最上面template代码中的效果
  48. render(h){
  49. return h('div',[
  50. h('input',{
  51. directives: [
  52. {
  53. name: 'slice', // v-slice
  54. value: this.content, // v-slice="content"
  55. expression: 'content', //字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
  56. arg: 5, // v-slice:5="content"
  57. modifiers: {
  58. number: true // v-slice:5.number="content"
  59. },
  60. }
  61. ]
  62. }),
  63. this.content,
  64. ])
  65. }
  66. }
  67. </script>

插槽

具名插槽

所使用的的api: vm.$slot.具名插槽的名字
vue官方给出解释
image.png

父组件代码

  1. <script>
  2. // html代码示例
  3. // <template>
  4. // <div>
  5. // <slot>我是默认插槽</slot>
  6. // <slot name="header">我是头部插槽header</slot>
  7. // </div>
  8. // </template>
  9. export default {
  10. render(h){
  11. return h('div',[
  12. h('base-slot',[
  13. h('p',{
  14. domProps:{
  15. innerText:'我是默认插槽'
  16. },
  17. slot:'default' // 具名插槽的name
  18. })
  19. ]),
  20. h('i',{
  21. domProps:{
  22. innerText:'我是插槽header'
  23. },
  24. slot:'header'// 具名插槽的name
  25. }),
  26. ])
  27. }
  28. }
  29. </script>

v-slotd的render代码

  1. <script>
  2. // <template>
  3. // <div>
  4. // <slot></slot>
  5. // <slot name="header"></slot>
  6. // </div>
  7. // </template>
  8. export default {
  9. data(){
  10. return{
  11. msg:'Im a slot'
  12. }
  13. },
  14. render(h){
  15. return h('div',[
  16. this.msg,
  17. this.$slots.header,
  18. this.$slots.default
  19. ])
  20. }
  21. }
  22. </script>

最终效果图
image.png

作用域插槽

获取子组件的数据,
需要使用: vm.$scopedSlots
vue官方的讲解:
image.png
父组件的代码

  1. <script>
  2. //最终的html代码
  3. // <template>
  4. // <div>
  5. // <div-slot2>
  6. // 子组件中template的代码
  7. // <div>
  8. // <strong> {{name}} </strong>
  9. // </div>
  10. // </div-slot2>
  11. // </div>
  12. // </template>
  13. export default {
  14. data(){
  15. return{
  16. obj:{
  17. name:'张三',
  18. age:'123',
  19. }
  20. }
  21. },
  22. render(h){
  23. return h('div',[
  24. this.$scopedSlots.default({
  25. obj:this.obj,
  26. })
  27. ])
  28. }
  29. }
  30. </script>

子组件的代码//

  1. <script>
  2. import baseSlot2 from './base-slot2'
  3. export default {
  4. components:{
  5. baseSlot2,
  6. },
  7. render(h){
  8. return h('div',[
  9. h('base-slot2',{
  10. scopedSlots:{
  11. default:function(props){
  12. const {name,age} = props.obj
  13. return h('strong',name)
  14. }
  15. }
  16. })
  17. ])
  18. }
  19. }
  20. </script>