任務清單(單檔案)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
<style>
table {
border: 1px solid black;
border-collapse: collapse;
}
tr,
td {
border: 1px solid black;
text-align: center;
padding: 10px;
}
</style>
</head>
<body>
<div id="app">
<h3>小滿記事本</h3>
<p><input type="text" v-model="text" @keyup.enter="addTask"> <button @click="addTask">新增任務</button> <button
@click="clear" v-show="taskList.length > 0">清空任務</button></p>
<table v-show="taskList.length > 0">
<tr>
<td>任務id</td>
<td>任務內容</td>
<td colspan="2">操作</td>
</tr>
<tr v-for="(task, index) in taskList" :key="task.id">
<td>{{index+1}}</td>
<td>{{task.name}}</td>
<td><button @click="changeTask(task)">修改任務</button></td>
<td><button @click="del(task.id)">刪除任務</button></td>
</tr>
</table>
<p v-show="taskList.length > 0">任務數量: {{taskList.length}} </p>
<br>
<!-- 修改任務的時候會用到 -->
<div v-show="isShow">
<label>請輸入新的任務內容<input type="text" v-model="newText"></label> <button @click="relChange">確認修改</button>
</div>
</div>
</body>
<script>
const app = new Vue({
el: "#app",
data: {
taskList: [
{ "id": 1, "name": "欺負小滿" },
{ "id": 2, "name": "逃課" }
],
text: "",
newText: "",
isShow: 0,
// 需要被修改的物件
changeOBJ: null,
},
methods: {
// 新增任務
addTask() {
if (this.text !== "") {
this.taskList.push(
{ id: this.taskList.length + 1, name: this.text }
)
this.text = ""
} else {
alert("請輸入任務名稱!")
}
},
// 刪除任務 根據id去刪除
del(id) {
this.taskList = this.taskList.filter(item => item.id !== id)
},
// 首次修改
changeTask(obj) {
this.isShow = 1
this.changeOBJ = obj
},
// 最終修改
relChange() {
this.changeOBJ.name = this.newText
alert("任務修改成功!")
this.isShow = 0
},
// 清空任務
clear() {
this.taskList = []
}
},
})
</script>
</html>
效果演示
任務清單(元件版)
- 父子通訊,遵循單檔案流原則
- 自己的資料自己負責,即雖然資料是從父傳給子的,但是修改還是要子傳給父,然後父操作修改或者刪除
- 別忘記加scoped,保證樣式互不影響
- 持久化儲存 watch ,created裡面,深度監視 deep
持久化儲存更簡單的寫法
list: JSON.parse(localStorage.getItem("data")) || [預設陣列]
NoteDetail.vue
<template>
<div class="note-detail">
<!-- 頭部 -->
<ToDoHeader @addTask="addTask"></ToDoHeader>
<br>
<!-- 身體 -->
<ToDoMain :list="list" @delTask="delTask"></ToDoMain>
<br>
<!-- 底部 -->
<ToDoFooter :list="list" @clearTask="clearTask" v-show="list.length > 0"></ToDoFooter>
</div>
</template>
<script>
import ToDoHeader from "@/components/ToDoHeader.vue";
import ToDoMain from "@/components/ToDoMain.vue";
import ToDoFooter from "@/components/ToDoFooter.vue";
export default {
components: {
ToDoHeader,
ToDoMain,
ToDoFooter,
},
data() {
return {
baseLsit: [
{ id: 1, name: "按時吃飯" },
{ id: 2, name: "按時摸魚" },
{ id: 3, name: "按時學習" },
],
// 傳遞給子元件的陣列 這裡置空了因為資料從本地讀取
list: [],
// 用來控制當資料為空的適合 底部元件是否顯示
isShow: true
};
},
created() {
// 如果能從本地讀取到資料,預設的資料就從本地獲取
// 如果讀取不到 預設資料就從初始化的baseList獲取
if (localStorage.getItem('data')){
this.list = JSON.parse(localStorage.getItem('data'))
}else{
this.list = this.baseLsit
}
},
methods: {
// 新增單個任務
addTask(value){
this.list.unshift({
id: this.list.length + 1,
name: value
})
},
// 刪除單個任務
delTask(id){
this.list = this.list.filter(item => item.id !== id)
},
// 清空全部任務
clearTask(value){
this.list = value
}
},
watch: {
list: {
deep: true,
handler(newValue){
// 持久化到本地
localStorage.setItem("data", JSON.stringify(newValue))
}
}
}
};
</script>
<style scoped>
.note-detail {
margin: 50px;
width: 500px;
/* height: 300px; */
background-color: tomato;
padding: 50px;
}
</style>
ToDoHeader.vue
<!-- ToDoHeader.vue -->
<template>
<div class="todo-header">
<p>
<label><input type="text" placeholder="請輸入任務名稱" v-model="task" @keyup.13="addTask"></label>
 
