vue前端知识——处理边界情况

vue前端知识——处理边界情况1,在绝大多数情况下,最好不要去触达另一个组件的实例内部或者手动操作DOM元素,不过在一些情况下,也是可以使用的。

大家好,欢迎来到IT知识分享网。
vue前端知识——处理边界情况"

1,在绝大多数情况下,最好不要去触达另一个组件的实例内部或者手动操作DOM元素,不过在一些情况下,也是可以使用的。

访问根实例:

每个new Vue实例的子组件中,其根实例可以通过$root property进行访问,如下例子:

// Vue 根实例newVue({ data: { foo: 1}, computed: { bar: function() { /* ... */} }, methods: { baz: function() { /* ... */} } })

所有的子组件都可以将这个实例作为一个全局 store 来访问或使用。

// 获取根组件的数据 this.$root.foo // 写入根组件的数据 this.$root.foo = 2 // 访问根组件的计算属性 this.$root.bar // 调用根组件的方法 this.$root.baz()

子组件也可以访问到父级组件的实例,可以使用类似的this.$parent.getMap方式访问到父组件的Map地图。

但一般不建议这样使用,可能会导致失控。

同时也可以访问子组件实例或者元素,可以通过ref这个attribute为子组件赋予一个ID引用:

<base-input ref="usernameInput"></base-input>

定义完ref这个组件之后,就可以使用

this.$refs.usernameInput

访问到子组件实例或者元素。

也可以程序化地让一个父级组件聚集于输入框,例如代码:

<input ref="input">

可以通过其父级组件定义方法:

methods: { // 用来从父级组件聚焦输入框 focus: function() { this.$refs.input.focus() } } 父级组件也可以通过下面代码聚集<base-input>里的输入框: this.$refs.usernameInput.focus()

依赖注入:依赖注入有两个新的实例选项,可以帮助父级组件的property扩展到更深层级的嵌套组件上,两个新的实例选项provide和inject。

provide选项允许我们指定我们想要提供给后代组件的数据/方法,如下代码,是<google-map>内部的getMap方法:

provide: function() { return { getMap: this.getMap } }

在任何后代组件里,都可以使用inject选项来接收指定的想要添加在这个实例上的property。

inject: ['getMap']

依赖注入允许我们更好的持续研发该组件,不需要担心可能会改变/移除一些子组件依赖的东西。不过也有缺点,会导致应用程序的组件与当前组织方式耦合起来, 使得重构变得更加困难。

2,程序化的事件侦听器

Vue实例除了可以被v-on侦听之外,也可以通过其它侦听器侦听。

  • 通过 $on(eventName, eventHandler) 侦听一个事件
  • 通过 $once(eventName, eventHandler) 一次性侦听一个事件
  • 通过 $off(eventName, eventHandler) 停止侦听一个事件

具体实例如下:

// 一次性将这个日期选择器附加到一个输入框上 // 它会被挂载到 DOM 上。 mounted: function() { // Pikaday 是一个第三方日期选择器的库 this.picker = new Pikaday({ field: this.$refs.input, format: 'YYYY-MM-DD' }) }, // 在组件被销毁之前, // 也销毁这个日期选择器。 beforeDestroy: function() { this.picker.destroy() }

这样的代码会出现两个潜在问题,

  • 它需要在这个组件实例中保存这个 picker,如果可以的话最好只有生命周期钩子可以访问到它。这并不算严重的问题,但是它可以被视为杂物。
  • 我们的建立代码独立于我们的清理代码,这使得我们比较难于程序化地清理我们建立的所有东西。

可以通过一个程序化的侦听器来解决这个问题:

mounted: function() { var picker = new Pikaday({ field: this.$refs.input, format: 'YYYY-MM-DD' }) this.$once('hook:beforeDestroy', function() { picker.destroy() }) }

使用了这个策略,我甚至可以让多个输入框元素同时使用不同的 Pikaday,每个新的实例都程序化地在后期清理它自己:

mounted: function() { this.attachDatepicker('startDateInput') this.attachDatepicker('endDateInput') }, methods: { attachDatepicker: function(refName) { varpicker = newPikaday({ field: this.$refs[refName], format: 'YYYY-MM-DD'}) this.$once('hook:beforeDestroy', function() { picker.destroy() }) } }

如果发现不得不在单个组件做很多建立和清理的工作,最好的方式还是创建更多的模块化组件。

3,循环引用

组件是可以在自己的模板中调用自身的,只能通过name选项来做这件事:

name: 'unique-name-of-my-component'

当使用vue.component全局注册组件时,这个全局的ID会自动设置为该组件的name选项。

如果错的话,会导致递归组件无线循环:

name: 'stack-overflow', template: '<div><stack-overflow></stack-overflow></div>'

因此建议在使用递归调用时,使用条件性的判断语句。

组件之间出现循环引用,在一个<tree-folder>组件中,模板是这样的:

<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>

会产生A依赖B,B依赖A的情况,会尝试悖论。当使用Vue.component全局注册组件的时候,会将这个悖论自动解开。

如果使用模板系统依赖/导入组件,在官网上面有解决方法。

4,模板定义的替代品

使用内联模板inline-template这个特殊的attribute出现在子组件上时,这个组件会使用其里面的内容作为模板,而不是将其作为被分发的内容。例如:

<my-componentinline-template> <div> <p>These are compiled as the component's own template.</p> <p>Not parent's transclusion content.</p> </div> </my-component>

不过,inline-template 会让模板的作用域变得更加难以理解。所以作为最佳实践,请在组件内优先选择 template 选项或 .vue 文件里的一个 <template> 元素来定义模板。

X-Template

也可以在<script>元素中,为其带上text/x-template的类型,然后通过id将模板引用过去。

<scripttype="text/x-template"id="hello-world-template"> <p>Hello hello hello</p></script> Vue.component('hello-world', { template: '#hello-world-template'})

x-template 需要定义在 Vue 所属的 DOM 元素外。

这些可以用于模板特别大的 demo 或极小型的应用,但是其它情况下请避免使用,因为这会将模板和该组件的其它定义分离开。

5,控制更新

强制更新,$forceUpdate

通过v-once创建低开销的静态组件,可以在根元素上添加v-once attribute以确保这些内容只计算一次然后缓存起来,如下代码:

Vue.component('terms-of-service', { template: ` <div v-once> <h1>Terms of Service</h1> ... a lot of static content ... </div> ` })

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/58709.html

(0)
上一篇 2024-07-02 21:00
下一篇 2024-07-07 15:33

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信