23、$refs是什么东东?
通过在标签上设置ref属性,然后在Vue实例方法中可以通过$refs拿到这些标签,如:
<input ref="input">
methods: { focus: function () { //拿到文本框标签,调用其获取焦点方法 this.$refs.input.focus() } }
24、对于多级嵌套组件,后代组件如何拿到父级或祖父级,设置更高级别的组件的数据或方法?
使用依赖注入。
provide选项允许我们在当前组件指定我们想要提供给后代组件的数据/方法,比如:
provide: function () { return { getMap: this.getMap } }
然后在任何后代组件里,我们都可以使用inject 选项来接收指定的我们想要添加在这个实例上的属性:
inject: ['getMap']
实际上,可以把依赖注入看做是一部分”大范围有效的prop", 但是这个依赖注入祖先组件不需要知道哪些后代组件使用它提供的属性,同时后代组件不需要知道被注入的属性来自哪一级祖先组件。
25、对于某些我们创建的对象,如何程序化的清理?
程序化事件侦听器:
- 通过$on(eventName, eventHandler) 侦听一个事件
- 通过$once(eventName, eventHandler) 一次性侦听一个事件
- 通过$off(eventName, eventHandler) 停止侦听一个事件
先看一个示例:
mounted: function () { //Pikaday是一个第三方日期选择器的库。这里是将这个日期选择器附加到一个输入框上,最后挂载到DOM上 var picker = new Pikaday({ field: this.$refs.input, format: 'YYYY-MM-DD' }) //设置一次性的侦听事件,在组件销毁之前,销毁这个日期选择器 this.$once('hook:beforeDestroy', function () { picker.destroy() }) }
对于多个这种输入框,可以让多个输入框使用不同的Pikady, 每个新的实例都程序化地在后期清理它自己
mounted: function () { this.attachDatepicker('startDateInput') this.attachDatepicker('endDateInput') }, methods: { attachDatepicker: function (refName) { var picker = new Pikaday({ field: this.$refs[refName], format: 'YYYY-MM-DD' }) this.$once('hook:beforeDestroy', function () { picker.destroy() }) } }
26、如果组件之间出现了互相引用,如何处理?
先看一个示例:
组件<tree-foler>的模板是这样的:
<p> <span>{{ folder.name }}</span> <tree-folder-contents :children="folder.children"/> </p>
另外一个组件<tree-folder-contents>的模板是这样的:
<ul> <li v-for="child in children"> <tree-folder v-if="child.children" :folder="child"/> <span v-else>{{ child.name }}</span> </li> </ul>
这两个组件互相引用,导致出现了循环引用。这种情况如何去解决呢?
假设这两个组件<tree-folder>是父组件,<tree-folder-contents>是子组件,则产生问题的是子组件<tree-folder-contents>, 因此我们在生命周期钩子beforeCreate里面去注册子组件
beforeCreate: function () { this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue').default }
或者,在本地注册组件的时候,我们使用webpack的异步import:
components: { TreeFolderContents: () => import('./tree-folder-contents.vue') }
这样问题就解决了。