繁体   English   中英

如何在 Vue.js 中将选项 api 转换为组合 api?

[英]How to convert options api to composition api in Vue.js?

我正在使用 Vue.js 第 3 版。这是我的完整代码,其中包含虚拟数据和选项 API 以及过滤器和排序,并且一切都很好

<template>
  <h5>List of Products</h5>

        <h3>Filter</h3> 
        <button v-on:click="resetOptions">Reset</button>
        <button v-on:click="sorting">Sorting</button>
        <button v-on:click="sorting2">Sorting2</button>
        <select v-model="category">
            <option value="Accessories">Accessories</option>
            <option value="Laptop">Laptop</option>
            <option value="Stationary">Stationary</option>
        </select> 
        <div>
        <input type="checkbox" name="test" id="test" v-model="city"  value='Roma' /> 
        <label for="test"> Roma</label>
        <input type="checkbox" name="test2" id="test2" v-model.trim="city" value='Barselona'  />
        <label for="test2"> Barselona</label>
        <input type="checkbox" name="test3" id="test3" v-model.trim="city" value='Milano'  />
        <label for="test3"> Milano</label>
        </div>
         <!-- <select v-model="city">
            <option value="Barselona">Barselona</option>
            <option value="Roma"> Roma </option>
            <option value="Milano">Milano</option>
        </select>  -->

        <input type="text" v-model="name" placeholder="Filter By Name"/>

        <label for="vol">Price (between 0 and 1000):</label>
    
        <input type="range" v-model.trim="range" min="0" max="1000" step="10"/>  
        <ul>
            <li v-for="product in filterProducts" :key="product.name"> Product Name : {{product.name}} - Price : {{product.price}} ({{product.category}}) 
                {{product.city}}
            </li>
        </ul>
</template>

<script>
import getPosts from '../composables/getPosts'
export default {
 data: ()=> ( {

            city:['Roma', 'Barselona', 'Milano'],
            category: '',
            name: '',
            range: '10000',
            products: [
                { name: "Keyboard", price: 44, category: 'Accessories', city:'Roma'},
                { name: "Mouse", price: 20, category: 'Accessories', city:'Barselona'},
                { name: "Monitor", price: 399, category: 'Accessories', city:'Roma'},
                { name: "Dell XPS", price: 599, category: 'Laptop', city:'Roma'},
                { name: "MacBook Pro", price: 899, category: 'Laptop', city:'Roma'},
                { name: "Pencil Box", price: 6, category: 'Stationary', city:'Barselona'},
                { name: "Pen", price: 2, category: 'Stationary', city:'Milano'},
                { name: "USB Cable", price: 7, category: 'Accessories', city:'Milano'},
                { name: "Eraser", price: 2, category: 'Stationary', city:'Roma'},
                { name: "Highlighter", price: 5, category: 'Stationary', city:'Roma'}
            ]

        }),

              computed: {
            filterProducts: function(){
                return 
 this.filterProductsByName(this.filterProductsByRange(this.filterProductsByCity(this.filterProductsByCateg 
 ory(this.products))))
            },

        },
        
        methods: {

            filterProductsByCategory: function(products){
                return products.filter(product => !product.category.indexOf(this.category))
            },

            filterProductsByName: function(products) {
                return products.filter(product => 
  !product.name.toLowerCase().indexOf(this.name.toLowerCase()))
            },

            filterProductsByCity: function(products) {
                     return products.filter(product => this.city.indexOf(product.city) !== -1)
            },

             filterProductsByCity2: function(products) {
                 return products.filter(product => !product.city.indexOf(this.city))
             },

            filterProductsByRange: function(products){
                return products.filter(product => (product.price >= 0 && product.price <= this.range) ? product : '')
            },

            sorting:function(){
                this.products.sort((a,b)=>(a.price > b.price) ? 1 : -1)
            },
             sorting2:function(){
                this.products.sort((a,b)=>(a.price < b.price) ? 1 : -1)
            },

            uniqueCheck(e){
            this.city = [];
            if (e.target.checked) {
                 this.city.push(e.target.value);
               }
         },

            resetOptions:function(){
                this.category='',
                this.city='',
                this.name='',
                this.range='1000'
            },
        },

}
</script>

<style>

</style>

但我想将其转换为合成 API 并将虚拟数据放入假 API 中。 我进行了 API 调用并将其放入 getProducts.js 文件中。 我在此页面上导入的那个文件,我想在其中显示该数据。 这很好用。 但是我在将函数从选项 API 转换为组合 API 时遇到问题 这是我的代码

