UI Component Marketplace Vue.js (JavaScript)

👤 Sharing: AI
```vue
<template>
  <div class="marketplace">
    <h1>Vue.js Component Marketplace</h1>

    <div class="search-bar">
      <input type="text" v-model="searchTerm" placeholder="Search components..." />
    </div>

    <div class="component-list">
      <div v-for="component in filteredComponents" :key="component.id" class="component-card">
        <h2>{{ component.name }}</h2>
        <p>{{ component.description }}</p>
        <div class="component-tags">
          <span v-for="tag in component.tags" :key="tag" class="tag">{{ tag }}</span>
        </div>
        <a :href="component.url" target="_blank">View on GitHub</a>
        <button @click="addToCart(component)">Add to Cart</button>
      </div>
    </div>

    <h2>Cart</h2>
    <div class="cart">
      <div v-if="cart.length === 0">Your cart is empty.</div>
      <div v-else v-for="item in cart" :key="item.id" class="cart-item">
        {{ item.name }}
        <button @click="removeFromCart(item)">Remove</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      searchTerm: '',
      components: [
        {
          id: 1,
          name: 'Vue Awesome Slider',
          description: 'A responsive and customizable slider component for Vue.js.',
          url: 'https://github.com/vue-awesome/vue-awesome-slider',
          tags: ['slider', 'carousel', 'responsive'],
        },
        {
          id: 2,
          name: 'Vue Chart.js',
          description: 'Chart.js wrapper component for Vue.js.',
          url: 'https://github.com/vuejs/vue-chartjs',
          tags: ['chart', 'graphs', 'data visualization'],
        },
        {
          id: 3,
          name: 'Vue Material',
          description: 'Material Design components for Vue.js.',
          url: 'https://github.com/vuematerial/vue-material',
          tags: ['material design', 'ui kit', 'components'],
        },
        {
          id: 4,
          name: 'Vue Quill Editor',
          description: 'Quill editor component for Vue.js.',
          url: 'https://github.com/surmon-china/vue-quill-editor',
          tags: ['text editor', 'richtext', 'wysiwyg'],
        },
        {
          id: 5,
          name: 'Vue Draggable',
          description: 'Drag and drop component for Vue.js.',
          url: 'https://github.com/SortableJS/Vue.Draggable',
          tags: ['drag and drop', 'sortable', 'ui'],
        },
      ],
      cart: [],
    };
  },
  computed: {
    filteredComponents() {
      const term = this.searchTerm.toLowerCase();
      return this.components.filter((component) => {
        return (
          component.name.toLowerCase().includes(term) ||
          component.description.toLowerCase().includes(term) ||
          component.tags.some(tag => tag.toLowerCase().includes(term)) //checks the array of tags
        );
      });
    },
  },
  methods: {
    addToCart(component) {
      this.cart.push(component);
    },
    removeFromCart(component) {
      this.cart = this.cart.filter((item) => item.id !== component.id);
    },
  },
};
</script>

<style scoped>
.marketplace {
  font-family: sans-serif;
  padding: 20px;
}

.search-bar {
  margin-bottom: 20px;
}

.search-bar input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.component-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
}

.component-card {
  border: 1px solid #ccc;
  padding: 15px;
  border-radius: 4px;
}

.component-tags {
  margin-top: 10px;
}

.tag {
  background-color: #eee;
  padding: 5px 10px;
  border-radius: 4px;
  margin-right: 5px;
  display: inline-block;
}

.cart {
  margin-top: 20px;
  border: 1px solid #ccc;
  padding: 15px;
  border-radius: 4px;
}

.cart-item {
  margin-bottom: 5px;
}
</style>
```

**Explanation:**

