vue.js 构建项目_如何在Vue.js中构建实时可编辑数据表

vue.js 构建项目

by Peter Mbanugo

彼得·姆巴努戈(Peter Mbanugo)

如何在Vue.js中构建实时可编辑数据表 (How to build a real-time editable data table in Vue.js)

In data-driven applications, a data table is used to display data in a tabular format with the ability to edit and delete records in place. When you’re working with Vue, there are different open-sourced components that can be used to easily add a data table to your application.

在数据驱动的应用程序中,数据表用于以表格格式显示数据,并具有就地编辑和删除记录的功能。 当您使用Vue时 ,可以使用不同的开源组件轻松地将数据表添加到您的应用程序。

Many applications today have real-time features, and you may wonder how you can synchronize editing and deleting data in real-time. There are three options for this:

如今,许多应用程序都具有实时功能,您可能想知道如何实时同步编辑和删除数据。 共有三个选项:

  1. Use WebSocket API. This is not a good option if some of your users are using browsers that don’t yet support WebSocket.

    使用WebSocket API 。 如果您的某些用户使用的浏览器尚不支持WebSocket,则这不是一个好选择。

  2. Use a library that abstracts away these cross-browser differences with a fallback mechanism, such as Socket.IO, SignalR, and SockJS. With this option, you’d have to manage the server that handles a large number of open connections and deal with scaling.

    使用一个库,该库通过后备机制(例如Socket.IOSignalRSockJS)来抽象化这些跨浏览器的差异。 使用此选项,您将不得不管理处理大量打开的连接并进行扩展的服务器。

  3. Use a service that provides a library that does the same thing as the previous option, but manages the server and scales appropriately. This is a preferable option for companies and teams that are adopting (or have adopted) the serverless approach.

    使用提供库的服务,该库的功能与上一个选项相同,但是可以管理服务器并适当扩展。 对于采用(或已经采用)无服务器方法的公司和团队来说,这是一个更好的选择。

I’ll show you how to build a real-time editable data table in Vue.js using Hamoni Sync as the real-time state synchronisation service. The picture below shows what we’ll build:

我将向您展示如何使用Hamoni Sync作为实时状态同步服务在Vue.js中构建实时可编辑数据表。 下图显示了我们将要构建的内容:

To follow along, you’ll need to have some basic knowledge of Vue. If you have no knowledge of Vue, you can read my previous post to get up to speed with Vue.js. You’ll also need the following tools:

要继续学习,您需要具备Vue的一些基本知识。 如果您不了解Vue,则可以阅读我以前的文章 ,以快速掌握Vue.js。 您还需要以下工具:

  1. Node.js & npm (follow the link to download an installer for your OS)

    Node.js和npm (点击链接以下载适用于您的操作系统的安装程序)

  2. Vue CLI to scaffold a new Vue project. If you don’t have this, run npm install -g vue-cli@2.9.6 from the command line to install it.

    Vue CLI支持新的Vue项目。 如果没有,请从命令行运行npm install -g vue-cli@2.9.6进行安装。

设置项目 (Set up the project)

We’ll set up the project using the Vue CLI and a template from Vuetify. Open the command line and run the command vue init vuetifyjs/simple realtime-datatable-vue. You'll get asked for a name and an author, so accept the default value by hitting enter for each prompt. This will scaffold a new Vue project with a single index.html file.

我们将使用Vue CLI和来自Vuetify模板来设置项目。 打开命令行并运行命令vue init vuetifyjs/simple realtime-datatable-vue 。 系统会要求您输入名称和作者,因此请在每个提示中按Enter接受默认值。 这将使用单个index.html文件搭建一个新的Vue项目。

This file contains script references to Vue and Vuetify. Vuetify is a Material Design Component for Vue.js. It has a v-data-table component with features for sorting, searching, pagination, inline-editing, header tooltips, and row selection.

该文件包含对Vue和Vuetify的脚本引用。 Vuetify是Vue.js的材料设计组件。 它具有一个v-data-table组件,具有用于排序,搜索,分页,内联编辑,标题工具提示和行选择的功能。

添加数据表组件 (Add the data table component)

Open the file index.html with your text editor (or IDE). Replace the content on line 50 with the following:

使用文本编辑器(或IDE)打开文件index.html 。 用以下内容替换第50行上的内容:

