undraw_laravel_and_vue_59tp.png

数据 property

当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 数据 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

为什么 vue 组件中 data 必须是一个函数?

对象为引用类型,当复用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object的实例),引用地址不同,则不会出现这个问题。

实例 property 与方法

除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 $,以便与用户定义的 property 区分开来。

  1. var data = { a: 1 }
  2. var vm = new Vue({
  3. el: '#example',
  4. data: data
  5. })
  6. vm.$data === data // => true
  7. vm.$el === document.getElementById('example') // => true
  8. // $watch 是一个实例方法
  9. vm.$watch('a', function (newValue, oldValue) {
  10. // 这个回调将在 `vm.a` 改变后调用
  11. })

可以在 API 参考中查阅到完整的实例 property 和方法的列表。

实例 property

使用 $root 作为 “全局数据 property”

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

  1. // Vue 根实例
  2. new Vue({
  3. data: {
  4. foo: 1
  5. },
  6. computed: {
  7. bar: function () { /* ... */ }
  8. },
  9. methods: {
  10. baz: function () { /* ... */ }
  11. }
  12. })

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

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

对于 demo 或非常小型的有少量组件的应用来说这是很方便的。不过这个模式扩展到中大型应用来说就不然了。因此在绝大多数情况下,我们强烈推荐使用 Vuex 来管理应用的状态。

Vue 不允许动态添加根级响应式 property,所以你必须在初始化实例前声明所有根级响应式 property,哪怕只是一个空值

$nextTick是什么 ?

vue实现响应式并不是数据发生变化后dom立即变化,而是按照一定的策略来进行dom更新。

nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用nextTick,则可以在回调中获取更新后的 DOM

$refs 访问子组件或子元素

https://cn.vuejs.org/v2/guide/components-edge-cases.html#%E8%AE%BF%E9%97%AE%E5%AD%90%E7%BB%84%E4%BB%B6%E5%AE%9E%E4%BE%8B%E6%88%96%E5%AD%90%E5%85%83%E7%B4%A0

v-for 中的 Ref 数组


image.png

实例方法/数据

$set 设置对象或者数组某个属性的变化

当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并没有更新。这是因为Object.defineprototype()限制,监听不到变化。

解决方式:

  • this.$set(你要改变的数组/对象,你要改变的位置/key,你要改成什么value)

    1. this.$set(this.arr, 0, "OBKoro1"); // 改变数组
    2. this.$set(this.obj, "c", "OBKoro1"); // 改变对象
  • 数组原生方法触发视图更新,vue可以监听到数组原生方法导致的数据数据变化

    1. splice()、 push()、pop()、shift()、unshift()、sort()、reverse()

意思是使用这些方法不用我们再进行额外的操作,视图自动进行更新。推荐使用splice方法会比较好自定义,因为splice可以在数组的任何位置进行删除/添加操作

$watch 监听数据变化

$watch和watch都是监听值的变化的,是同一个作用,但是有两个不同写法。

  1. //假设 data 定义的数据如下:
  2. data() {
  3. return {
  4. a: 1,
  5. b: 2,
  6. c: {
  7. d: 3,
  8. e: 4
  9. }
  10. }
  11. },
  12. //单个的顶层属性,第一个参数是字符串,第二个参数是函数
  13. created() {
  14. // 顶层属性
  15. this.$watch('a', (newVal, oldVal) => {
  16. // 做点什么
  17. })
  18. }
  19. // 嵌套的对象里面的属性,Vue3 两个参数都必须是函数形式
  20. created() {
  21. // 用于监视单个嵌套属性
  22. this.$watch(
  23. () => this.c.d,
  24. (newVal, oldVal) => {
  25. // 做点什么
  26. }
  27. )
  28. }
  29. // 嵌套的对象里面的属性,Vue2 可以使用简单的键路径
  30. created() {
  31. // 键路径
  32. this.$watch('c.d', (newVal, oldVal) => {
  33. // 做点什么
  34. })
  35. }
  36. // 更复杂的表达式,用一个函数取代
  37. created() {
  38. // 用于监视复杂表达式的函数
  39. this.$watch(
  40. // 表达式 `this.a + this.b` 每次得出一个不同的结果时
  41. // 处理函数都会被调用。
  42. // 这就像监听一个未被定义的计算属性
  43. () => this.a + this.b,
  44. (newVal, oldVal) => {
  45. // 做点什么
  46. }
  47. )
  48. }
  49. // Object深度监听
  50. created() {
  51. // 顶层属性
  52. this.$watch('c', (newVal, oldVal) => {
  53. // 做点什么
  54. }, { deep: true, immediate: true })
  55. }

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

  1. created() {
  2. // 顶层属性
  3. let cancel = this.$watch('a', (newVal, oldVal) => {
  4. // 做点什么
  5. })
  6. cancel()
  7. }

实例方法/事件

$emit