最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • [译]关于vue3 compostion api "reactive()"方法的害处

    正文概述 掘金(蟹老板爱写代码)   2021-03-24   507

    Composition API简介

    你可以通过下面两个api创建响应性对象:

    1. reactive()
    2. ref() / computed()

    reactive简介

    reactive(obj) 会返回一个响应性对象,对象的所有属性都具备响应性。

    例如:

    // 模板: {{ state.a }} - {{ state.b }}
    const state = reactive({ a: 3 })
    // 渲染结果: 3 - undefined
    
    state.a = 5
    state.b = 'bye'
    // 渲染结果: 5 - bye
    

    他和vue2的data属性是一样的,但是他可以给对象添加新的属性,属性也具备响应性,因为vue3是基于proxy实现的。

    Ref简介

    Ref相当于一个包含.value属性的简单对象,就像下面Typescript的定义:

    interface Ref<A> {
      value: A
    }
    

    两个方法创建 refs:

    1. ref()
      • .value 支持读取和赋值
    2. computed()
      • .value 只支持读取

    例子:

    const countRef = ref(0) // { value: 0 }
    const countPlusOneRef = computed(() => countRef.value + 1) // { value: 1 }
    countRef.value = 5
    
    /*
     * countRef is { value: 5 }
     * countPlusOneRef is { value: 6 } (readonly)
     */
    

    推荐ref而非reactive

    这只是我在使用compostion api实践总结的小小观点,并不具备权威性,你也可以试一下,告诉我你的观点。

    在使用compostion api前,我以为reactive会是首选API,因为它不需要通过.value读取值。但是,我使用compostion api 一段时间后,我不再使用reactive

    三个理由:

    1. 便利性 - ref() 允许自由的定义一个响应性变量。

    2. 灵活性 - ref() 允许替换整个对象

    3. 明确性 - .value 明确告诉你正在做什么

    1. 便利性

    composition api 提供一种以组件功能为维度组合逻辑的方法,他不同于options api把逻辑分别定义在data, computed, methods, 生命周期之类,就像下图。

    [译]关于vue3 compostion api "reactive()"方法的害处

    思考下面的例子:

    const state = reactive({
      count: 0,
      errorMessage: null,
    })
    setTimeout(() => state.count++, 1000)
    watch(state.count, count => {
      if (count > 10) {
        state.errorMessage = 'Larger than 10.'
      }
    })
    

    如果使用reactive() 先定义所有属性,会导致像vue2那样,以特性划分代码,而不是根据逻辑划分,这会导致你的业务逻辑代码分散到不同地方。

    const count = ref(0)
    setTimeout(() => count.value++, 1000)
    
    const errorMessage = ref(null)
    watch(count, count => {
      if (count > 10) {
        errorMessage.value = 'Larger than 10.'
      }
    })
    

    如果用ref()你可以自由的创建响应变量,看到例子上,我只会在我需要响应变量时才定义他们,这会让逻辑更直观。

    2.灵活性

    I initially thought the sole purpose of ref() was to enable primitive values to be reactive. But it can become extremely handy too when using ref() with objects.

    我最初认为ref() 只是用来把原始类型声明为响应性,但是,当ref()和对象一起使用,它也是非常方便的。

    思考:

    const blogPosts = ref([])
    blogPosts.value = await fetchBlogPosts()
    

    如果我用reactive实现相同的功能,我需要遍历数组。

    const blogPosts = reactive([])
    for (const post of (await fetchBlogPosts())) {
      blogPosts.push(post)
    }
    

    或者使用 Array.prototype.splice()

    const blogPosts = reactive([])
    blogPosts.splice(0, 0, ...(await fetchBlogPosts()))
    

    上面例子使用ref()明显比较简单,因为你只需要把新的数组替换旧的数组即可。再看看下面这个分页例子:

    watch(page, page => {
      // 删除所以内容
      while (blogPosts.length > 0) {
        blogPosts.pop()
      }
    
      // 添加新数据
      for (const post of (await fetchBlogPostsOnPage(page))) {
        blogPosts.push(post)
      }
    })
    

    或者用 splice

    watch(page, page => {
      blogPosts.splice(0, blogPosts.length, ...(await fetchBlogPostsOnPage(page)))
    })
    

    但是用 ref()

    watch(page, page => {
      blogPosts.value = await fetchBlogPostsOnPage(page)
    })
    

    这会非常灵活.

    3. 明确性

    reactive() 返回的对象和非响应性对象是相同的,当你需要处理其他非响应性对象时,容易造成混淆。

    watch(() => {
      if (human.name === 'Jason') {
        if (!partner.age) {
          partner.age = 30 
        }
      }
    })
    

    上面的代码,你没法知道humanpartner哪个是响应对象,但是用ref()就不会有这个问题

    .value 看起来有点啰嗦,但是这可以提醒你这是响应对象。

    watch(() => {
      if (human.value.name === 'Jason') {
        if (!partner.age) {
          partner.age = 30 
        }
      }
    })
    

    现在很显然human是响应性对象,partner不是

    结论

    上面只是我的初步看法,你的看法是怎样的,评论区见

    原文地址:dev.to/ycmjason/th…


    起源地下载网 » [译]关于vue3 compostion api "reactive()"方法的害处

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元