我们一起来学习vue3
这是我学习vue3做的一个demo,功能实现了增删查改。是演示效果,没有真正与数据库打交道。
做这个demo的过程中,我遇到了几个问题。还好一一解决了。所以我觉得必要分享出来。
给各位像我一样的新手。少浪费一些时间,多学习一些新知识。
我也是参考博客园一些人的文章,开始学的。
先看看效果。
整体效果,上面两个导航按钮,
中间搜索框,操作按钮。
下面是内容,有修改,有删除。

看看查询的

还可以吧
再看看修改的。


修改成功了
在来看看删除的。

只有一条了
再看看新增的


现在看看项目结构

现在开始看代码
product页面
<template>
<div>
<!-- 我是产品页面内容
<br/>
{{name}}
<button @click="changeData">改变数据</button> -->
<div class="search-form">
<div class="search-form-key"><input v-model="keywords" placeholder="请输入型号名称" /></div>
<div class="search-btn"><button @click="search">搜索</button> </div>
<div class="search-btn"><button @click="add">添加</button> </div>
</div>
<div>
<!-- {{productData}} -->
<list :list="tempData.length>0?tempData:productData"></list>
<!-- {{tempData}} -->
<br>
<!-- {{tempData.length}} -->
<br>
<!-- <list :list="tempData"></list> -->
</div>
</div>
<teleport to="body">
<div v-if="modalOpen" class="modal">
<div class="model-header">
<button @click="modalOpen = false">
Close
</button>
</div>
<div class="model-body">
<div class="form-item">型号编码<input v-model="productModel.productModelCode"></div>
<div class="form-item">型号名称<input v-model="productModel.productModelName"></div>
<div class="form-item">产品编码<input v-model="productModel.productCode"></div>
<div class="form-item">产品名称<input v-model="productModel.productName"></div>
</div>
<div class="model-footer">
<button class="btn" @click="modalOpen = false">取消</button> <button class="btn"
@click="saveData">确定</button>
</div>
</div>
</teleport>
</template>
<script>
import list from '../../components/List.vue'
import dogData from '../../tempdata/productModel.js'
import {
useStore
} from 'vuex'
import {
ref,
reactive,
toRefs,
onMounted,
onBeforeUpdate,
watchEffect,
toRef
} from 'vue'
export default {
name: 'product',
components: {
list
},
setup() {
let keywords = ref('')
const store = useStore();
//console.log('store', store.state.name);
let name = ref('原始数据');
store.commit('changeName', '改变后的数据');
function changeData() {
store.dispatch('changeVal')
name.value = store.state.name;
};
let productData = reactive(dogData.data.rows);
let tempData = ref([])
//console.log((productData[1]),'reactive')
function search() {
setTimeout(() => {
console.log(keywords.value, "keywords")
let x = productData.filter((item) => {
if (item.productModelName.includes(keywords.value.trim())) {
return item
}
});
console.log(...toRefs(x), "ddddd")
tempData.value = (x);
}, 1000)
}
let modalOpen = ref(false);
let productModel = ref({})
function add(){
modalOpen.value=true;
}
function saveData(){
productData.push(productModel.value);
modalOpen.value=false;
}
return {
name,
keywords,
productData,
changeData,
tempData,
search,
add,
modalOpen,
productModel,
saveData
}
},
}
</script>
<style>
.search-form {
width: 100%;
margin: 20px;
padding: 10px;
display: flex;
justify-content: center;
}
.search-form-key,
.search-btn {
height: 30px;
margin-right: 10px;
}
.search-form-key input {
width: 200px;
height: 30px;
border-radius: 10px;
}
.search-btn button {
height: 37px;
width: 100px;
border-radius: 10px;
}
</style>
自定义组件页面
<template>
<div class="list">
<div class="table-header">
<div class="item-title">型号编码</div>
<div class="item-title">型号名称</div>
<div class="item-title">产品编码</div>
<div class="item-title">产品名称</div>
<div class="item-title">创建时间</div>
<div class="item-title-btnlist">操作</div>
</div>
<div v-for="(item,index) in items">
<ListItem :listItem="item" :selected="changeChecked" :numIndex="index" :deleteItem="deleteRow"></ListItem>
</div>
</div>
</template>
<script>
import {
ref,
reactive
} from 'vue'
import ListItem from './ListItem.vue'
export default {
name: "list",
components: {
ListItem
},
props: {
list: {
type: Array,
default: []
}
},
watch: {
list: function(newValue, oldValue) {
// console.log(newValue,"newValuenewValue")
this.items = newValue;
// console.log(this.items,"thisitems")
}
},
setup(props) {
const items = ref(props.list); //获取从父级传来的值
function changeChecked(num, newData) {
let item = items.value[num] //获得选中的项
item.productModelCode = newData.productModelCode //修改选中状态
item.productModelName = newData.productModelName //修改选中状态
item.productCode = newData.productCode //修改选中状态
item.productName = newData.productName //修改选中状态
//console.log(item,"item")
}
function deleteRow(num) {
//alert(num)
//console.log(items.value,"items.value")
items.value.splice(num, 1)
}
return {
items,
changeChecked,
deleteRow
}
}
}
</script>
<style>
.table-header {
display: flex;
justify-content: space-between;
margin: 10px 0;
text-align: left;
}
.item-title {
flex: 1;
font-size: 18px;
font-weight: bold;
}
.item-title-btnlist {
flex: 1.5;
font-size: 18px;
font-weight: bold;
display: flex;
justify-content: flex-start
}
</style>
最小组件
<template>
<div class="box-item">
<div class="item">{{listItem.productModelCode}}</div>
<div class="item">{{listItem.productModelName}}</div>
<div class="item">{{listItem.productCode}}</div>
<div class="item">{{listItem.productName}}</div>
<div class="item">{{listItem.createTime}}</div>
<div class="item-btnlist">
<div class="btn"><button @click="updateData(listItem)">修改</button></div>
<div class="btn"><button @click="deleteItemData(numIndex)">删除</button></div>
</div>
</div>
<teleport to="body">
<div v-if="modalOpen" class="modal">
<div class="model-header">
<button @click="modalOpen = false">
Close
</button>
</div>
<div class="model-body">
<div class="form-item">型号编码<input v-model="productModel.productModelCode"></div>
<div class="form-item">型号名称<input v-model="productModel.productModelName"></div>
<div class="form-item">产品编码<input v-model="productModel.productCode"></div>
<div class="form-item">产品名称<input v-model="productModel.productName"></div>
</div>
<div class="model-footer">
<button class="btn" @click="modalOpen = false">取消</button> <button class="btn"
@click="saveData">确定</button>
</div>
</div>
</teleport>
</template>
<script>
import {
ref,
reactive,
toRefs,
readonly
} from 'vue'
export default {
name: "listitem",
props: {
listItem: {
type: Object,
default: {}
},
numIndex: {
type: Number //索引ID号属性
},
selected: {
type: Function //方法作为属性传过去
},
deleteItem: {
type: Function //方法作为属性传过去
}
},
setup(props) {
const listItem = (props.listItem) //接受父级传来的参数
let modalOpen = ref(false);
let productModel = ref({})
function saveData() {
props.selected(props.numIndex, productModel.value)
modalOpen.value = false;
}
function deleteItemData(index) {
props.deleteItem(index)
}
return {
modalOpen,
productModel,
saveData,
deleteItemData
}
},
methods:{
updateData(data) {
let tempData={...data}
this.modalOpen = true;
this.productModel =tempData
}
}
}
</script>
<style>
.box-item {
display: flex;
justify-content: space-between;
margin: 10px 0;
text-align: left;
}
.item {
text-align: left;
flex: 1;
/**设置每项宽度**/
}
.item-btnlist {
text-align: left;
flex: 1.5;
/**设置每项宽度**/
display: flex;
justify-content: flex-start
}
.btn {
margin: 0 10px;
}
.modal {
background: red;
z-index: 99999;
width: 40%;
height: 50%;
position: absolute;
left: 25%;
top: 25%;
border-radius: 10px;
}
.model-header {
height: 30px;
text-align: right;
margin: 0 20px;
padding: 10px;
}
.model-body {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.form-item {
flex: 20;
margin: 10px 20px;
}
.form-item input {
height: 30px;
border-radius: 10px;
}
.model-footer {
margin-top: 20px;
display: flex;
justify-content: space-around;
align-items: center;
text-align: center;
height: 45px;
}
.btn {
height: 40px;
width: 120px;
border-radius: 10px;
}
</style>
数据
let data={ "version": 0, "timestamp": 1640827793378, "sign": null, "total": 12, "size": 10, "current": 1, "pages": 2, "resultStateVo": { "code": 200, "msg": "操作成功" }, "rows": [{ "productModelCode": "xm_cp_bm_001", "productModelName": "小明产品型号001", "productCode": "xm_bm_001", "productName": "小明产品001", "description": null, "createTime": "2021-12-13 18:05:39", "creatorId": "104", "updateTime": null, "updateId": null }, { "productModelCode": "hao", "productModelName": "车海洋洗车中心", "productCode": "bm001", "productName": "编码001", "description": "test888", "createTime": "2021-12-09 16:23:48", "creatorId": "1", "updateTime": "2021-12-10 17:38:51", "updateId": "1" }, { "productModelCode": "chy_001", "productModelName": "车海洋001号", "productCode": "bm001", "productName": "编码001", "description": "666sss", "createTime": "2021-12-03 09:26:48", "creatorId": "1", "updateTime": "2021-12-10 17:37:21", "updateId": "1" }, { "productModelCode": "chy_five_wash", "productModelName": "五代+", "productCode": "hello", "productName": "测试111", "description": "一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。", "createTime": "2021-10-22 15:54:06", "creatorId": "1", "updateTime": "2021-12-02 16:43:50", "updateId": "1" }, { "productModelCode": "chy_one_tow_three", "productModelName": "一拖三", "productCode": "chy_product", "productName": "车海洋产品666", "description": "测试", "createTime": "2021-10-22 15:53:44", "creatorId": "1", "updateTime": "2021-12-07 14:41:58", "updateId": "1" }, { "productModelCode": "chy_water", "productModelName": "加水机", "productCode": "chy_product", "productName": "车海洋产品666", "description": "测试", "createTime": "2021-10-22 15:53:26", "creatorId": "1", "updateTime": null, "updateId": null }, { "productModelCode": "chy_digital", "productModelName": "数码洗车机", "productCode": "chy_product", "productName": "车海洋产品666", "description": "测试", "createTime": "2021-10-22 15:52:42", "creatorId": "1", "updateTime": null, "updateId": null }, { "productModelCode": "chy_automatic", "productModelName": "全自动", "productCode": "chy_product", "productName": "车海洋产品666", "description": "测试", "createTime": "2021-10-22 15:52:16", "creatorId": "1", "updateTime": null, "updateId": null }, { "productModelCode": "chy_android", "productModelName": "安卓机", "productCode": "chy_product", "productName": "车海洋产品666", "description": "测试", "createTime": "2021-10-22 15:50:06", "creatorId": "1", "updateTime": null, "updateId": null }, { "productModelCode": "S3", "productModelName": "S3电动自行车", "productCode": "S1-01", "productName": "小白系列电动自行车S101", "description": null, "createTime": "2021-10-22 14:26:49", "creatorId": "1", "updateTime": null, "updateId": null } ] } // 定义数据出口 export default {data}
明天再把一些关键点列一下,今天先发布了。
参考文章
https://www.cnblogs.com/web-learn/p/15722923.html
https://www.cnblogs.com/xiaohuasan/p/15720539.html

浙公网安备 33010602011771号