Vue.js是一个Web应用程序开发框架。 它具有一个反应系统,使开发人员可以模拟应用程序的状态并进行管理。 结果,当数据更改时,它会自动反映在用户界面上,而开发人员则不需要访问DOM。 如果使用纯JavaScript或jQuery创建应用程序,则意味着必须显式访问DOM元素并更新它们,以便在界面中反映应用程序状态的变化,例如,在网页上显示一些数据。
对于大型项目,手动管理状态和应用程序界面的同步并非易事。 该材料的作者(我们将其翻译为您今天关注的翻译)希望分享他的研究结果,该研究旨在比较使用
Hoodie (这是
购物清单)的
渐进式Web应用程序的两个版本。 该应用程序的基本版本是用纯JS编写的(在
本文中,您可以找到有关它的详细信息)。 在这里,通过对框架基本功能的通过检查以及对最终情况的分析,将显示应用程序到Vue.js的翻译。
准备申请如果您想通读本材料,则可以使用纯JS下载应用程序的
源代码,并跟随作者,使用Vue处理它。
将产品添加到列表
▍JavaScript
该应用程序允许用户将产品添加到他们的购物清单。 这是在公用文件夹的
index.html
文件中完成的。 标记包含在此文件的第92-124行中。 她在那儿。
<div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="text" id="new-item-name"> <label class="mdl-textfield__label" for="new-item-name">Item Name</label> </div> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="number" id="new-item-cost"> <label class="mdl-textfield__label" for="new-item-cost">Item Cost</label> </div> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="number" id="new-item-quantity"> <label class="mdl-textfield__label" for="new-item-quantity">Quantity</label> </div> </div> <div class="mdl-grid center-items"> <button id="add-item" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> Add Item </button> </div> </div>
用于处理和保存数据的代码位于文件
public/js/src/index.js
。 第28行的
saveItems()
函数负责从用于输入数据的控件中收集值并保存该数据。 此功能绑定到
add-item
按钮的
click
事件。 这是有问题的代码。
function saveNewitem() { let name = document.getElementById("new-item-name").value; let cost = document.getElementById("new-item-cost").value; let quantity = document.getElementById("new-item-quantity").value; let subTotal = cost * quantity; if (name && cost && quantity) { hoodie.store.withIdPrefix("item").add({ name: name, cost: cost, quantity: quantity, subTotal: subTotal }); document.getElementById("new-item-name").value = ""; document.getElementById("new-item-cost").value = ""; document.getElementById("new-item-quantity").value = ""; } else { let snackbarContainer = document.querySelector("#toast"); snackbarContainer.MaterialSnackbar.showSnackbar({ message: "All fields are required" }); } } document.getElementById("add-item").addEventListener("click", saveNewitem);
ueVue
在开始使用Vue重做该项目之前,您需要将框架连接到页面。 在我们的示例中,在
index.html
文件中,操作如下:
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
另外,在标识符
app
添加了
<div>
元素,该元素将包括位于
body
标记内的所有页面元素。 这是因为初始化Vue实例时,需要告知框架应管理页面的哪一部分。 在这种情况下,我们通知框架它应该处理此块中的所有内容。
现在让我们开始将项目转换为Vue。 首先,我们修改标记以使用一些Vue指令。 Vue指令是前缀为
v-
特殊属性。 这是更新的标记的外观。
<form v-on:submit.prevent="onSubmit"> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="text" id="new-item-name" v-model="name"> <label class="mdl-textfield__label" for="new-item-name">Item Name</label> </div> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="number" id="new-item-cost" v-model.number="cost"> <label class="mdl-textfield__label" for="new-item-cost">Item Cost</label> </div> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="number" id="new-item-quantity" v-model.number="quantity"> <label class="mdl-textfield__label" for="new-item-quantity">Quantity</label> </div> </div> <div class="mdl-grid center-items"> <button id="add-item" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> Add Item </button> </div> </form>
这里使用的
v-on
指令用于侦听DOM事件。 在上面的代码段中,它在form元素中用于侦听
submit
事件。 此外,它使用
.prevent
修饰符,该修饰符告诉
v-on
指令在被调用事件上调用
event.preventDefault()
。 我们将
v-model
指令用于用于数据输入的元素。 应用于表单元素时,需要创建双向数据绑定。 这使系统可以根据项目的类型自动选择更新项目的正确方法。 我们将
.number
修饰符用于
cost
和
quantity
元素。
这会自动将值类型从输入字段转换为数字。 这样做是因为即使将类型设置为
type=number
,该值也将始终作为字符串返回。 此处使用的修饰符可自动执行以前必须独立执行的其他检查。
接下来,创建一个新文件
index-vue.js
,在其中我们将代码与
index.js
的代码等效,但要使用Vue的功能。 该文件的代码如下所示。 这将创建具有必要属性的Vue实例,用于处理表单事件和收集数据。
const vm = new Vue({ el: "#app", data: { name: "", cost: "", quantity: "" }, methods: { onSubmit: function(event) { if (this.name && this.cost && this.quantity) { hoodie.store.withIdPrefix("item").add({ name: this.name, cost: this.cost, quantity: this.quantity, subTotal: this.cost * this.quantity }); this.name = ""; this.cost = ""; this.quantity = ""; } else { const snackbarContainer = document.querySelector("#toast"); snackbarContainer.MaterialSnackbar.showSnackbar({ message: "All fields are required" }); } } } });
在此代码段中创建了Vue实例,并将一个对象传递给它,告诉Vue如何配置应用程序。
el
属性告诉框架DOM元素的标识符,该元素的内容将由Vue控制,并将其视为“领土”。 在此元素内,Vue将考虑特定于框架的指令(以及与Vue相关的所有其他内容),并且在初始化框架的过程中,它将为应用程序配置绑定和事件处理程序。
data
属性包含应用程序的状态。 初始化Vue时,此处可用的对象中的所有属性都将添加到框架的响应系统中。 当更改与DOM相关的值时,正是此系统的操作导致了用户界面的更新。 例如,使用
v-model="name"
指令将
name
属性绑定到
name
控件。 该指令设置属性和控件之间的双向数据绑定,以便在将某些内容添加到输入字段(或从中删除某些内容)时,对
name
属性进行更新。 结果,输入字段的内容反映了
name
属性的当前状态。
同样,绑定可与其他控件一起使用。
methods
属性包含函数。 在上面的代码中,
onSubmit()
了
onSubmit()
函数,该函数附加到
submit()
表单事件。
在页面上显示保存的数据
▍JavaScript
onSubmit
函数将数据保存在连帽衫中。 之后,我们需要以表格的形式显示添加到商店的商品。 对于使用常规JS编写的应用程序,相应的标记如下所示:
<div class="mdl-grid center-items"> <table id="item-table" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp"> <thead> <tr> <th class="mdl-data-table__cell--non-numeric">Item Name</th> <th class="mdl-data-table__cell--non-numeric">Cost</th> <th class="mdl-data-table__cell--non-numeric">Quantity</th> <th class="mdl-data-table__cell">Sub-total</th> <th class="mdl-data-table__cell--non-numeric"> <button class="mdl-button mdl-js-button mdl-button--icon"> <i class="material-icons">delete</font></i> </button> </th> </tr> </thead> <tbody> </tbody> </table> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="number" id="total-cost" readonly value="0"> <label class="mdl-textfield__label" for="cost">Total Item Cost</label> </div> </div> <script id="item-row" type="text/template"> <tr id='{{row-id}}'> <td class="mdl-data-table__cell--non-numeric">{{name}}</td> <td class="mdl-data-table__cell--non-numeric">{{cost}}</td> <td class="mdl-data-table__cell--non-numeric">{{quantity}}</td> <td class="mdl-data-table__cell">{{subTotal}}</td> <td class="mdl-data-table__cell--non-numeric"> <button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored" onclick="pageEvents.deleteItem('{{item-id}}')"> <i class="material-icons">remove</font></i> </button> </td> </tr> </script>
该表将包含动态添加的数据,因此在这里我们需要某种方式用实际数据替换占位符,并将发生的事情附加到DOM。 在我们的案例中,使用微模板解决了这个问题。
以下代码显示了添加时用户界面中的元素。
function addItemToPage(item) { if (document.getElementById(item._id)) return; let template = document.querySelector("#item-row").innerHTML; template = template.replace("{{name}}", item.name); template = template.replace("{{cost}}", item.cost); template = template.replace("{{quantity}}", item.quantity); template = template.replace("{{subTotal}}", item.subTotal); template = template.replace("{{row-id}}", item._id); template = template.replace("{{item-id}}", item._id); document.getElementById("item-table").tBodies[0].innerHTML += template; let totalCost = Number.parseFloat( document.getElementById("total-cost").value ); document.getElementById("total-cost").value = totalCost + item.subTotal; } hoodie.store.withIdPrefix("item").on("add", addItemToPage);
在此代码片段中,从DOM获取模板,将占位符替换为实际数据,并将结果附加到DOM。 然后计算出
total-cost
指标,该列表中所有元素的总金额也显示在界面中。
ueVue
切换到Vue时,脚本使用的模板已删除,表元素也进行了重新设计,以便它们使用Vue
v-for
指令,该指令可让您遍历包含元素数据的属性。 这就是现在相应标记的外观。
<div class="mdl-grid center-items"> <table id="item-table" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp"> <thead> <tr> <th class="mdl-data-table__cell--non-numeric">Item Name</th> <th class="mdl-data-table__cell--non-numeric">Cost</th> <th class="mdl-data-table__cell--non-numeric">Quantity</th> <th class="mdl-data-table__cell">Sub-total</th> <th class="mdl-data-table__cell--non-numeric"> <button class="mdl-button mdl-js-button mdl-button--icon"> <i class="material-icons">delete</font></i> </button> </th> </tr> </thead> <tbody> <tr v-for="item in items" :key="item._id"> <td class="mdl-data-table__cell--non-numeric">{{ item.name}}</td> <td class="mdl-data-table__cell--non-numeric">{{ item.cost}}</td> <td class="mdl-data-table__cell--non-numeric">{{ item.quantity}}</td> <td class="mdl-data-table__cell">{{ item.subTotal}}</td> <td class="mdl-data-table__cell--non-numeric"> <button @click="deleteRow(item._id)" class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored"> <i class="material-icons">remove</font></i> </button> </td> </tr> </tbody> </table> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <h4>Total Cost: {{ total }}</h4> </div> </div>
实际上,标记没有做太大的改变。 在此,将复制先前使用的微模板的内容,并使用Vue文本的指令和插值机制。
v-for
伪指令用于列出其数据来自
items
属性的
items
。 使用Vue
{{ item.name }}
构造的功能,数据以列显示。 此机制类似于微模板中使用的占位符。 总金额也使用文本插值技术显示在页面上。
现在,我们将完成
index-vue.js
的JavaScript代码,并获得以下内容。
const vm = new Vue({ el: "#app", data: { name: "", cost: "", quantity: "", items: [] }, computed: { // total: function() { // `this` vm return this.items.reduce( (accumulator, currentValue) => accumulator + currentValue.subTotal, 0 ); } }, methods: { ..... } }); hoodie.store.withIdPrefix("item").on("add", item => vm.items.push(item));
由Vue准备的上述机制的一种变体比使用常规JS创建的机制更短,更简单。 在此代码中,添加了
items
数据属性,该属性在上述
v-for
指令中使用。 添加项目后,Hoodie会调用一个函数,该函数执行
vm.items.push(item)
操作来更新应用程序的状态,这要归功于Vue反应性系统自动更新用户界面。 为了计算总量,不需要引用DOM元素。 在这里,我们使用计算属性,该属性使用
.reduce()
函数处理
items
数据集。 现在,借助Vue反应系统,当这些值更改时,用户界面也会更新。 好消息是,所有这些使程序员不必担心在代码中使用DOM元素。 结果,在较小的代码的帮助下,我们解决了相同的问题,在常规JS的情况下,这需要更多的代码(可能,如果在这种情况下使用jQuery库代替普通的JS,那么猫的体积也会更大,比使用Vue时获得的版本)。
将项目另存为列表
▍JavaScript
添加元素后,需要保存它们以备后用,以便以后可以将其他元素列表添加到系统中。 该应用程序具有一个“
Save List
按钮,该按钮用于收集数据,使用Hoodie工具将它们保存为一组元素,并允许用户向系统中添加一组新元素。
使用常规JavaScript时,相应的函数绑定到
onClick
button
onClick
。 这是标记。
//index.html <div class="mdl-grid center-items"> <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" onclick="pageEvents.saveList()"> Save List </button> </div>
这是功能代码。
//index.js function saveList() { let cost = 0; hoodie.store .withIdPrefix("item") .findAll() .then(function(items) { for (var item of items) { cost += item.subTotal; } // hoodie.store.withIdPrefix("list").add({ cost: cost, items: items }); // hoodie.store .withIdPrefix("item") .remove(items) .then(function() { // document.getElementById("item-table").tBodies[0].innerHTML = ""; // var snackbarContainer = document.querySelector("#toast"); snackbarContainer.MaterialSnackbar.showSnackbar({ message: "List saved succesfully" }); }) .catch(function(error) { // var snackbarContainer = document.querySelector("#toast"); snackbarContainer.MaterialSnackbar.showSnackbar({ message: error.message }); }); }); } window.pageEvents = { deleteItem: deleteItem, saveList: saveList .... };
ueVue
切换到Vue不需要太多更改。 我们仍然需要将处理程序绑定到单击按钮时触发的事件,此外,我们需要在初始化Vue对象的
methods
属性时将
methods
(该事件的处理程序)添加到Vue对象的
methods
属性中。
这就是标记的外观。
<div class="mdl-grid center-items"> <button @click="saveList" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> Save List </button> </div>
@click="saveList"
是
v-on:click="saveList"
的简写
v-on:click="saveList"
。 此机制用于侦听DOM事件。 在纯JS编写的应用程序版本中使用了相同的
saveList
函数,该函数已添加到Vue对象的
methods
属性中。
导航栏
▍JavaScript
现在可以将元素另存为列表,我们希望能够查看先前保存的列表以及其中包含的商品总价值的数据。 此信息将显示在另一页上,如下所示。
先前创建的产品列表中的数据该页面的标记位于
public/history.html
文件中,相应的JS代码位于
public/js/src/history.js
。 此页面和
index.html
有一些共同点。 这是位于窗口顶部的导航栏。 该面板包含指向不同页面的链接,“
Login
和“
Register
链接,这些链接调用用于输入系统并在其中进行注册的对话框形式。 还有一个
Signout
按钮,用于注销。
在使用普通JS创建的应用程序版本中,您必须在两个页面上复制相同的标记。 这就是导航栏HTML代码的样子。
<header class="mdl-layout__header"> <div class="mdl-layout__header-row"> <span class="mdl-layout-title">Shopping List</span> <div class="mdl-layout-spacer"></div> <nav class="mdl-navigation mdl-layout--large-screen-only"> <a class="mdl-navigation__link" href="index.html">Home</a> <a class="mdl-navigation__link" href="history.html">History</a> <a onclick="pageEvents.showLogin()" style="cursor: pointer" class="mdl-navigation__link login">Login</a> <a onclick="pageEvents.showRegister()" style="cursor: pointer" class="mdl-navigation__link register">Register</a> <a onclick="pageEvents.signout()" style="cursor: pointer" class="mdl-navigation__link logout">Logout</a> </nav> </div> </header> <div class="mdl-layout__drawer"> <span class="mdl-layout-title">Shopping List</span> <nav class="mdl-navigation"> <a class="mdl-navigation__link" href="index.html">Home</a> <a class="mdl-navigation__link" href="history.html">History</a> <a onclick="pageEvents.showLogin()" style="cursor: pointer" class="mdl-navigation__link login">Login</a> <a onclick="pageEvents.showRegister()" style="cursor: pointer" class="mdl-navigation__link register">Register</a> <a onclick="pageEvents.signout()" style="cursor: pointer" class="mdl-navigation__link logout">Logout</a> </nav> </div>
在分析了这段代码之后,您会发现,当您单击
Login
,
Register
和
Logout
链接时,将调用它们的相应功能。 该标记中描述的元素的事件处理程序在
index.js
文件中定义。
import * as shared from "shared.js"; .... shared.updateDOMLoginStatus(); window.pageEvents = { showLogin: shared.showLoginDialog, showRegister: shared.showRegisterDialog, signout: shared.signOut };
负责使用导航栏的功能在
shared.js
文件中声明。
// let loginDialog = document.querySelector("#login-dialog"); dialogPolyfill.registerDialog(loginDialog); let registerDialog = document.querySelector("#register-dialog"); dialogPolyfill.registerDialog(registerDialog); let showLoginDialog = function() { loginDialog.showModal(); }; let showRegisterDialog = function() { registerDialog.showModal(); }; let showAnonymous = function() { document.getElementsByClassName("login")[0].style.display = "inline"; document.getElementsByClassName("login")[1].style.display = "inline"; document.getElementsByClassName("register")[0].style.display = "inline"; document.getElementsByClassName("register")[1].style.display = "inline"; document.getElementsByClassName("logout")[0].style.display = "none"; document.getElementsByClassName("logout")[1].style.display = "none"; }; let showLoggedIn = function() { document.getElementsByClassName("login")[0].style.display = "none"; document.getElementsByClassName("login")[1].style.display = "none"; document.getElementsByClassName("register")[0].style.display = "none"; document.getElementsByClassName("register")[1].style.display = "none"; document.getElementsByClassName("logout")[0].style.display = "inline"; document.getElementsByClassName("logout")[1].style.display = "inline"; }; let updateDOMLoginStatus = () => { hoodie.account.get("session").then(function(session) { if (!session) { // showAnonymous(); } else if (session.invalid) { // , showAnonymous(); } else { // showLoggedIn(); } }); }; let signOut = function() { hoodie.account .signOut() .then(function() { showAnonymous(); let snackbarContainer = document.querySelector("#toast"); snackbarContainer.MaterialSnackbar.showSnackbar({ message: "You logged out" }); location.href = location.origin; }) .catch(function() { let snackbarContainer = document.querySelector("#toast"); snackbarContainer.MaterialSnackbar.showSnackbar({ message: "Could not logout" }); }); }; export { signOut, showRegisterDialog, showLoginDialog, updateDOMLoginStatus };
此代码导出
index.js
中使用的功能。
showLoginDialog()
和
showRegisterDialog()
函数分别显示模式对话框,用于登录和注册。
signout()
函数允许用户注销并调用
showAnonymous()
函数,该函数隐藏
Logout
链接并仅显示
Register
和
Login
链接。
updateDOMLoginStatus()
函数检查用户是否已通过身份验证并显示适当的链接。 页面加载时调用此函数。
为了在两个不同页面上具有相同的导航栏,我们必须复制标记,访问DOM元素并使用CSS功能来显示和隐藏面板上的链接。 让我们看一下Vue创建的替代导航栏。
ueVue
许多Web应用程序在不同页面上使用相同的代码片段。 例如,导航栏。 此类实体应放置在容器中或作为适合重复使用的组件显示。 Vue为开发人员提供了一个组件引擎,可用于解决我们正在考虑的问题。 Vue组件是独立的且可重复使用。
转移项目以使用Vue组件,我们创建一个新文件
shared-vue.js
。 Vue, . .
Vue.component("navigation", { props: ["isLoggedIn", "toggleLoggedIn"], template: `<div> <header class="mdl-layout__header"> <div class="mdl-layout__header-row"> <span class="mdl-layout-title">Shopping List</span> <div class="mdl-layout-spacer"></div> <nav class="mdl-navigation mdl-layout--large-screen-only"> <a class="mdl-navigation__link" href="index.html">Home</a> <a class="mdl-navigation__link" href="history.html">History</a> <a v-show="!isLoggedIn" @click="showLogin" style="cursor: pointer" class="mdl-navigation__link login">Login</a> <a v-show="!isLoggedIn" @click="showRegister" style="cursor: pointer" class="mdl-navigation__link register">Register</a> <a v-show="isLoggedIn" @click="logout" style="cursor: pointer" class="mdl-navigation__link logout">Logout</a> </nav> </div> </header> <div class="mdl-layout__drawer"> <span class="mdl-layout-title">Shopping List</span> <nav class="mdl-navigation"> <a class="mdl-navigation__link" href="index.html">Home</a> <a class="mdl-navigation__link" href="history.html">History</a> <a v-show="!isLoggedIn" @click="showLogin" style="cursor: pointer" class="mdl-navigation__link login">Login</a> <a v-show="!isLoggedIn" @click="showRegister" style="cursor: pointer" class="mdl-navigation__link register">Register</a> <a v-show="isLoggedIn" @click="logout" style="cursor: pointer" class="mdl-navigation__link logout">Logout</a> </nav> </div> </div>`, methods: { showLogin: function() { const loginDialog = document.querySelector("#login-dialog"); dialogPolyfill.registerDialog(loginDialog); loginDialog.showModal(); }, showRegister: function() { const registerDialog = document.querySelector("#register-dialog"); dialogPolyfill.registerDialog(registerDialog); registerDialog.showModal(); }, logout: function() { hoodie.account .signOut() .then(() => { this.toggleLoggedIn(); }) .catch(error => { alert("Could not logout"); }); } } });
Vue,
navigation
, , , Vue. —
props .
props
— . , , ,
props
.
isLoggedIn
, .
,
template
, , . , , JS, , Vue —
v-show
@click
.
v-show
.
Logout
,
isLoggedIn
true
,
false
—
Login
Register
. , Vue
v-if
v-else
.
.
@click
—
v-on:click
.
showLogin
,
showRegister
logout
.
methods
.
logout
, ,
this.toggleLoggedIn()
,
props
. ,
props
, ,
isLoggedin
, . , Vue DOM.
index.html
. , 59-84. .
<navigation v-bind:is-logged-in="isLoggedIn" v-bind:toggle-logged-in="toggleLoggedIn"></navigation>
JS-
isLoggedIn
toggleLoggedIn
, ,
props
, , kebab-case.
v-bind
.
isLoggedIn
.
:
v-bind
, .
<navigation :is-logged-in="isLoggedIn" :toggle-logged-in="toggleLoggedIn"></navigation>
isLoggedIn
,
toggleLoggedIn
— , Vue
index-vue.js
. .
const vm = new Vue({ el: "#app", data: { name: "", cost: "", quantity: "", items: [], isLoggedIn: false }, computed: { .....// }, methods: { toggleLoggedIn: function() { this.isLoggedIn = !this.isLoggedIn; }, ......// } }); .....// hoodie.account.get("session").then(function(session) { if (!session) { // vm.isLoggedIn = false; } else if (session.invalid) { vm.isLoggedIn = false; } else { // vm.isLoggedIn = true; } });
Vue , , , , Vue. , Vue DOM , .
▍JavaScript
Login
Register
, . , , , . 171-244
index.html
100-158
history.html
.
<dialog id="login-dialog" class="mdl-dialog"> <h4 class="mdl-dialog__title">Login</h4> <div class="mdl-dialog__content"> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <input class="mdl-textfield__input" type="text" id="login-username"> <label class="mdl-textfield__label" for="login-username">Username</label> </div> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <input class="mdl-textfield__input" type="password" id="login-password"> <label class="mdl-textfield__label" for="login-password">Password</label> </div> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <span id="login-error"></span> </div> </div> </div> <div class="mdl-dialog__actions"> <button onclick="pageEvents.closeLogin()" type="button" class="mdl-button close">Cancel</button> <button onclick="pageEvents.login()" type="button" class="mdl-button">Login</button> </div> </dialog> <dialog id="register-dialog" class="mdl-dialog"> <h4 class="mdl-dialog__title">Login</h4> <div class="mdl-dialog__content"> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <input class="mdl-textfield__input" type="text" id="register-username"> <label class="mdl-textfield__label" for="register-username">Username</label> </div> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <input class="mdl-textfield__input" type="password" id="register-password"> <label class="mdl-textfield__label" for="register-password">Password</label> </div> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <span id="register-error"></span> </div> </div> </div> <div class="mdl-dialog__actions"> <button onclick="pageEvents.closeRegister()" type="button" class="mdl-button close">Cancel</button> <button onclick="pageEvents.register()" type="button" class="mdl-button">Register</button> </div> </dialog>
, ,
shared.js
index.js
.
//shared.js // let loginDialog = document.querySelector("#login-dialog"); dialogPolyfill.registerDialog(loginDialog); let registerDialog = document.querySelector("#register-dialog"); dialogPolyfill.registerDialog(registerDialog); let closeLoginDialog = function() { loginDialog.close(); }; let closeRegisterDialog = function() { registerDialog.close(); }; let showAnonymous = function() { ... }; let showLoggedIn = function() { .... }; let signOut = function() { .... }; let updateDOMLoginStatus = () => { .... }; let login = function() { let username = document.querySelector("#login-username").value; let password = document.querySelector("#login-password").value; hoodie.account .signIn({ username: username, password: password }) .then(function() { showLoggedIn(); closeLoginDialog(); let snackbarContainer = document.querySelector("#toast"); snackbarContainer.MaterialSnackbar.showSnackbar({ message: "You logged in" }); }) .catch(function(error) { console.log(error); document.querySelector("#login-error").innerHTML = error.message; }); }; let register = function() { let username = document.querySelector("#register-username").value; let password = document.querySelector("#register-password").value; let options = { username: username, password: password }; hoodie.account .signUp(options) .then(function(account) { return hoodie.account.signIn(options); }) .then(account => { showLoggedIn(); closeRegisterDialog(); return account; }) .catch(function(error) { console.log(error); document.querySelector("#register-error").innerHTML = error.message; }); }; export { register, login, closeRegisterDialog, closeLoginDialog, ... };
index.js.
//index.js window.pageEvents = { closeLogin: shared.closeLoginDialog, showLogin: shared.showLoginDialog, closeRegister: shared.closeRegisterDialog, showRegister: shared.showRegisterDialog, login: shared.login, register: shared.register, signout: shared.signOut };
▍Vue
Vue . , .
Vue.component("login-dialog", { data: function() { return { username: "", password: "" }; }, props: ["toggleLoggedIn"], template: `<dialog id="login-dialog" class="mdl-dialog"> <h4 class="mdl-dialog__title">Login</h4> <div class="mdl-dialog__content"> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <input v-model="username" class="mdl-textfield__input" type="text" id="login-username"> <label class="mdl-textfield__label" for="login-username">Username</label> </div> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <input v-model="password" class="mdl-textfield__input" type="password" id="login-password"> <label class="mdl-textfield__label" for="login-password">Password</label> </div> </div> <div class="mdl-grid center-items"> <div class="mdl-textfield mdl-js-textfield"> <span id="login-error"></span> </div> </div> </div> <div class="mdl-dialog__actions"> <button @click="closeLogin" type="button" class="mdl-button close">Cancel</button> <button @click="login" type="button" class="mdl-button">Login</button> </div> </dialog>`, methods: { closeLogin: function() { const loginDialog = document.querySelector("#login-dialog"); dialogPolyfill.registerDialog(loginDialog); loginDialog.close(); }, login: function(event) { hoodie.account .signIn({ username: this.username, password: this.password }) .then(() => { this.toggleLoggedIn(); this.closeLogin(); }) .catch(error => { console.log(error); document.querySelector("#login-error").innerHTML = "Error loggin in"; }); } } });
data
,
props
,
template
methods
,
Vue.component()
.
, , Vue .
//index.html <login-dialog v-bind:toggle-logged-in="toggleLoggedIn"></login-dialog>
.
, , Vue. ,
, . ,
- Push API .
总结
-, JS, Vue.js. HTML, CSS JavaScript (jQuery), Vue . ES6 , .
Vue , , . , , , Vue. , , Vue .
, JS.
— , Vue.
亲爱的读者们! - ?