<button @click="addTask" class="btn btn-dark">新增任務</button>
</p>
</div>
</template>
<script>
export default {
data() {
return {
task: ""
}
},
methods: {
addTask(){
if (this.task.trim() === ''){
alert('不能為空')
return
}
// 新增讓父元件新增
this.$emit("addTask", this.task)
// 清空預設的輸入
this.task = ''
}
},
}
</script>
<style scoped>
.todo-header p {
margin: auto;
width: 80%;
}
</style>
ToDoMain.vue
<!-- ToDoMain.vue -->
<template>
<div class="todo-main">
<ul v-for="(item, index) in list" :key="item.id">
<li>
<span>{{ index + 1 }} {{ item.name }}</span>
<span @click="del(item.id)">x</span>
</li>
<hr>
</ul>
</div>
</template>
<script>
export default {
props: {
list: {
type: Array,
required: true,
},
},
methods: {
del(id){
this.$emit("delTask", id)
}
},
};
</script>
<style scoped>
.todo-main ul {
list-style: none;
}
li {
/* text-indent: 2em; */
margin: 0 10px 0 10px;
display: flex;
justify-content: space-between
}
</style>
ToDoFooter.vue
<!-- ToDoFooter.vue -->
<template>
<div class="todo-footer">
<div class="inner">
<span>合計:{{ totalCount }}</span>
<span><button @click="clearTask" class="btn btn-danger">清空任務</button></span>
</div>
</div>
</template>
<script>
export default {
props: {
list: {
type: Array,
required: true,
default: () => [],
},
},
computed: {
totalCount() {
return this.list.length;
},
},
methods: {
clearTask(){
this.$emit("clearTask", [])
}
},
};
</script>
<style scoped>
div.inner {
display: flex;
justify-content: space-between;
}
span {
font-weight: 700;
color: #fff;
}
</style>
效果演示
成績計算
案例用到的
-
渲染功能,用到了v-for,渲染的時候使用的是index,這樣保證序號的準確性,別忘記🔑
-
分數判斷,如果大於等於60 應用紅色樣式樣式,否則不使用樣式,使用了 :class
-
有兩個tbody,互斥狀態,只能顯示一個,條件判斷 v-if v-else
-
刪除資料,點選事件,因為這裡使用的a標籤,又使用了prevent,阻止預設事件,然後methods內部使用了filter邏輯更方便計算。
-
計算總分和平均分,使用了計算屬性computed
- 計算總分,使用到了陣列.reduce
- 計算平均分,使用.toFixed()保留兩位小數
- 渲染平均分,使用了三目運算子
-
新增資料,在最後一個輸入框(分數)
- v-model.number 修飾符
- @keyup.13按鍵修飾符
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板</title> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script> <style> #app { margin: 20px; } table { border: 1px solid black; border-collapse: collapse; } tr, td { border: 1px solid black; padding: 10px; text-align: center; } td { width: 200px; } .red-color { color: red } a { text-decoration: none; color: red; } </style> </head> <body> <div id="app"> <p>科目:<input type="text" v-model.trim="subject" placeholder="請輸入科目" @focus="isShow=false"></p> <p>成績:<input type="text" v-model.number="score" placeholder="請輸入分數" @keyup.13="addScore" @focus="isShow=false"></p> <button @click="addScore">新增</button> <span :class="{'red-color':true}" v-show="isShow">{{message}}</span> <br><br> <table> <!-- 頭 --> <thead> <tr> <th>編號</th> <th>科目</th> <th>成績</th> <th>操作</th> </tr> </thead> <!-- 內容 有資料顯示這個tbody--> <tbody v-if="scoreList.length > 0"> <tr v-for="(item, index) in scoreList" :key="item.id"> <td>{{index+1}}</td> <td>{{item.subject}}</td> <!-- 不及格的成績標紅 --> <td :class="{'red-color': item.score < 60}">{{item.score}}</td> <td><a @click.prevent="del(item.id)" href="#" target="_blank">刪除</a></td> </tr> </tbody> <!-- 這裡不要使用v-show去控制 那樣需要寫兩遍 --> <!-- 沒有資料才顯示這個tbody --> <tbody v-else> <tr> <td colspan="4">暫無資料</td> </tr> </tbody> <!-- 腳 --> <tfoot> <tr> <td colspan="4">總分:{{totalScore}}  平均分:{{avgScore}} </td> </tr> </tfoot> </table> </div> </body> <script> const app = new Vue({ el: "#app", data: { // 科目 subject: null, // 分數 score: null, // 全部成績陣列 scoreList: [], // 添科目和分數時沒有資料觸發 message: '', isShow: false }, methods: { // 新增分數 addScore() { this.isShow = false if(this.subject && this.score){ this.scoreList.unshift({ id: this.scoreList.length + 1, subject: this.subject, score: this.score }) // 新增後清空輸入框的內容 this.subject = '' this.score = '' }else{ this.isShow = true this.message = "請填寫資料!" } }, // 從陣列中刪除一個物件,即表格中的tr del(index) { this.scoreList = this.scoreList.filter(item => item.id !== index) } }, computed: { // 總成績 totalScore() { return this.scoreList.reduce((sum, item) => sum + item.score, 0) }, // 平均分 avgScore() { let avg = this.totalScore / this.scoreList.length return avg ? avg.toFixed(2) : 0 } } }) </script> </html>
效果演示
監聽屬性案例(簡單寫法)
- 如果不需要渲染頁面,可以不需要寫到data中,直接透過this.xx操作即可
- setTimeout延遲,時間不要太長,使用者體驗不好
- 設定了setTimeout記得清掉
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
<style>
#app {
margin: 20px;
}
</style>
</head>
<body>
<div id="app">
<h3>簡單監聽屬性1</h3>
<input type="text" v-model="words" placeholder="請輸入內容"> -- {{result}}
<h3>簡單監聽屬性2</h3>
<input type="text" v-model="obj.words" placeholder="請輸入內容"> -- {{objResult}}
</div>
</body>
<script>
const app = new Vue({
el: "#app",
data: {
// 簡單監聽屬性
words: "",
// 裡面的監聽屬性
obj: {
url: 'https://api.vvhan.com/api/ian/rand',
words: ''
},
url: 'https://applet-base-api-t.itheima.net/api/translate',
// 渲染監聽結果 簡單
result: '',
// 物件監聽結果
objResult: '',
// 延時器
timer: null
},
watch: {
// 該方法會在資料變化時,觸發執行
// 這裡的資料屬性名,要與data中定義的保持一致
// 當上面的資料變化了,就會立即呼叫watch中的方法,就是本方法。
// 引數分別是 變化後的新值 和 老值
words(newValue, oldValue) {
clearTimeout(this.timer)
//一些業務邏輯 或 非同步操作。
this.timer = setTimeout(async () => {
axios({
url: this.url,
params: {
words: newValue
}
}).then(response => {
this.result = response.data.data
})
.catch(error => {
return error
})
}, 300) // 設定延遲時間 1秒太長了使用者體驗不好
},
// 如果是物件裡面的子屬性,就會觸發此方法執行,其他同上面一樣
'obj.words'(newValue, oldValue) {
this.timer = setTimeout(async () => {
// 一些業務邏輯 或 非同步操作
axios({
url: this.obj.url,
params: {
words: newValue
}
}).then(response => {
this.objResult = response.data
})
}, 300) // 設定延遲時間 1秒太長了使用者體驗不好
}
}
})
</script>
效果演示
完整監聽屬性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
<style>
#app {
margin: 20px;
}
</style>
</head>
<body>
<div id="app">
<h3>完整監聽屬性</h3>
<select v-model="obj.lang">
<option value="english">英語</option>
<option value="italy">義大利</option>
<option value="chinese">中文</option>
</select>
<input type="text" v-model="obj.words" placeholder="請輸入內容"> -- {{result}}
</div>
</body>
<script>
const app = new Vue({
el: "#app",
data: {
// 翻譯api地址
url: 'https://applet-base-api-t.itheima.net/api/translate',
// 渲染監聽結果 簡單
result: '',
// 物件監聽結果
timer: null,
obj: {
words: '小滿',
lang: 'italy'
},
},
watch: {
obj: {
// watch 完整寫法
deep: true, // 深度監視
immediate: true, // 立刻執行, 一進入頁面handler立即執行
handler(newValue) {
clearTimeout(this.timer)
//一些業務邏輯 或 非同步操作。
this.timer = setTimeout(async () => {
axios({
url: this.url,
params: newValue
}).then(response => {
this.result = response.data.data
})
.catch(error => {
return error
})
}, 300) // 設定延遲時間 1秒太長了使用者體驗不好
}
}
}
})
</script>
</html>
效果演示
水果購物車案例
- 渲染資料,使用v-for
- 刪除功能,使用陣列.filter
- 修改個數,使用++和-- ,需要注意的是,如果數量小於等於1 需要把disable設定為true
- 全選和反選
- 這裡不需要設定兩個陣列,因為每一個物件裡面都包含一個isChacked的布林值,這裡只需要使用v-model繫結陣列.every的返回結果即可,全部滿足返回true,即v-model對應的多選框為true,反之同理
- 用到了計算屬性的完整寫法 get() 和 set()
- 統計選中的個數以及總數量,使用了reduce去更方便的統計,不過這裡有一個坑,需要統計選中的數量,邏輯需要重新理一理
- 持久化到本地
- 這裡使用了監聽屬性,監聽全部,也就是需要用完整的監聽屬性,使用了deep:true
- 這裡使用了localStorage,localStorage是window的物件,可以直接引入使用,Vue是一建立的時候,即created,在這裡寫邏輯,優先從本地去拿值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
<script src="https://kit.fontawesome.com/0f0be1c400.js" crossorigin="anonymous"></script>
<!-- bootstrap5 -->
<link rel="stylesheet" href="E:\vue\css\bootstrap.min.css">
<style>
#app {
margin: 20px;
}
table {
border: 1px solid black;
border-collapse: collapse;
width: 800px !important;
}
tr,
td {
height: 50px;
width: 50px;
line-height: 50px;
padding: 10px;
border: 1px solid black;
text-align: center;
}
.active {
background-color: #f0eeee;
}
/* 商品總價格 */
.price-style {
font-size: 20px;
font-weight: 700;
color: tomato;
}
</style>
</head>
<body>
<div id="app">
<img src="./img/banner.png">
<p><i class="fa-solid fa-house" style="color:tomato"></i> / 購物車</p>
<table class="table" v-if="fruitList.length > 0">
<!-- 頭 -->
<thead>
<tr>
<th>選中</th>
<th>圖片</th>
<th>單價</th>
<th>個數</th>
<th>小計</th>
<th>操作</th>
</tr>
</thead>
<!-- 有內容顯示這個 -->
<tbody>
<tr v-for="(item, index) in fruitList" :key="item.id" :class="{active: item.isChacked}">
<td><input type="checkbox" v-model="item.isChacked"></td>
<td><img :src="item.icon" width="40px"></td>
<td>{{item.price}}</td>
<td>
<button @click="item.num--" :disabled="item.num <= 1" class="btn btn-outline-dark">-</button>
{{item.num}}
<button @click="item.num++" class="btn btn-outline-dark">+</button>
</td>
<!-- 小計 -->
<td>{{(item.price * item.num).toFixed(2)}}</td>
<td><button class="btn btn-danger" @click="del(item.id)">刪除</button></td>
</tr>
</tbody>
<!-- 腳 -->
<tfoot>
<tr>
<td><input type="checkbox" v-model="isChackedAll">全選</td>
<td colspan="3"></td>
<td>總價:<span :class="{'price-style': true}">{{totalPrice.toFixed(2)}}</span> 元</td>
<td><button class="btn btn-success">結算{{totalCount}}</button></td>
</tr>
</tfoot>
</table>
<!-- 分割線 -->
<table class="table table-striped" v-else>
<!-- 沒有選中任何內容選這個 -->
<tbody>
<tr>
<td colspan="6"><i class="fa-solid fa-cart-shopping"></i> / 空空如也</td>
</tr>
</tbody>
</table>
</div>
</body>
<script src="E:\vue\js\bootstrap.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
// 預設資料
baseFruitList: [
{
id: 1,
icon: "./img/fruit/檸檬.png",
isChacked: true,
num: 3,
price: 8
},
{
id: 2,
icon: "./img/fruit/香蕉.png",
isChacked: true,
num: 5,
price: 6
},
{
id: 3,
icon: "./img/fruit/橙子.png",
isChacked: false,
num: 2,
price: 7.7
}
],
// 全部水果陣列 從本地快取讀取 別忘記轉成 json
fruitList: []
},
created(){
// Vue例項建立之後就觸發
if (localStorage.getItem('data')) {
this.fruitList = JSON.parse(localStorage.getItem('data'))
}else{
this.fruitList = this.baseFruitList
}
},
computed: {
// 總價格
totalPrice() {
return this.fruitList.reduce((sum, item) => {
if (item.isChacked){
return sum + item.num * item.price
}else{
return sum
}
}, 0)
},
// 全選 全不選
// 要使用完整的計算屬性去實現
isChackedAll: {
get() {
// 必須所有的小選項卡都選中,全選按鈕才會被選中 -- > every
return this.fruitList.every(item => item.isChacked)
},
set(value) {
this.fruitList.forEach(item => item.isChacked = value)
}
},
// 選中的總數量
totalCount() {
return this.fruitList.reduce((sum, item) =>{
if(item.isChacked){
return sum + item.num
}else{
return sum
}
}, 0
)
}
},
methods: {
// 刪除一個tr
del(id) {
this.fruitList = this.fruitList.filter(item => item.id !== id)
}
},
watch: {
fruitList: {
deep: true,
handler(newValue){
console.log(newValue);
// 需要將變化後的資料 也就newValue 儲存到本地 (不要忘記轉json)
localStorage.setItem('data', JSON.stringify(newValue))
}
}
}
})
</script>
</html>
效果演示
小滿記賬日記
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
<!-- icon圖示 -->
<script src="https://kit.fontawesome.com/0f0be1c400.js" crossorigin="anonymous"></script>
<!-- bootstrap5 -->
<link rel="stylesheet" href="E:\vue\css\bootstrap.min.css">
<!-- 彈窗 -->
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<!-- echarts -->
<script src="E:\vue\js\echarts.js"></script>
<style>
.self-style {
margin-top: 50px;
}
.red {
color: red;
}
.price-style {
font-size: 20px;
font-weight: 700;
text-align: left;
}
table td,
table th {
width: 25%;
text-align: center;
}
/* echarts */
.echarts-box {
width: 70%;
margin: auto;
height: 400px;
border: 1px solid black;
padding: 30px;
}
</style>
</head>
<body>
<div id="app">
<!-- 表格資料 -->
<div class="container self-style">
<p>
<input type="text" v-model.trim="name" placeholder="消費名稱">
<input type="text" v-model.number="price" placeholder="消費價格">
<button class="btn btn-primary" @click="add">新增賬單</button>
</p>
<table class="table border-dart">
<tr>
<th>編號</th>
<th>消費名稱</th>
<th>消費價格</th>
<th>操作</th>
</tr>
<tr v-for="(item, index) in dataList" :key="item.id">
<td>{{index + 1}}</td>
<td>{{item.name}}</td>
<td :class="{red: item.price >= 500}">{{item.price.toFixed(2)}}</td>
<td><button class="btn btn-danger" @click="del(item.id)">刪除</button></td>
</tr>
<tr>
<td class="price-style" colspan="4">消費總計:{{totalPrice}} 元</td>
</tr>
</table>
</div>
<!-- echarts圖表 -->
<div class="echarts-box" id="main"></div>
</div>
</body>
<script src="E:\vue\js\bootstrap.js"></script>
<script>
/*
功能需求:
1. 基本渲染
(1)立刻傳送請求獲取資料created
(2) 拿到資料,存到data的響應式資料中
(3) 結合資料,進行渲染,v-for
(4) 消費統計 => 計算屬性
2. 新增功能
(1) 收集表單資料 v-model
(2) 給新增按鈕註冊點選事件,傳送新增請求
(3) 需要重新渲染
3. 刪除功能
(1) 註冊點選事件,傳參傳入 id
(2) 根據 id 傳送刪除請求
(3) 需要重新渲染
4. 餅圖渲染
(1) 初始化一個餅圖 echarts.init(dom) mounted鉤子實現
(2) 根據資料實時更新餅圖 echarts.setOption({...}) 原本已經設定過的,就不需要再次設定了
*/
const app = new Vue({
el: "#app",
data: {
// 拿到的全部資料
dataList: [],
// 消費名稱
name: '',
// 消費價格
price: '',
},
created() {
this.getList()
},
computed: {
// 獲取總價格
totalPrice() {
return this.dataList.reduce((sum, item) => sum + item.price, 0)
}
},
mounted() {
this.myEchart = echarts.init(document.querySelector('#main'))
let option = {
// 大標題
title: {
text: '小滿的記賬日記',
// 子標題
// subtext: 'Fake Data',
left: 'center'
},
// 提示框
tooltip: {
trigger: 'item'
},
// 圖例
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: '消費賬單', // 滑鼠懸停顯示的
type: 'pie',
radius: '70%', // 圓的半徑
// radius: ["50%", "80%"], // 圓的半徑 和內半徑大小
// data: [
// { value: 1048, name: 'Search Engine' },
// ],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
this.myEchart.setOption(option);
},
methods: {
// 渲染資料
async getList() {
// await 一定要寫在 async 中
const res = await axios('https://applet-base-api-t.itheima.net/bill', {
params: {
creator: '小滿'
}
})
this.dataList = res.data.data
let option = {
series: [
{
// { value: 1, name: 2 }
data: this.dataList.map(item => ({ value: item.price, name: item.name }))
}
]
}
this.myEchart.setOption(option)
},
// 新增資料
async add() {
if (!this.name) {
swal({
title: '錯誤!',
text: "請輸入正確的消費名稱",
icon: "error"
})
return
}
if (typeof this.price !== 'number') {
swal({
title: "錯誤!",
text: '請輸入正確的價格',
icon: "error"
})
return
}
const res = await axios.post('https://applet-base-api-t.itheima.net/bill', {
creator: '小滿',
name: this.name,
price: this.price
})
swal({
text: '更新資料成功',
icon: 'success'
})
this.getList()
// 資料新增成功之後,別忘記清空之前的
this.name = ''
this.price = ''
},
// 刪除記錄
async del(id) {
const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)
swal({
text: '刪除成功',
icon: "success"
})
// 別忘記重新渲染
this.getList()
}
},
})
</script>
</html>