【问题标题】:Is it possible to turn that into '<script setup>' ? I try many ways but missing something maybe是否可以将其转换为 '<script setup>' ?我尝试了很多方法,但可能错过了一些东西
【发布时间】:2022-01-01 15:44:29
【问题描述】:

是否可以将其转换为 &lt;script setup&gt; ?我尝试了很多方法,但也许错过了一些东西。需要帮助!

<script>
    import ProductsAPI from '../api/products.api';

    export default {
        name: 'products',

        components: {
            product: 'product',
        },

        data() {
            return {
                products: [],
                error: '',
            };
        },

        async created() {
            this.products = await ProductsAPI.fetchAll();
        },
    };
</script>

【问题讨论】:

  • 以正常方式尝试,但我遇到了很多问题,例如我的承诺无法解决(待定)......变量'products'似乎是作用域而不是可在函数外访问...

标签: vue.js vuejs3 vue-composition-api vue-script-setup


【解决方案1】:

您应该在注册之前导入组件。

<script>
import ProductsAPI from '../api/products.api';
import ProductComp from './components/Product.vue'

export default {
    name: 'products',

    components: {
        'product': ProductComp
    },

    data() {
        return {
            products: [],
            error: '',
        };
    },

    async created() {
        this.products = await ProductsAPI.fetchAll();
    },
};

使用脚本设置看起来像这样。

 <script setup>
   import ProductsAPI from '../api/products.api';
   import Product from './components/Product.vue'

   let error = '';
   let products = await ProductsAPI.fetchAll();
</script>

【讨论】:

  • 它们不等价。第二个 sn-p 导致使用 suspense 的异步组件
【解决方案2】:

它有助于将问题分解为可以单独解决的较小问题...

组件注册

组件在将其定义导入&lt;script setup&gt; 时会自动注册,因此注册Product 很简单:

<script setup>
import Product from '@/components/Product.vue' // locally registered
</script>

数据属性

反应性数据属性声明为ref(或reactive):

<script setup>
import { ref } from 'vue'

const products = ref([])
const error = ref('')

// to change the value of the `ref`, use its `.value` property
error.value = 'My error message'
products.value = [{ name: 'Product A' }, { name: 'Product B' }]
</script>

或者,您可以在&lt;script setup&gt; 中使用新的/实验性的Reactivity Transform,它全局定义了反应性API,前缀为$(例如,$ref 代表ref),并且避免了解包@ 987654336@s 通过.value:

<script setup>
let products = $ref([])
let error = $ref('')

// assign the values directly (no need for .value)
error = 'My error message'
products = [{ name: 'Product A' }, { name: 'Product B' }]
</script>

created生命周期钩子

&lt;script setup&gt; 块与setup 钩子发生的时间相同,这也与created 钩子的时间相同,因此您可以在那里复制原始钩子代码。要使用await,您可以将调用包装在async IIFE

<script setup>
import ProductAPI from '@/api/products.api'
import { ref } from 'vue'

const products = ref([])

;(async () => {
  products.value = await ProductAPI.fetchAll()
})()
</script>

...或创建一个在其中调用的async 函数:

<script setup>
import ProductAPI from '@/api/products.api'
import { ref } from 'vue'

const products = ref([])

const loadProducts = async () => products.value = await ProductAPI.fetchAll()
loadProducts()
</script>

组件名称

name 属性没有等效的 Composition API,但您可以在同一 SFC 中使用 &lt;script&gt; 块和 &lt;script setup&gt; 来包含 Composition API 不支持的任何道具:

<script setup>
⋮
</script>

<!-- OK to have <script> and <script setup> in same SFC -->
<script>
export default {
  name: 'products',
}
</script>

demo

【讨论】:

    【解决方案3】:

    问题是特定于组合 API,而不是特定于 script setup。只要正确编写组件,script 可以通过提取setup 的内容,同时保留导入和setup 返回值,轻松转换为script setup,除了少数例外。

    组合 API 中的 lifecyclecreated 挂钩非常接近,但并不直接对应。问题是 created 最初被滥用。 Vue 大量借鉴了 React 并具有类似的生命周期,后者对在组件创建中使用副作用有严格的规定。所有副作用都应该在组件已经挂载后执行。

    Vue 没有与 React 相同的技术限制,但也存在一些问题。在created 中没有足够的理由做副作用,所以它们属于mounted。在created 中使用它们几乎没有优势,而缺点是初始渲染被稍后可以在组件安装时完成的工作阻塞,并且在组件创建时过早完成的副作用可能会导致SSR 由于其语义而存在问题,然后script setup 存在问题。 mountedunmounted 钩子也有明确的语义,后者可能会对前者产生的副作用进行清理。

    script setupscriptsetup 函数中,它可以是:

    let products = ref([]);
    
    onMounted(async () => {
      products.value = await ProductsAPI.fetchAll();
    });
    

    TL;DR:使用mounted 而不是created 生命周期钩子来处理异步副作用是一个好习惯。 mountedscript setup 中可用。

    【讨论】:

    • 是否缺少导入?我收到ReferenceError: onMounted is not defined - 也许是import { ref, onMounted } from 'vue'
    • 是的。如前所述,需要使用脚本设置语法来维护导入。这与一般使用组合 API 没有区别。
    猜你喜欢
    • 2013-08-12
    • 1970-01-01
    • 2011-04-10
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多