使用Vue中的广告位作为产品摘要示例

当使用不使用SSR(服务器端渲染)或无法实现的项目时,会出现问题,即某些功能或逻辑针对后端打印的静态元素和呈现Vue的组件两次编写。

例如,我们需要实现一个具有以下要求的产品代码段组件:

  • 它可以从后端静态打印,并带有SEO和逻辑的所有必要信息。
  • 它可以用作常规Vue组件,通过v-bind传递参数,附加点击事件等。
  • 它应该显示购买按钮的当前状态
  • 单击“购买”按钮后,预载器应出现,等待篮子的状态

一种解决方案:

  1. 通过附加点击事件来编写静态片段的逻辑,在“购买”按钮上添加和删除负载类别
  2. 在Vue上单独编写一个仅以模板格式实现相同逻辑的组件
  3. 使用第一个项目从后端输出,第二个项目例如用于输出从state或ajax获得的干净数据

因此,我们将编写两种逻辑,一种逻辑直接与DOM一起使用,另一种逻辑与纯数据一起使用。

我对这个问题的解决方案是使用插槽,即设置包含动态参数的默认内容的能力,但是同时,如果将该组件用作内联模板,则所有这些参数都将被后端绘制的参数替换。

让我们编写一个既可以处理静态也可以处理动态的组件:

组件清单
<template> <div> <!--   image   ,       --> <slot name="image"> <!--    --> <a :href="url" class="snippet__image"> <img :src="image"> </a> </slot> <slot name="title"> <a :href="url" class="snippet__title">{{ title }}</a> </slot> <div v-if="!inCart" @click="add" :class="{ 'snippet__buy--load': load }" class="snippet__control" > <slot name="button"> <div class="snippet__button"></div> </slot> </div> <div v-if="inCart" class="snippet__control"> <div class="snippet__button"></div> </div> <div v-if="load" class="snippet__load"></div> </div> </template> <script> //  vuex     import { mapState, mapActions } from 'vuex' export default { props: { id: { type: Number, required: true }, url: { type: String }, image: { type: String }, title: { type: String } }, data() { return { //   load: false, //     inCart: false, } }, computed: { ...mapState({ //     cartItems: ({cart}) => cart.items }), }, mounted() { this.$nextTick(() => { //      this.inCart = this.cartItems.some(item => item.id === this.id) }) }, methods: { ...mapActions([ //     'addToCart' ]), add() { //    this.load = true //   this.addToCart({ id: this.id }) } }, watch: { //      cartItems(items) { //    this.load = false //      this.inCart = items.some(item => item.id === this.id) } } } </script> 


通过后端使用组件:

 <snippet :id="1" class="snippet"> <a slot="image" href="#" class="snippet__image"> <img src="photo.jpg"> </a> <a slot="title" href="#" class="snippet__title"> 1</a> <div slot="button" class="snippet__button"></div> </snippet> 

在其他组件中使用组件:

 <catalog-list> <snippet v-for="item in items" :key="item.id" v-bind="item"></snippet> </catalog-list> 

现在,我们有了一个可以在不同情况下使用的组件。

我想听听您对这种方法的看法,也许有更好的解决方案。

Source: https://habr.com/ru/post/zh-CN422465/


All Articles