<div>    <v-dialog v-model="dialog" max-width="500px">    <v-btn slot="activator" color="primary" dark class="mb-2">New Item</v-btn>    <v-card>        <v-card-title>        <span class="headline">{{ formTitle }}</span>        </v-card-title>        <v-card-text>        <v-container grid-list-md>            <v-layout wrap>            <v-flex xs12 sm6 md4>                <v-text-field v-model="editedItem.name" label="Dessert name"></v-text-field>            </v-flex>            <v-flex xs12 sm6 md4>                <v-text-field v-model="editedItem.calories" label="Calories"></v-text-field>            </v-flex>            <v-flex xs12 sm6 md4>                <v-text-field v-model="editedItem.fat" label="Fat (g)"></v-text-field>            </v-flex>            <v-flex xs12 sm6 md4>                <v-text-field v-model="editedItem.carbs" label="Carbs (g)"></v-text-field>            </v-flex>            <v-flex xs12 sm6 md4>                <v-text-field v-model="editedItem.protein" label="Protein (g)"></v-text-field>            </v-flex>            </v-layout>        </v-container>        </v-card-text>        <v-card-actions>        <v-spacer></v-spacer>        <v-btn color="blue darken-1" flat @click.native="close">Cancel</v-btn>        <v-btn color="blue darken-1" flat @click.native="save">Save</v-btn>        </v-card-actions>    </v-card>    </v-dialog>    <v-data-table :headers="headers" :items="desserts" hide-actions class="elevation-1">    <template slot="items" slot-scope="props">        <td>{{ props.item.name }}</td>        <td class="text-xs-right">{{ props.item.calories }}</td>        <td class="text-xs-right">{{ props.item.fat }}</td>        <td class="text-xs-right">{{ props.item.carbs }}</td>        <td class="text-xs-right">{{ props.item.protein }}</td>        <td class="justify-center layout px-0">        <v-btn icon class="mx-0" @click="editItem(props.item)">            <v-icon color="teal">edit</v-icon>        </v-btn>        <v-btn icon class="mx-0" @click="deleteItem(props.item)">            <v-icon color="pink">delete</v-icon>        </v-btn>        </td>    </template>    </v-data-table></div>

The code above adds a v-dialog component for displaying a dialog to collect data for new records or edit an existing record. Also, it adds the v-data-table which renders the table. We need to define the data and methods used by these components. After line 126, add the following code to the data properties:

上面的代码添加了一个v-dialog组件,用于显示对话框以收集新记录的数据或编辑现有记录。 此外,它还添加了呈现该表的v-data-table table。 我们需要定义这些组件使用的数据和方法。 在第126行之后,将以下代码添加到数据属性中:

dialog: false,headers: [    {        text: 'Dessert (100g serving)',        align: 'left',        sortable: false,        value: 'name'    },    { text: 'Calories', value: 'calories' },    { text: 'Fat (g)', value: 'fat' },    { text: 'Carbs (g)', value: 'carbs' },    { text: 'Protein (g)', value: 'protein' },    { text: 'Actions', value: 'name', sortable: false }],desserts: [],editedIndex: -1,editedItem: {    name: '',    calories: 0,    fat: 0,    carbs: 0,    protein: 0},defaultItem: {    name: '',    calories: 0,    fat: 0,    carbs: 0,    protein: 0},listPrimitive: null

The desserts data property will hold the data to be displayed in the table. The editedItem property will hold values for the record being edited, and the editedIndex will hold the index of the record being edited.

desserts数据属性将保存要在表中显示的数据。 editedItem属性将保存正在编辑的记录的值, editedIndex将保存正在编辑的记录的索引。

Add the following properties after the data property definition, after line 189:

在第189行的data属性定义之后添加以下属性:

computed: {    formTitle() {        return this.editedIndex === -1 ? 'New Item' : 'Edit Item'    }},
watch: {    dialog(val) {        val || this.close()    }},

We added a computed and watch property. The computed property defines formTitle which gives the dialog component a title based on the value of editedIndex. The watch property watches dialog for when its value changes. If the value changes to false, it calls the function close() which will be defined later.

