All the features on this page document the handling of edge cases,meaning unusual situations that sometimes require bending Vue’s rules a little. Note however, that they all have disadvantages or situations where they could be dangerous.

本页的所有功能都记录了边缘情况的处理,这意味着有时需要稍微弯曲Vue规则的异常情况。但是,请注意,它们都有缺点或可能存在危险的情况。

1、访问元素&组件

1.1、访问根实例 Accessing The Root Instance

通过this.$root根实例

  1. // the root Vue instance
  2. new Vue({
  3. data:{
  4. foo: 1
  5. },
  6. created: function(){
  7. // 获取 根组件 的数据
  8. console.log(this.$root.foo)
  9. // 写入 根组件 的 数据
  10. this.$root.foo = 2
  11. // 访问 根组件的 计算属性
  12. this.$root.bar
  13. },
  14. computed:{
  15. bar: function(){
  16. alert('我是计算属性Bar,只要有人访问我活着改变我的值,我就执行')
  17. }
  18. },
  19. methods:{
  20. baz: function(){
  21. alert('baz')
  22. }
  23. }
  24. })

这种适合小型代码量的项目使用,中大型项目还是推荐用 Vuex来管理应用的状态。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script src="../vue.js"></script>
  7. <script src="../vuex.js"></script>
  8. </head>
  9. <body>
  10. <script>
  11. const store = new Vuex.Store({
  12. state: {
  13. foo: 1
  14. },
  15. mutations: {
  16. increment (state) {
  17. state.foo++
  18. }
  19. }
  20. })
  21. // The root Vue instance
  22. new Vue({
  23. store: store,
  24. created:function(){
  25. // 获取根组件的数据
  26. console.log(this.$store.state.foo); // 1
  27. // 写入根组件的数据
  28. this.$store.commit('increment')
  29. console.log(this.$store.state.foo) // 2
  30. },
  31. computed: {
  32. bar: function () {
  33. alert('我是计算属性bar,只要有人访问我或者改变我的值,我就执行')
  34. }
  35. },
  36. methods: {
  37. baz: function () {
  38. alert('baz')
  39. }
  40. }
  41. })
  42. </script>
  43. </body>
  44. </html>

1.2、访问父组件实例

Similar to $root, the $parent property can be used to access the parent instance from a child. This can be tempting to reach for as a lazy alternative to passing data with a prop. 与处理边界情况 - 图1parent属性可用于从子级访问父实例。作为一种懒散的替代方法,这可能是一种诱人的方法,而不是用道具传递数据。

父组件通过prop向子组件传值,子组件也可以通过$parent访问父组件的值

1.3、访问子组件或者子元素

通过$refs访问子组件。注意:$refs 只会在组件渲染完成之后生效。

  1. <div id="app">
  2. <base-input ref="usernameInput"></base-input>
  3. </div>
  1. Vue.component('base-input', {
  2. template: '<input type="input" ref="input">',
  3. methods:{
  4. popUP(){
  5. alert(111)
  6. },
  7. focus: function(){
  8. this.$refs.input.focus()
  9. }
  10. }
  11. })
  12. new Vue({
  13. el: '#app',
  14. data: {},
  15. mounted: function(){
  16. this.$refs.usernameInput.popUP()
  17. this.$refs.usernameInput.focus()
  18. }
  19. })

1.4、依赖注入

In fact, you can think of dependency injection as sort of “long-range props” 事实上,你可以把依赖注入看作是一种“远程道具”

使用 props 是父组件向子组件共享数据,而使用 依赖注入 是父组件向所有子孙组件共享数据(可跨层级的共享数据)

  1. // 父组件中 抛出 要分享的 数据
  2. provide: function(){
  3. return {
  4. getMap: this.getMap
  5. }
  6. }
  7. // 子组件中 注入
  8. inject:['getMap']

2、程序化的事件监听

  • Listen for an event with $on(event_name, event_handler)
  • Listen for an event only once with $once(event_name, enent_handler)
  • Stop listening for an event with $off(event_name, event_handler)

当需要在一个组件实例上手动侦听事件时,使用。

  1. <div id="app">
  2. <input ref="dateInput" v-model="date" type="text">
  3. </div>
  1. new Vue({
  2. el: '#app',
  3. data: {
  4. date: null
  5. },
  6. mounted: function(){
  7. var picker = new Pikaday({
  8. field: this.$refs.dateInput,
  9. format: 'YYYY-MM-DD'
  10. })
  11. this.$once('hook:beforeDestory', function(){
  12. picker.destory()
  13. })
  14. }
  15. })

3、循环引用

3.1、递归组件

Components can recursively invoke themselves in their own template. However, they can only do so with the name option.

组件可以在自身模板中调用自己,注意:不要陷入无限循环。

  1. <div>
  2. <base-input />
  3. </div>
  1. Vue.component('base-input', {
  2. name: 'stack-overflow',
  3. template: `<div> <stack-overflow /> </div>`
  4. })
  5. new Vue({
  6. el: '#app',
  7. data: {}
  8. })

3.2、组件之间的循环引用

常见场景:渲染多层级结构时会用到。