vuejs / docs-next-zh-cn

:cn: Chinese translation for v3.vuejs.org
https://v3.cn.vuejs.org
MIT License
950 stars 849 forks source link

bug: 修改响应式 property 的代码示例错误使用this #830

Closed lizheng0515 closed 2 years ago

lizheng0515 commented 2 years ago

https://v3.cn.vuejs.org/guide/composition-api-provide-inject.html#%E4%BF%AE%E6%94%B9%E5%93%8D%E5%BA%94%E5%BC%8F-property

文档中介绍 修改响应式 property代码示例里, methods里面定义了一个updateLocation方法, 里面用this来访问location

我在"vue": "^3.2.16",版本工程里尝试,发现vscode提示无法访问location 这里应该不能用this来访问location吧,methods 对象的 this指向data返回的对象

image

<!-- src/components/MyMap.vue -->
<template>
  <MyMarker />
</template>

<script>
import { provide, reactive, ref } from 'vue'
import MyMarker from './MyMarker.vue'

export default {
  components: {
    MyMarker
  },
  setup() {
    const location = ref('North Pole')
    const geolocation = reactive({
      longitude: 90,
      latitude: 135
    })

    provide('location', location)
    provide('geolocation', geolocation)

    return {
      location
    }
  },
  methods: {
    updateLocation() {
      this.location = 'South Pole'
    }
  }
}
</script>
// 当 methods 有方法时
if (methods) {
    // 对methods对象中的每一个方法遍历
    for (const key in methods) {
        // 取出每一个方法
      const methodHandler = (methods as MethodOptions)[key]
        // 判断是否是方法Function类型
      if (isFunction(methodHandler)) {
        // In dev mode, we use the `createRenderContext` function to define
        // methods to the proxy target, and those are read-only but
        // reconfigurable, so it needs to be redefined here
        // 在开发环境时
        if (__DEV__) {
          Object.defineProperty(ctx, key, {
            // 对每个方法进行绑定this的作用域 this等于这里的publicThis
            value: methodHandler.bind(publicThis),
            configurable: true,
            enumerable: true,
            writable: true
          })
        } else {
            // 非开发环境时,对每个方法进行this的绑定
          ctx[key] = methodHandler.bind(publicThis)
        }
        if (__DEV__) {
          checkDuplicateProperties!(OptionTypes.METHODS, key)
        }
      } else if (__DEV__) {
        warn(
          `Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
            `Did you reference the function correctly?`
        )
      }
    }
  }

publicThis的指向是 实例的代理

const publicThis = instance.proxy! as any 而这个实例的代理就是Vue中的data对象,所以this指向的应该是data返回的对象

希望能获得解答!!!

wxsms commented 2 years ago

麻烦贴一下你认为有问题的文档链接或者截图?你上面给的链接是链接到项目wiki的,我并不是很明白你说的是哪一个位置的示例代码有问题。

lizheng0515 commented 2 years ago

麻烦贴一下你认为有问题的文档链接或者截图?你上面给的链接是链接到项目wiki的,我并不是很明白你说的是哪一个位置的示例代码有问题。

更改了链接。 image

lizheng0515 commented 2 years ago

英文版也是错的 image

wxsms commented 2 years ago

https://sfc.vuejs.org/

这个用法并没有问题,请见demo链接。至于vscode的提示问题不在本仓库讨论范畴,请移步至合适的项目提问。谢谢!