我们添加了一个computedwatch属性。 computed formTitle属性定义formTitle ,该属性根据editedIndex的值为对话框组件提供标题。 watch属性watch其值更改dialog 。 如果该值更改为false,它将调用函数close() ,稍后将对其进行定义。

添加Hamoni Sync (Add Hamoni Sync)

At this junction we need to add Hamoni Sync. It is used to synchronise the application state, and handles conflict resolution to avoid one user overriding another user’s data. To use Hamoni Sync, you’ll have to sign up for an account and application ID. Follow these steps to create an application in Hamoni.

在这个结点,我们需要添加Hamoni Sync。 它用于同步应用程序状态,并处理冲突解决方案,以避免一个用户覆盖另一个用户的数据。 要使用Hamoni Sync,您必须注册一个帐户和应用程序ID。 请按照以下步骤在Hamoni中创建一个应用程序。

  1. Register and login to the Hamoni dashboard.

    注册并登录到Hamoni 仪表板

  2. Enter your preferred application name in the text field and click the create button. This should create the app and display it in the application list section.

    在文本字段中输入首选的应用程序名称,然后单击创建按钮。 这将创建该应用程序并将其显示在“应用程序列表”部分中。
  3. Click the button “Show Account ID” to see your account ID.

    单击按钮“显示帐户ID”以查看您的帐户ID。

Below the script reference to Vuetify on line 139, add a reference to Hamoni Sync:

在第139行上对Vuetify的脚本引用下面,添加对Hamoni Sync的引用:

<script src="https://unpkg.com/hamoni-sync@0.4.0/hamoni.dev.js"><;/script>

Then we need to initialise Hamoni Sync once the Vue component is mounted. Add a mounted property below the watch property:

然后,在安装Vue组件后,我们需要初始化Hamoni Sync。 在watch属性下面添加一个已mounted的属性:

mounted: function () {    let hamoni = new Hamoni("ACCOUNT_ID", "APP_ID");
hamoni.connect().then(() => {        hamoni          .get("vue-table")          .then(primitive => {            this.listPrimitive = primitive            this.desserts = [...primitive.getAll()]            this.subscribeToUpdate()          }).catch(error => {              if (error === "Error getting state from server") {                this.initialise(hamoni);              }              else {                 alert(error);              }          })    }).catch(alert)},

From the code above, we initialize Hamoni Sync with an account and application ID. Replace the string placeholders with the account and application ID from the dashboard. Then it is connected to the Hamoni server by calling hamoni.connect() which returns a promise.

从上面的代码,我们使用帐户和应用程序ID初始化Hamoni Sync。 用仪表板中的帐户和应用程序ID替换字符串占位符。 然后通过调用hamoni.connect()将其连接到hamoni.connect()服务器,该协议返回一个hamoni.connect()

Once connected, we call hamoni.get() with the name of the state stored in Hamoni. In order to retrieve a state from Hamoni, it needs to have been created, otherwise it'll return an error. What I've done here is handle this error within the catch block, such that it calls another function to initialize the state in Hamoni Sync.

连接后,我们使用存储在hamoni.get()中的状态名称调用hamoni.get() 。 为了从Hamoni检索状态,必须先创建状态,否则将返回错误。 我在这里所做的是在catch块中处理此错误,以便它调用另一个函数来初始化Hamoni Sync中的状态。

If the call to get an application state succeeds, it returns an object which will be used to modify data contained in that state. This object is referred to as a Sync primitive. There are three types of Sync primitives:

如果获取应用程序状态的调用成功,它将返回一个对象,该对象将用于修改该状态中包含的数据。 该对象称为“同步”原语。 同步原语有三种类型:

  1. Value Primitive: This kind of state holds simple information represented with datatypes like string, boolean or numbers. It is best suited for cases such as unread message count, toggles, etc.

    值原始值 :这种状态包含简单信息,这些信息用数据类型表示,例如字符串,布尔值或数字。 最适合未读消息计数,切换等情况。

  2. Object Primitive: Object state represents states that can be modelled as a JavaScript object. An example usage could be storing the score of a game.

    Object Primitive :对象状态表示可以建模为JavaScript对象的状态。 示例用法可以是存储游戏得分。

  3. List Primitive: This holds a list of state objects. A state object is a JavaScript object. You can update an item based on its index in the list.

    列表基元 :包含状态对象的列表。 状态对象是JavaScript对象。 您可以根据列表中的项目索引来更新项目。