<template>
  <div class='home'>
      <h1>Third</h1>
        <select v-model="category">
            <option value="Accessories">Accessories</option>
            <option value="Laptop">Laptop</option>
            <option value="Stationary">Stationary</option>
        </select> 
      <div>
        <input type="checkbox" name="test" id="test" v-model="city"  value='Roma' /> 
        <label for="test"> Roma</label>
      </div>
      <div v-if="error"> {{error}} </div>
      <div v-if="products.length">
          <div v-for="product in filterProducts" :key='product.price'>
            <h3>{{product.name }}</h3>
            <h4>{{product.category}}</h4>
          </div>
      </div>
    <div v-else> Loading...</div>
  </div>
</template>


<script>
import { computed, ref} from 'vue'
import getProducts from '../composables/getProducts'

export default {
    components: {} ,
    setup(){ 

      const category = ref('')
      const city = ref('')
      const{products,error,load} = getProducts()

      load()

        function filterProductsByCategory (products){
              return products.filter(product => !product.category.indexOf(category.value))
          }
         function filterProductsByCity (products) {
               return products.filter(product => city.value.indexOf(product.city) !== -1)
            }

       const filterProducts = computed (()=> {  
        return filterProductsByCity.value(filterProductsByCategory.value(products.value))**
    }) 


      return {products, error, category, city, filterProducts, filterProductsByCity, filterProductsByCategory}
    }
}
</script>

<style>

</style>

这是我的过滤功能的一部分,我认为这是功能的问题。 我更改了将 Options API 转换为 Composition API 所需的一切

所以这只是过滤器逻辑的一部分,但如果有人帮助我,我将轻松转换所有代码

data

  1. ref替换每个数据属性。 稍后转换methods时,我们将在setup()中更新它们的引用。

  2. 在安装组件时使用onMounted调用load()

import { ref, onMounted } from 'vue'
import getProducts from '@/composables/getProducts'

export default {
  setup() {
    const { products, load } = getProducts()
    const category = ref('')
    const city = ref([])
    const name = ref('')
    const range = ref('10000')

    onMounted(() => load()) // load products

    return {
      // properties that the template needs should be returned here
      products,
      category,
      city,
      name,
      range,
    }
  }
}

methods

  1. setup()中将方法声明为 function 实例。
  2. 对于现在是ref的所有数据属性,更新它们的代码引用以解开ref (即this.name应该是name.value等)。
export default {
  setup() {
    //...
    const filterProductsByCategory = (products) => {
      return category.value
        ? products.filter((product) => !product.category.indexOf(category.value))
        : products
    }

    const filterProductsByName = (products) => {
      return name.value
        ? products.filter((product) => !product.name.toLowerCase().indexOf(name.value.toLowerCase()))
        : products
    }

    const filterProductsByCity = (products) => {
      return city.value && city.value.length
        ? products.filter((product) => city.value.indexOf(product.city) !== -1)
        : products
    }

    const filterProductsByRange = (products) => {
      return range.value
        ? products.filter((product) => product.price >= 0 && product.price <= range.value)
        : products
    }

    const sorting = () => products.value.sort((a, b) => (a.price > b.price ? 1 : -1))
    const sorting2 = () => products.value.sort((a, b) => (a.price < b.price ? 1 : -1))

    const uniqueCheck = (e) => {
      city.value = []
      if (e.target.checked) {
        city.value.push(e.target.value)
      }
    }

    const resetOptions = () => {
      category.value = ''
      city.value = ''
      name.value = ''
      range.value = '1000'
    }

    return {
      //...

      // methods that the template needs should be returned here
      sorting,
      sorting2,
      uniqueCheck,
      resetOptions,
    }
  }
}

computed

  1. 使用computed创建一个计算属性,引用上面在setup()中创建的 function 实例和ref
import { computed } from 'vue'

export default {
  setup() {
    //...
    const filterProducts = computed(() => {
      return filterProductsByName(
        filterProductsByRange(
          filterProductsByCity(filterProductsByCategory(products.value))
        )
      )
    })

    return {
      //...
      filterProducts,
    }
  }
}

演示

<script setup>版本的组合 api 代码可以如下完成。

<script setup>
     import DemoComponent from "./Demo.vue"
     import { onMounted, ref, computed } from "vue";

     const demoVar = ref(""); //data property of options api
     const demoComputed = computed(()=>{
         return {};
     });  // computed property 

     //Methods can be declared in 2 ways
     //1st
     function demo(){
        //logic
     }

     //2nd
     const demoTwo = function(){};

     //lifecycle hook
     onMounted(() => {})
</script> 

有关声明方法及其用途的更多信息,请查看正确使用 const 来定义函数

我们不需要在脚本末尾返回constfunction ,通过脚本设置,模板甚至components都可以直接访问所有内容。

<script setup>提供了更多的可读性,并避免了由于在返回中遗漏了 const 而导致的不必要的错误。 有关更多详细信息,脚本设置

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM