javascript - 创建可以管理外部数据的抽象组件

标签 javascript vue.js vuetify.js

目前我将 Vuetify 用于基本组件,并希望创建可重用的扩展。例如,包含复选框的列表、具有某些功能的数据表列等。

对于这个问题,我将以包含复选框的列表为例。我创建了以下名为 CheckboxGroup.vue

的组件
<template>
  <v-container>
    <v-checkbox
      v-for="(item, index) in items"
      :key="index"
      v-model="item.state"
      :label="item.title"
    ></v-checkbox>
  </v-container>
</template>

<script>
export default {
  props: {
    items: Array,
    required: true
  }
};
</script>

此组件将对象数组作为属性并为每个条目创建一个复选框。

重要的部分是 v-model="item.state":label="item.title"。大多数情况下,state 属性的名称与 title 属性的名称不同。

出于测试目的,我创建了一个名为 Home.vue 的 View 文件,其中包含一组文档。

<template>
  <v-container>
    <CheckboxGroup :items="documents"/>
    <v-btn @click="saveSettings">Save</v-btn>
  </v-container>
</template>

<script>
import CheckboxGroup from "../components/CheckboxGroup";

export default {
  components: {
    CheckboxGroup
  },
  data: function() {
    return {
      documents: [
        {
          id: 1,
          name: "Doc 1",
          deleted: false
        },
        {
          id: 2,
          name: "Doc 2",
          deleted: false
        },
        {
          id: 3,
          name: "Doc 3",
          deleted: true
        }
      ]
    };
  },
  methods: {
    saveSettings: function() {
      console.log(this.documents);
    }
  }
};
</script>

这次 title 被称为 namestate 被称为 deleted。显然 CheckboxGroup 无法管理文档,因为属性名称错误。

你会如何解决这个问题?你会创建一个计算属性并重命名这些属性吗?我认为这是个坏主意......

顺便说一下,使用 v-model 是个好主意吗?另一种解决方案是监听复选框的更改事件并发出带有项目索引的事件。然后你将不得不监听父组件中的变化。

我认为没有办法创建类似的东西

<CheckboxGroup :items="documents" titleAttribute="name" stateAttribute="deleted"/> 

因为无论如何这都是糟糕的设计。我希望这是一个非常微不足道的问题,每个 Vue 开发人员都遇到过它,因为主要目标应该始终是开发可以多次重用的抽象组件。

请记住,这个复选框问题只是一个例子。这个问题的解决方案也将解决相同或相似的问题:)

最佳答案

如果我明白你想要什么,那就不是那么微不足道了。使用 Prop 是个好主意。您不需要管理文档属性名称,只需将属性名称设置为您的组件即可。

注意

像此解决方案一样,重命名属性或使用代理会占用更多资源,因为您需要运行循环来重命名属性名称或将别名应用于数据数组对象。

示例

CheckboxGroup.vue

  <template>
      <v-container fluid>
        <v-checkbox 
          v-for="(item, index) in items"
          :key="index"
          v-model="item[itemModel]" 
          :label="item[itemValue]"
        ></v-checkbox>
        <hr>
        {{items}}
      </v-container>
    </template>
    <script>

    export default {
      name: "CheckboxGroup",
       props: {

        items: {
          type: Array,
          required:true
        },

        itemValue:{
          type:String,
          default: 'title',

           // validate props if you need
          //validator: function (value) {
          //  return ['title', 'name'].indexOf(value) !== -1
          // }
          // or make required
        },

        itemModel:{
          type:String,
          default: 'state',

           // validate props if you need
           //validator: function (value) {
            // validate props if you need
            // return ['state', 'deleted'].indexOf(value) !== -1
           // }
         // or make required
        }

      }
    };
    </script>

Home.vue

<template>

  <div id="app">
    <checkbox-group :items="documents"
      item-value="name"
      item-model="deleted"
    >

    </checkbox-group>
  </div>
</template>

<script>
import CheckboxGroup from "./CheckboxGroup.vue";

export default {
  name: "App",
  components: {
    // HelloWorld,
    CheckboxGroup
  },
  data: function() {
    return {
      documents: [
        {
          id: 1,
          name: "Doc 1",
          deleted: false
        },
        {
          id: 2,
          name: "Doc 2",
          deleted: false
        },
        {
          id: 3,
          name: "Doc 3",
          deleted: true
        }
      ]
    }
}
};
</script>

根据您的示例,我尝试展示如何创建组件以管理子组件中的对象属性。如果您需要更多信息,请告诉我。

关于javascript - 创建可以管理外部数据的抽象组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56479276/

相关文章:

javascript - 如何创建倒计时器?

javascript - 移动折叠 Bootstrap 在 Chrome 中不起作用

javascript - jQuery 父元素内部 HTML

javascript - 在路由器推送后调用方法有什么负面影响吗? (Vue.js)

vue.js - Vuetify 2.0 : How can I achieve this layout from Vuetify 1. 5?

javascript - 如何将 HTML CSS 图像 slider 转换为 Angular 图像 slider ?

vue.js - Vue-router 组件复用

javascript - v-for prop 值未使用 Bootstrap 模式更新

javascript - Vue.js - 从过滤后的 scopedSlots 动态创建槽

css - Vuetify 步进器文本溢出