We’ve used a list primitive for this example. We call primitive.getAll() to get the state and pass it to desserts. After that, it calls the function subscribeToUpdate(). This function will be used to subscribe to state change events from Hamoni Sync.

在此示例中,我们使用了列表原语。 我们调用primitive.getAll()来获取状态并将其传递给desserts 。 之后,它将调用函数subscribeToUpdate() 。 此功能将用于从Hamoni Sync订阅状态更改事件。

Add the following code after the mounted property on line 215:

在第215行的mounted属性之后添加以下代码:

methods: {  initialise(hamoni) {    hamoni.createList("vue-table", [      {        name: 'Frozen Yogurt',        calories: 159,        fat: 6.0,        carbs: 24,        protein: 4.0      },      {        name: 'Ice cream sandwich',        calories: 237,        fat: 9.0,        carbs: 37,        protein: 4.3      },      {        name: 'Eclair',        calories: 262,        fat: 16.0,        carbs: 23,        protein: 6.0      }    ]).then(primitive => {      this.listPrimitive = primitive      this.desserts = this.listPrimitive.getAll()      this.subscribeToUpdate();    }).catch(alert)  },
subscribeToUpdate() {    this.listPrimitive.onItemAdded(item => {      this.desserts.push(item.value)    })
this.listPrimitive.onItemUpdated(item => {      //update the item at item.index      this.desserts.splice(item.index, 1, item.value);    })
this.listPrimitive.onItemDeleted(item => {      //remove the item at item.index      this.desserts.splice(item.index, 1);    })  },
editItem(item) {    this.editedIndex = this.desserts.indexOf(item)    this.editedItem = Object.assign({}, item)    this.dialog = true  },
deleteItem(item) {    const index = this.desserts.indexOf(item)    confirm('Are you sure you want to delete this item?') && this.listPrimitive.delete(index)  },
close() {    this.dialog = false    setTimeout(() => {      this.editedItem = Object.assign({}, this.defaultItem)      this.editedIndex = -1    }, 300)  },
save() {    if (this.editedIndex > -1) {      this.listPrimitive.update(this.editedIndex, this.editedItem)    } else {      this.listPrimitive.push(this.editedItem)    }
this.close()  }}

The code above defines the functions we’ve been referencing thus far.

上面的代码定义了到目前为止我们一直在引用的功能。

The initialise() function creates the list primitive with name as vue-table.

initialise()函数创建名称为vue-table的列表原语。

The subscribeToUpdate() functions contain code to handle when an item is added, updated, or deleted from the list primitive.

subscribeToUpdate()函数包含用于在添加,更新或从列表原语中删除项目时处理的代码。

The deleteItem()function removes an item from the list primitive by calling listPrimitive.delete(index) with the index of the item to delete.

deleteItem()函数通过调用带有要删除项目索引的listPrimitive.delete(index)从列表原语中删除项目。

The save() function calls listPrimitive.push(editedItem) to add a new item to the list primitive, and calls listPrimitive.update(editedIndex, editedItem) to update the record at a certain index.

save()函数调用listPrimitive.push(editedItem)将一个新项添加到列表原语,并调用listPrimitive.update(editedIndex, editedItem)以某个索引更新记录。

This is all the code that’s needed to achieve our objective of a real-time editable data table. Open the index.html file in your browser and the application is ready to use!

这是实现我们的实时可编辑数据表目标所需的全部代码。 在浏览器中打开index.html文件,该应用程序就可以使用了!

这是一个包装! (That’s A Wrap!)

We’ve built a real-time editable data table in Vue.js. Hamoni Sync makes it easy to add real-time functionality. Both Vuetify and Hamoni Sync have npm packages if you’re working with a build system and using single file components. You can find the source code on GitHub.

我们在Vue.js中建立了一个实时可编辑数据表。 Hamoni Sync使添加实时功能变得容易。 如果您使用的是构建系统并使用单个文件组件,则VuetifyHamoni Sync都具有npm软件包。 您可以在GitHub上找到源代码。

翻译自: https://www.freecodecamp.org/news/how-to-build-a-real-time-editable-data-table-in-vue-js-46b7f0b11684/

vue.js 构建项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值