vue文档摘录六:实例方法

参考文档:https://v3.cn.vuejs.org/api/instance-methods.html

$watch:

API文档:

  • 参数:

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

  • 用法:

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

  • 示例:

    const app = 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` 每次得出一个不同的结果时
          // 处理函数都会被调用。
          // 这就像监听一个未被定义的计算属性
          () => this.a + this.b,
          (newVal, oldVal) => {
            // 做点什么
          }
        )
      }
    })
    

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

    const app = 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: {
        // 这些方法不会触发侦听器,因为我们只更改了Object/Array的一个property,
        // 不是对象/数组本身
        changeArticleText() {
          this.article.text = 'Vue 3 is awesome'
        },
        addComment() {
          this.comments.push('New comment')
        },
    
        // 这些方法将触发侦听器,因为我们完全替换了对象/数组
        changeWholeArticle() {
          this.article = { text: 'Vue 3 is awesome' }
        },
        clearComments() {
          this.comments = []
        }
      }
    })
    

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

    const app = createApp({
      data() {
        return {
          a: 1
        }
      }
    })
    
    const vm = app.mount('#app')
    
    const unwatch = vm.$watch('a', cb)
    // later, teardown the watcher
    unwatch()
    
  • 选项:deep

    为了发现对象内部值的变化,可以在选项参数中指定 deep: true。这个选项同样适用于监听数组变更。

    注意:当变更(不是替换)对象或数组并使用 deep 选项时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变更之前值的副本。

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

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

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

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

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

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

    let unwatch = null
    
    unwatch = vm.$watch(
      'value',
      function() {
        doSomething()
        if (unwatch) {
          unwatch()
        }
      },
      { immediate: true }
    )
    
  • 选项:flush

    flush 选项可以更好地控制回调的时间。它可以设置为 'pre''post' 或 'sync'

    默认值是 'pre',指定的回调应该在渲染前被调用。它允许回调在模板运行前更新了其他值。

    'post' 值是可以用来将回调推迟到渲染之后的。如果回调需要通过 $refs 访问更新的 DOM 或子组件,那么则使用该值。

    如果 flush 被设置为 'sync',一旦值发生了变化,回调将被同步调用。

    对于 'pre' 和 'post',回调使用队列进行缓冲。回调只被添加到队列中一次,即使观察值变化了多次。值的中间变化将被跳过,不会传递给回调。

    缓冲回调不仅可以提高性能,还有助于保证数据的一致性。在执行数据更新的代码完成之前,侦听器不会被触发。

    'sync' 侦听器应少用,因为它们没有这些好处。

    更多关于 flush 的信息,请参阅副作用刷新时机

测试代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!-- <script src="https://unpkg.com/vue@next"></script> -->
		<script src="js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			根组件:{{msg}}
			<test :msg="msg"></test>
		</div>
		<script>
			var app = Vue.createApp({
				data() {
					return {
						msg: '组件传值'
					}
				},
				created() {
					//监听参数msg是否发生了变化
					this.$watch('msg', (newVal, oldVal) => {
						console.log("值发生了变化:");
						console.log("旧值:" + oldVal);
						console.log("新值:" + newVal);
						console.log("data:" + this.$data.msg);
					})
				},
				mounted() {
					console.log(this.$data.msg);
					this.$data.msg = "222"
				}
			});
			app.mount('#app')
		</script>
	</body>
</html>

运行结果:

$emit:

API文档:

  • 参数:

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

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

  • 示例:

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

    <div id="emit-example-simple">
      <welcome-button v-on:welcome="sayHi"></welcome-button>
    </div>
    
    const app = 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')
    

    配合额外的参数使用 $emit

    <div id="emit-example-argument">
      <advice-component v-on:advise="showAdvice"></advice-component>
    </div>
    
    const app = 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')
    

测试代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!-- <script src="https://unpkg.com/vue@next"></script> -->
		<script src="js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			根组件:{{msg}}
			<test :msg="msg" v-on:change_="changeMsg"></test>
		</div>
		<script>
			var app = Vue.createApp({
				data() {
					return {
						msg: '组件传值'
					}
				},
				created() {
					//监听参数msg是否发生了变化
					this.$watch('msg', (newVal, oldVal) => {
						console.log("值发生了变化:");
						console.log("旧值:" + oldVal);
						console.log("新值:" + newVal);
						console.log("data:" + this.$data.msg);
					})
				},
				mounted() {
					console.log(this.$data.msg);
					this.$data.msg = "222"
				},
				methods: {
					changeMsg(msg) {
						this.$data.msg = msg
					}
				}
			});
			app.component('test', {
				emits: ['change_'],
				template: `
				    <button v-on:click="$emit('change_','3333')">
				      Click me to be change_
				    </button>
				  `
			})
			app.mount('#app')
		</script>
	</body>
</html>

运行结果:

$forceUpdate:

API文档:

  • 用法:

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

$nextTick:

API文档:

  • 参数:

    • {Function} [callback]
  • 用法:

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

  • 示例:

    createApp({
      // ...
      methods: {
        // ...
        example() {
          // 修改数据
          this.message = 'changed'
          // DOM 尚未更新
          this.$nextTick(function() {
            // DOM 现在更新了
            // `this` 被绑定到当前实例
            this.doSomethingElse()
          })
        }
      }
    })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

军军君01

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值