vuejs 教程,vue3.0 文档,vuejs 实战,前端框架,vuejs 入门,vue3.0 迁移,vue3资讯,Vue3最新动态,vuejs 中文社区,javascript中文网,vuejs 面试题,vuejs bug

# 实例方法

# $watch

  • 参数:

    • {string | Function} source
    • {Function | Object} callback
    • {Object} [options]
      • {boolean} deep
      • {boolean} immediate
      • {string} flush
  • 返回:{Function} unwatch

  • 用法:

    侦听组件实例上的响应式 property 或函数计算结果的变化。回调函数得到的参数为新值和旧值。我们只能将顶层的 datapropcomputed property 名作为字符串传递。对于更复杂的表达式,用一个函数取代。

  • 示例:

    const app = Vue.createApp({
      data() {
        return {
          a: 1,
          b: 2,
          c: {
            d: 3,
            e: 4
          }
        }
      },
      created() {
        // 顶层property 名
        this.$watch('a', (newVal, oldVal) => {
          // 做点什么
        })
    
        // 用于监视单个嵌套property 的函数
        this.$watch(
          () => this.c.d,
          (newVal, oldVal) => {
            // 做点什么
          }
        )
    
        // 用于监视复杂表达式的函数
        this.$watch(
          // 表达式 `this.a + this.b` 每次得出一个不同的结果时
          // 处理函数都会被调用。
          // 力扣 – 中文网 助你高效提升编程技能 https://www.javascriptc.com/special/leetcode/
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

// 这就像监听一个未被定义的计算属性 () => this.a + this.b, (newVal, oldVal) => { // 做点什么 } ) } })


当侦听的值是一个对象或者数组时,对其属性或元素的任何更改都不会触发侦听器,因为它们引用相同的对象/数组:

```js
const app = Vue.createApp({
  data() {
    return {
      article: {
        text: 'Vue is awesome!'
      },
      comments: ['Indeed!', 'I agree']
    }
  },
  created() {
    this.$watch('article', () => {
      console.log('Article changed!')
    })

    this.$watch('comments', () => {
      console.log('Comments changed!')
    })
  },
  methods: {
    // 力扣 – 中文网 助你高效提升编程技能 https://www.javascriptc.com/special/leetcode/
// 这些方法不会触发侦听器,因为我们只更改了Object/Array的一个property,
    // 不是对象/数组本身
    changeArticleText() {
      this.article.text = 'Vue 3 is awesome'
    },
    addComment() {
      this.comments.push('New comment')
    },

    // 力扣 – 中文网 助你高效提升编程技能 https://www.javascriptc.com/special/leetcode/
// 这些方法将触发侦听器,因为我们完全替换了对象/数组
    changeWholeArticle() {
      this.article = { text: 'Vue 3 is awesome' }
    },
    clearComments() {
      this.comments = []
    }
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

$watch 返回一个取消侦听函数,用来停止触发回调:

const app = Vue.createApp({
  data() {
    return {
      a: 1
    }
  }
})

const vm = app.mount('#app')

const unwatch = vm.$watch('a', cb)
// later, teardown the watcher
unwatch()
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 选项:deep

    为了发现对象内部值的变化,可以在选项参数中指定 deep: true。注意监听数组的变更不需要这么做。

    vm.$watch('someObject', callback, {
      deep: true
    })
    vm.someObject.nestedValue = 123
    // callback is fired
    
    1
    2
    3
    4
    5
  • 选项:immediate

    在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调:

    vm.$watch('a', callback, {
      immediate: true
    })
    // 立即以 `a` 的当前值触发 `callback`
    
    1
    2
    3
    4

    注意,在带有 immediate 选项时,你不能在第一次回调时取消侦听给定的 property。

    // 力扣 – 中文网 助你高效提升编程技能 https://www.javascriptc.com/special/leetcode/
    
    1

// 这会导致报错 const unwatch = vm.$watch( 'value', function() { doSomething() unwatch() }, { immediate: true } )


如果你仍然希望在回调内部调用一个取消侦听的函数,你应该先检查其函数的可用性:

```js
let unwatch = null

unwatch = vm.$watch(
  'value',
  function() {
    doSomething()
    if (unwatch) {
      unwatch()
    }
  },
  { immediate: true }
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • Option: flush

    The flush option allows for greater control over the timing of the callback. It can be set to 'pre', 'post' or 'sync'.

    The default value is 'pre', which specifies that the callback should be invoked before rendering. This allows the callback to update other values before the template runs.

    The value 'post' can be used to defer the callback until after rendering. This should be used if the callback needs access to the updated DOM or child components via $refs.

    If flush is set to 'sync', the callback will be called synchronously, as soon as the value changes.

    For both 'pre' and 'post', the callback is buffered using a queue. The callback will only be added to the queue once, even if the watched value changes multiple times. The interim values will be skipped and won't be passed to the callback.

    Buffering the callback not only improves performance but also helps to ensure data consistency. The watchers won't be triggered until the code performing the data updates has finished.

    'sync' watchers should be used sparingly, as they don't have these benefits.

    For more information about flush see Effect Flush Timing.

  • 参考 Watchers

# $emit

  • 参数:

    • {string} eventName
    • [...args]

    触发当前实例上的事件。附加参数都会传给监听器回调。

  • 示例:

    只配合一个事件名使用 $emit:

    <div id="emit-example-simple">
      <welcome-button v-on:welcome="sayHi"></welcome-button>
    </div>
    
    1
    2
    3
    const app = Vue.createApp({
      methods: {
        sayHi() {
          console.log('Hi!')
        }
      }
    })
    
    app.component('welcome-button', {
      emits: ['welcome'],
      template: `
        <button v-on:click="$emit('welcome')">
          Click me to be welcomed
        </button>
      `
    })
    
    app.mount('#emit-example-simple')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    配合额外的参数使用 $emit

    <div id="emit-example-argument">
      <advice-component v-on:advise="showAdvice"></advice-component>
    </div>
    
    1
    2
    3
    const app = Vue.createApp({
      methods: {
        showAdvice(advice) {
          alert(advice)
        }
      }
    })
    
    app.component('advice-component', {
      emits: ['advise'],
      data() {
        return {
          adviceText: 'Some advice'
        }
      },
      template: `
        <div>
          <input type="text" v-model="adviceText">
          <button v-on:click="$emit('advise', adviceText)">
            Click me for sending advice
          </button>
        </div>
      `
    })
    
    app.mount('#emit-example-argument')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
  • 参考

  • emits 选项

  • 事件抛出一个值

# $forceUpdate

  • 用法:

    迫使组件实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

# $nextTick

  • 参数:

    • {Function} [callback]
  • 用法:

    将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

  • 示例:

Vue.createApp({
  // ...
  methods: {
    // ...
    example() {
      // modify data
      this.message = 'changed'
      // DOM is not updated yet
      this.$nextTick(function() {
        // DOM is now updated
        // `this` is bound to the current instance
        this.doSomethingElse()
      })
    }
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Js中文网,专注分享前端最新技术、大厂面试题、聊点程序员轶事、职场感悟,做前端技术的传播者.

加入前端布道师交流群

扫描二维码回复 加群 学习,与大厂大佬讨论技术.