Vue高级用法
  # # Vue高级用法
总结Vue的高级用法,其中绝大部分也应用在yi-ui (opens new window) (opens new window)组件库中。
# # v-model (opens new window) (opens new window)
    <input v-model="searchText">
    
    <!-- 等价于:-->
    <input
      v-bind:value="searchText"
      v-on:input="searchText = $event.target.value"
    >
    
 1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# # Vue.extend (opens new window) (opens new window)
使用基础 Vue 构造器,创建一个“子类”。简单说,就是基于一个Object可返回Vue的子类,可实例化后进行挂载。
    Modal.alert = content =>
        new Promise(resolve => {
            const Ctor = Vue.component('UModal')
            if (!Ctor) return
    
            let instance = new Ctor({
                propsData: { content, type: ModalType.ALERT, showClose: false, cancelButton: '' }
            })
            instance.$on('ok', () => resolve())
            instance.open()
        })
    
    // 实例open
    open() {
        if (!this.$el) this.$mount(document.createElement('div'))
    }
    
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# # provide/inject (opens new window) (opens new window)
provide 和 inject 主要为高阶插件/组件库提供用例。与 React 的上下文特性很相似。实现原理:Vue2.x源码分析 - inject/provide
    export default {
        name: 'u-form',
        props: {
            title: String,
            labelWidth: String,
            contentWidth: String,
            okButton: { type: String, default: '确定' },
            cancelButton: { type: String, default: '取消' }
        },
        provide() {
            return {
                uForm: this
            }
        }
    }
    
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    export default {
        name: 'u-form-item',
        props: {
            label: String,
            error: String,
            required: Boolean,
            tip: String
        },
        data() {
            return {
                leftSty: {},
                rightSty: {}
            }
        },
        inject: ['uForm'],
        created() {
            this.uForm.labelWidth && (this.leftSty.width = this.uForm.labelWidth)
            this.uForm.contentWidth && (this.rightSty.width = this.uForm.contentWidth)
        }
    }
    
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# # vm.$nextTick() (opens new window) (opens new window)
将回调延迟到下次 DOM 更新循环之后执行。实现原理:Vue2.x源码分析 - Vue.nextTick
尽管MVVM框架并不推荐访问DOM,但有时候确实会有这样的需求,尤其是和第三方插件进行配合的时候,免不了要进行DOM操作。而nextTick就提供了一个桥梁,确保我们操作的是更新后的DOM。
    // template
    <template>
        <h ref="someElement">{{message}}</h>
    </template>
    
    <script>
    export default {
        data: () => { message: 'oldValue'}
        methods: {
            example: function () {
            // 修改数据
            this.message = 'changed'
            // DOM 还没有更新。此时如果拿DOM元素的innerHTML,依然会是'oldValue'
            this.$nextTick(function () {
                // DOM 现在更新了,可以拿到最新的DOM元素了
                this.$refs['someElement'].innerHTML // 此时可以拿到最新的innerHTML值:'changed'
            })
            }
        }
    }
    </script>
    
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# # this.$once('hook:beforeDestroy',callback) (opens new window) (opens new window)
程序化的事件侦听器。实现原理:Vue2.x源码分析 - 组件系统 (opens new window) (opens new window)
    mounted: function () {
      var picker = new Pikaday({
        field: this.$refs.input,
        format: 'YYYY-MM-DD'
      })
    
      this.$once('hook:beforeDestroy', function () {
        picker.destroy()
      })
    }
    
 1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# # 其他
# # 组件prop为boolean
如果prop是Boolean值,如果prop有展示但未赋值意味着 true。
    <blog-post is-published></blog-post>
    
    <!-- 等价于 -->
    <blog-post :is-published="true"></blog-post>
    
 1
2
3
4
5
2
3
4
5
# # vm.$attrs/vm.$listeners
这两个变量挂载到组件实例this上,避免组件属性逐层透传。
    // base component: u-link.vue
    <a v-bind="$attrs"
       v-on="$listeners">
       <slot></slot>
    </h>
    
    // high component
    <u-link name="123" attr1="123">test</u-link>
    
    // 等价于
    <a name="123" attr1="123">
       <slot></slot>
    </a>
    
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# # 待更
# # watch deep/immediate
# # scss /deep/
编辑  (opens new window)