1.  **`template` Section:**
    *   **HTML Structure:** This section defines the HTML structure of the marketplace.  It includes:
        *   A heading (`<h1>`).
        *   A search bar for filtering components.
        *   A `component-list` to display the components.
        *   A `cart` section to show selected components.
    *   **`v-model="searchTerm"`:**  This directive binds the input field to the `searchTerm` data property in the component's `data`.  Any changes in the input field will update `searchTerm`, and vice-versa.  This enables two-way data binding.
    *   **`v-for="component in filteredComponents"`:**  This directive loops through the `filteredComponents` computed property and creates a `component-card` for each component.  The `key` attribute is important for Vue's efficient rendering.
    *   **`{{ component.name }}`**, **`{{ component.description }}`:**  These are examples of data binding.  They display the `name` and `description` properties of each component.
    *   **`v-for="tag in component.tags"`:**  Another `v-for` loop, this one iterates through the `tags` array of each component to display them as tags.
    *   **`:href="component.url"`:**  This binds the `href` attribute of the link to the `component.url`.  The colon `:` is shorthand for `v-bind:`.  This makes the links dynamic, pointing to the actual GitHub URLs.
    *   **`@click="addToCart(component)"`:**  This directive listens for a click event on the "Add to Cart" button and calls the `addToCart` method, passing the current component as an argument.  The `@` symbol is shorthand for `v-on:`.
    *   **Cart Display:** The `cart` section uses a `v-if` to display a message if the cart is empty and another `v-for` to display the items in the cart with a "Remove" button.
    *   **`@click="removeFromCart(item)"`:** Listens to the click event on the remove button.

2.  **`script` Section:**
    *   **`data()`:**  This is a function that returns an object.  This object holds the component's data.
        *   **`searchTerm`:** Stores the current search term entered by the user.  Initialized to an empty string.
        *   **`components`:** An array of component objects. Each object represents a component available in the marketplace.
        *   **`cart`:** An array that stores the components added to the cart.  Initialized to an empty array.
    *   **`computed: { filteredComponents() { ... } }`:**  Computed properties are dynamically calculated based on the data.  They are cached and only re-evaluated when their dependencies change.
        *   **`filteredComponents`:** This computed property filters the `components` array based on the `searchTerm`. It converts the `searchTerm` to lowercase and checks if the component's name, description, or any of its tags (converted to lowercase) include the search term.  If they do, the component is included in the filtered list.
    *   **`methods: { addToCart(component) { ... }, removeFromCart(component) { ... } }`:**  This section defines the component's methods (functions).
        *   **`addToCart(component)`:** This method takes a `component` object as an argument and adds it to the `cart` array using `this.cart.push(component)`.
        *   **`removeFromCart(component)`:** This method takes a `component` object as an argument and removes it from the `cart` array. It uses the `filter` method to create a new array containing only the components whose `id` is *not* equal to the `id` of the component to be removed.

3.  **`style scoped` Section:**
    *   **Scoped Styles:** The `scoped` attribute ensures that the styles defined within this block are only applied to the current component, preventing style conflicts with other components or global styles.
    *   **Basic Styling:** The CSS provides basic styling to improve the visual appearance of the marketplace.  It includes styles for fonts, padding, borders, colors, and layout (using `grid`).

**How it Works:**

1.  **Data Initialization:** The `data` object initializes the component's data, including the list of components and the initially empty cart.
2.  **Search Functionality:** The `v-model` on the search input keeps `searchTerm` updated. The `filteredComponents` computed property automatically recalculates whenever `searchTerm` changes, filtering the `components` array and updating the displayed list.
3.  **Adding to Cart:** Clicking the "Add to Cart" button calls the `addToCart` method, which adds the selected component to the `cart` array.
4.  **Removing from Cart:** Clicking the "Remove" button calls the `removeFromCart` method, which removes the selected component from the `cart` array.
5.  **Dynamic Rendering:** Vue's reactivity system automatically updates the UI whenever the data changes (e.g., when components are added to or removed from the cart).  The `v-for` directives ensure that the component list and cart are always up-to-date.

**To Run This Example:**

1.  **Install Vue CLI:**  If you don't have it already: `npm install -g @vue/cli`
2.  **Create a Vue Project:** `vue create marketplace-app` (choose the default preset or manually select features)
3.  **Replace `src/App.vue`:**  Replace the contents of your `src/App.vue` file with the code above.
4.  **Run the Development Server:** `npm run serve`
5.  **Open in Browser:** Open your browser and navigate to the URL provided by the Vue CLI (usually `http://localhost:8080`).

This will give you a running Vue.js component marketplace application with search and cart functionality. You can then expand this basic example to include more features, such as component details pages, ratings, reviews, and more sophisticated cart management.
👁️ Viewed: 7

Comments