vue工程项目案例(图书管理+用户管理) vue-router + element ui Plus

提示:文章有点长,请各位小伙伴耐心观看


效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、准备工作

1、创建vue3的工程文件

npm init vue@latest

Attention!!!:一步一步按照老师教的来、值得注意的事我并未选择eslint校验工具,因为在日常开放中会很麻烦。

1、创建对应目录文件

在这里插入图片描述
主页!!!!!!:只要是上面没有的文件全部删除
然后直接跳到 第三步的1、编写index.js(可以直接复制,前提是以上一、二步骤完成或者上面目录对应创建)

2、修改全局样式

1、删除src下的assets下的样式文件 只保留svg文件
2、在src下的main.js中注释掉 import ‘./assets/main.css’
// import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)

app.mount('#app')
3、删除app.vue里面的style以及其他不必要组件
<script setup>
import { RouterLink, RouterView } from 'vue-router'
</script>

<template>
  <RouterView />
</template>

<style scoped>

</style>

2、安装element ui Plus

(1)、进入element官网element ui Plus
(2)、点击指南找到安装中的使用包管理器

npm install element-plus --save

(3)、全局引入 element ui

// main.js
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')

二、开始编写基本页面

1、头部导航编写

使用element ui组件库搭建更快哟
(1)在src文件夹下的component文件夹下新建BarComponent.vue文件
(2)编写
这里我们使用的是vue3.2的写法

1.1、创建3.2vue模版

<template>
  
</template>


<script setup>
//在script 标签上加入 setup 语法糖


</script>

<style scoped>
/*在style上加伤scoped 防止样式干扰*/


</style>

1.2、在BarComponent.vue文件中使用 element ui Plus 的 Navigation 导航 中的 Menu 组件

在官网点击组件 在侧边导航栏找到 Navigation 导航 再找到 Menu
在这里插入图片描述
将以上源代码全部复制到 BarComponent.vue 中

<template>
  <el-menu
    :default-active="activeIndex"
    class="el-menu-demo"
    mode="horizontal"
    :ellipsis="false"
    @select="handleSelect"
  >
    <el-menu-item index="0">LOGO</el-menu-item>
    <div class="flex-grow" />
    <el-menu-item index="1">Processing Center</el-menu-item>
    <el-sub-menu index="2">
      <template #title>Workspace</template>
      <el-menu-item index="2-1">item one</el-menu-item>
      <el-menu-item index="2-2">item two</el-menu-item>
      <el-menu-item index="2-3">item three</el-menu-item>
      <el-sub-menu index="2-4">
        <template #title>item four</template>
        <el-menu-item index="2-4-1">item one</el-menu-item>
        <el-menu-item index="2-4-2">item two</el-menu-item>
        <el-menu-item index="2-4-3">item three</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>
  </el-menu>
</template>

<script lang="ts" setup>
import { ref } from 'vue'

const activeIndex = ref('1')
const handleSelect = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
</script>

<style>
.flex-grow {
  flex-grow: 1;
}
</style>

·注意:这里面的script标签没有 lang = 'ts' 因为我们并未下载 typescript 的解析因此不能使用它
注意 !!!:毫无疑问会报错,因为这是使用的 typescript 的类型校验写法 因此我们需要对他进行改动
在这里插入图片描述

1.3、修改报错部分

删除类型教研即可

<script setup>
const handleSelect = (key, keyPath) => {
  console.log(key, keyPath)
}
</script>

1.4、改造模版

因为他自己的模版是和我们的有差距因此我们需要改一下

<div class="bar">
      <el-menu
            :default-active="activeIndex"
            class="el-menu-demo"
            mode="horizontal"
            :ellipsis="false"
            @select="handleSelect"
        >
            <el-menu-item index="0">
                <el-avatar>LOGO</el-avatar>
            </el-menu-item>
            <div class="flex-grow" />
            <el-menu-item index='1'>登陆</el-menu-item>
            <el-menu-item index='2'>注册</el-menu-item>
            <el-menu-item index='3'>首页</el-menu-item>
            <el-menu-item index='4'>退出登陆</el-menu-item>
        </el-menu>
    </div>

1.5、加入跳转效果

这里我们需要在 menu 上加上 :router=‘true’,这样导航栏就有了router跳转的功能,其中index就是跳转的地址

<div class="bar">
      <el-menu
            :default-active="activeIndex"
            class="el-menu-demo"
            mode="horizontal"
            :ellipsis="false"
            @select="handleSelect"
            
            :router='true'
            
        >
            <el-menu-item index="0">
                <el-avatar>LOGO</el-avatar>
            </el-menu-item>
            <div class="flex-grow" />
            <el-menu-item index='1'>登陆</el-menu-item>
            <el-menu-item index='2'>注册</el-menu-item>
            <el-menu-item index='3'>首页</el-menu-item>
            <el-menu-item index='4'>退出登陆</el-menu-item>
        </el-menu>
    </div>

现在的导航基本完成

2.注册页面编写

(1)在src目录下的view目录下新建RegisterView.vue文件
(2)编写
(2.1)这里的输入框以及按钮我也是使用的element UI

<template>
    <div class="content">
        <div>
            <div style="color:aliceblue">
                <h2>welcome to Register</h2>
            </div>
            <div>
             <!-- element UI 组件库的input输入框-->
                <el-input v-model="username" placeholder="Please input" clearable />
            </div>
            <div style="margin: 10px 0;">
             <!-- element UI 组件库的input密码框-->
                <el-input
                    v-model="password"
                    type="password"
                    placeholder="Please input password"
                    show-password
                />
            </div>
            <div>
             <!-- element UI 组件库的按钮-->
                <el-button @click="Login()" type="primary">Register</el-button>
            </div>
        </div>
    </div>
  </template>
  
  <script setup>
   import { ref } from 'vue';
   //改良一下可以使用 类的方式书写
   let username = ref('')
   let password = ref('')
   let user = ref({}) //用户对象
   let userArray = ref([]) //用户数组 存储所有的用户
   
   function Login(){
    user.value.name = username.value
    user.value.password = password.value
    //本地存储不过多解释
    // 需要注意的是 存数组或对象 要把他们转化成字符串 取的时候又要把字符串还原
    if(JSON.parse(localStorage.getItem('userA')) != null){
        userArray.value = JSON.parse(localStorage.getItem('userA'))
    }
    userArray.value.push(user.value)
      localStorage.setItem('userA',JSON.stringify(userArray.value))
   }
  </script>
  
  <style scoped>
  .content{
    /* width: 500%; */
    background-size: 500%;
    height: 90vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: linear-gradient(125deg,#29c55b,#328be5,#6130e6,#b831e1);
    animation: bcColor 1s linear infinite;
}

@keyframes bcColor{
    0%{background-position: 0% 50%;};
    50%{background-position: 100% 50%;};
    100%{background-position: 0% 50%;}
}
.content >div>div{
    display: flex;
    justify-content: center;
}

.content>div>div>button{
    height: 34px;
    width: 230px;
    text-align: center;
    /* color: aliceblue; */
    font-size: 18px;
    margin: 5px 0;
}

button:hover{
    letter-spacing: 3px;
}
  </style>

3.登陆页面编写

(1)在src目录下的view目录下新建LoginView.vue文件
(2)编写
(2.1)这里的输入框以及登陆按钮我也是使用的element UI

<template>
  <div class="content">
    <div>
        <div style="color:aliceblue">
            <h2>welcome to login</h2>
        </div>
        <div>
        <!-- element UI 组件库的input输入框-->
            <el-input v-model="username" placeholder="Please input" clearable />
        </div>
        <div style="margin: 10px 0;">
         <!-- element UI 组件库的input密码框-->
            <el-input
                v-model="password"
                type="password"
                placeholder="Please input password"
                show-password
            />
        </div>
        <div>
         <!-- element UI 组件库的按钮-->
            <el-button @click="Login()" type="primary">Login</el-button>
        </div>
    </div>
  </div>
</template>

<script setup>
 import { ref } from 'vue';
 import { useRouter, useRoute } from 'vue-router' //引入路由
  const router = useRouter()
  const route = useRoute()
 let username = ref('')
 let password = ref('')
 function Login(){
 //得到本地存储的 user 数组
    let user = JSON.parse(localStorage.getItem('userA'))
    //遍历 user 数组
    user.forEach(el => {
    // 比较数组中是否有我登陆的信息 有就登陆成功
        if(el.name == username.value && el.password == password.value){
            localStorage.setItem('token',`${username.value}/${password.value}`)
            // 跳转到主页面
           // router.push({
            //    path:'main'
           // })
        }
    });
 }
</script>

<style scoped>
.content{
    /* width: 500%; */
    background-size: 500%;
    height: 90vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: linear-gradient(125deg,#29c55b,#328be5,#6130e6,#b831e1);
    animation: bcColor 1s linear infinite;
}

@keyframes bcColor{
    0%{background-position: 0% 50%;};
    50%{background-position: 100% 50%;};
    100%{background-position: 0% 50%;}
}
.content >div>div{
    display: flex;
    justify-content: center;
}

.content>div>div>button{
    height: 34px;
    width: 210px;
    text-align: center;
    /* color: aliceblue; */
    font-size: 18px;
    margin: 5px 0;
}

button:hover{
    letter-spacing: 3px;
}
</style>

4.主页面编写

(1)在src目录下的view目录下新建MainView.vue文件
(2)编写
(2.1)这里的输入框以及按钮我也是使用的element UI
代码如下(示例):

<template>
    <div class="content">
    <!--element ui tab组件-->
        <el-tabs :tab-position="tabPosition" style="height: 90vh" class="demo-tabs">
            <el-tab-pane label="图书管理">
                <BookCViewVue></BookCViewVue>
            </el-tab-pane>
            <el-tab-pane label="用户管理">
             	<UserCViewVue></UserCViewVue>               
            </el-tab-pane>
        </el-tabs>
    </div>
  </template>
  
<script setup>
import { ref } from 'vue'
import BookCViewVue from './ControlView/BookCView.vue'
import UserCViewVue from './ControlView/UserCView.vue'

const tabPosition = ref('left')
  </script>
  
  <style scoped>
  .demo-tabs > .el-tabs__content {
    padding: 32px;
    color: #6b778c;
    font-size: 32px;
    font-weight: 600;
  }
  
  .el-tabs--right .el-tabs__content,
  .el-tabs--left .el-tabs__content {
    height: 100%;
  }
  </style>

5.home页面的编写

(1)在src目录下的view目录下新建HomeView.vue文件
(2)编写
(2.1)这里的输入框以及按钮我也是使用的element UI

<template>
  <div class="content">
  <!--头部导航-->
    <el-affix :offset="0">
      <div class="bar">
        <BarCmpVue></BarCmpVue>
      </div>
    </el-affix>
   <!-- 导航对应内容部分-->
    <div>
      <RouterView></RouterView>
    </div>
  </div>
</template>

<script setup>
import { RouterView} from 'vue-router'

import BarCmpVue from '../components/BarComponent.vue'
</script>


该处使用的url网络请求的数据。


三、开始编写路由

1、编写index.js(可以直接复制,前提是以上一、二步骤完成)

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
    history: createWebHistory(
        import.meta.env.BASE_URL),
    routes: [{
            path: '/',
            name: 'home',
            component: HomeView,
            redirect: '/login',
            children: [{
                    // 当 /user/:id/profile 匹配成功
                    // UserProfile 将被渲染到 User 的 <router-view> 内部
                    path: 'main',
                    component: () =>
                        import ('../views/MainView.vue'),
                },
                {
                    // 当 /user/:id/profile 匹配成功
                    // UserProfile 将被渲染到 User 的 <router-view> 内部
                    path: 'login',
                    component: () =>
                        import ('../views/LoginView.vue'),
                },
                {
                    // 当 /user/:id/profile 匹配成功
                    // UserProfile 将被渲染到 User 的 <router-view> 内部
                    path: 'register',
                    component: () =>
                        import ('../views/Register.vue'),
                }
            ]
        },
        {
            path: '/about',
            name: 'about',
            // route level code-splitting
            // this generates a separate chunk (About.[hash].js) for this route
            // which is lazy-loaded when the route is visited.
            component: () =>
                import ('../views/AboutView.vue')
        },
        {
            path: '/look',
            name: 'look',
            // route level code-splitting
            // this generates a separate chunk (About.[hash].js) for this route
            // which is lazy-loaded when the route is visited.
            component: () =>
                import ('../views/LookBookView.vue')
        },

    ]
})
router.beforeEach(async(to, from) => {
    if (to.path === '/login') return;
    if (to.path === '/register') return;
    //获取token
    const tokenStr = localStorage.getItem('token')
    if (!tokenStr || tokenStr == 'null') return '/login'
        // next()
})
export default router

2、编写头部导航的路由对应关系


<template>
    <div class="bar">
    <!--
		 :default-active 默认显示的页面路由
		 @select="handleSelect" 选择导航时出发的事件
	-->
      <el-menu
            :default-active="activeIndex"
            class="el-menu-demo"
            mode="horizontal"
            :ellipsis="false"
            @select="handleSelect"
            :router="true"
            style="height: 10vh;"
        >
            <el-menu-item index="0">
            <!--头像组件-->
                <el-avatar> {{ userTitle[0] }} </el-avatar>
            </el-menu-item>
            <div class="flex-grow" />
            <!--这里我们使用v-for循环的方式-->
            <el-menu-item v-for="(p,index) in path" :index="p.path" :key="index">{{ p.name }}</el-menu-item>
            <el-menu-item @click="logout()">退出登陆</el-menu-item>
        </el-menu>
    </div>
  </template>
  
  <script setup>
  import { onMounted, ref } from 'vue'
  import { useRouter, useRoute } from 'vue-router'
  const router = useRouter()
  const route = useRoute()
  const path = ref([
   
    {name:'登陆',path:'login'},
    {name:'注册',path:'register'},
    {name:'首页',path:'main'},
])
const logout = () => {
    localStorage.setItem('token',null)
    router.push({
        path:'login'
    })
}
  
  const userTitle = ref('')
    const activeIndex = ref('login')
    //组件对应的方法
    const handleSelect = (key, keyPath) => {
        activeIndex.value = key
        localStorage.setItem('path',activeIndex.value)
    }
    onMounted(() => {
        activeIndex.value = localStorage.getItem('path')
        userTitle.value = localStorage.getItem('token')
        if(userTitle.value == 'null'){
            router.push({
                path:'login'
            })
        }

    })
  </script>
  
  <style scoped>
    .flex-grow {
    flex-grow: 1;
    }
  </style>
  

在这里插入图片描述

四、开始编写主页对应关系页面

以下部分有难度的 element ui官方文档
在 view目录下新建ControlView目录并在目录下新建BookCView.vue / UserCView.vue文件

1、编写BookCView.vue文件(图书管理)

<template>


<!--使用的是element ui里main的table组件-->


    <el-table :data="filterTableData" style="width: 100%;" :stripe="true" :border="true" >
        <el-table-column align="center" label="添加时间" prop="date"/>
        <el-table-column align="center" label="书名" prop="bookName" />
        <!-- <el-table-column align="center" label="详情" prop="textarea" /> -->
        <el-table-column align="center" label="作者" prop="authorName" />
        <el-table-column align="center" >
            <template #header>
                <div style="display: flex;justify-content: space-around;">
                    <el-button @click="addBook()">添加图书</el-button>
                    <el-input v-model="search" size="small" placeholder="查找图书" style="margin-left: 10px;"/>
                </div>
            </template>
            <template #default="scope">
            <el-button size="small" @click="handleEdit(scope.$index, scope.row)" type="primary"
                >编辑信息</el-button
            >
            <el-button size="small" @click="gotolook(scope.$index, scope.row)" type="success"
                >查看图书</el-button
            >
            <el-button
                size="small"
                type="danger"
                @click="handleDelete(scope.$index, scope.row)"
                >删除图书</el-button
            >
            </template>
        </el-table-column>
    </el-table>

    <el-dialog
        v-model="dialogVisible"
        title="图书添加"
        width="80%"
       style="height: 500px;"
    >
        <el-input v-model="bookName" placeholder="输入书名" clearable style="margin-bottom: 10px;"/>
        <el-input v-model="textarea" :rows="13" type="textarea" 
        placeholder="输入内容"
        />
        <template #footer>
        <span class="dialog-footer">
            <el-button @click="dialogVisible = false">Cancel</el-button>
            <el-button type="primary" @click="add()">
            Confirm
            </el-button>
        </span>
        </template>
    </el-dialog>
    <el-dialog
        v-model="dialogVisible11"
        title="图书编辑"
        width="80%"
       style="height: 500px;"
    >
        <el-input v-model="bookName" placeholder="输入书名" clearable style="margin-bottom: 10px;"/>
        <el-input v-model="textarea" :rows="13" type="textarea" 
        placeholder="输入内容"
        />
        <template #footer>
        <span class="dialog-footer">
            <el-button @click="dialogVisible11 = false">Cancel</el-button>
            <el-button type="primary" @click="change()">
            Confirm
            </el-button>
        </span>
        </template>
    </el-dialog>
  </template>
  
  <script setup>
  import { useRouter, useRoute } from 'vue-router'
  import { computed, onMounted, ref } from 'vue'
  import { ElMessage } from 'element-plus'
    const open2 = () => {
        ElMessage({
            message: '操作成功',
            type: 'success',
        })
    }
    const open4 = () => {
        ElMessage.error('操作失败')
    }
  const dialogVisible = ref(false)
  const dialogVisible11 = ref(false)
  const search = ref('') //查找
  let bookName = ref('') //书名
  let textarea = ref('') //内容
  let bookMsg = ref({}) //空书信息
  let tableData= []
  let indexxx = null
  const handleEdit = (index, row) => {
    dialogVisible11.value = true
    bookName.value = row.bookName
    textarea.value = row.textarea
    indexxx = index
  }
  const router = useRouter()
  const route = useRoute()
  const gotolook = (index,row) =>{
      router.push({
        path: 'look',
        query:{id:index},
      })
    }
// 编辑图书
  const change = () =>{
    tableData[indexxx].bookName = bookName.value
    tableData[indexxx].textarea = textarea.value
    localStorage.setItem('bookA',JSON.stringify(tableData))
    dialogVisible11.value = false
    open2()
  }
// 删除图书
  const handleDelete = (index, row) => {
    console.log(index, row)
    tableData.splice(index,1)
    localStorage.setItem('bookA',JSON.stringify(tableData))
    okk()
  }
  const addBook = () => {
    dialogVisible.value = true
  }
//   添加图书
  const add = () => {
    if( bookName.value !='' && textarea.value != ''){
       bookMsg.value.date = new Date
       bookMsg.value.bookName = bookName.value
       bookMsg.value.textarea = textarea.value
       bookMsg.value.authorName = localStorage.getItem('token').split('/')[0]
       tableData.push(bookMsg.value)
       localStorage.setItem('bookA',JSON.stringify(tableData))
       open2()
       dialogVisible.value = false
    }else{
        open4()
    }
  }
  //判断是否有
   //搜索
  let filterTableData  = ref([])
  if(localStorage.getItem('bookA') != null){
    tableData = JSON.parse(localStorage.getItem('bookA'))
    filterTableData = computed(() =>
    tableData.filter(
      (data) =>
        !search.value ||
        data.bookName.toLowerCase().includes(search.value.toLowerCase())
    )
  )
  }
 
  </script>
  <style scoped>

  </style>

2、编写UserCView.vue文件(用户管理)

<template>
  <div>
    <table style="border-collapse:collapse;">
        <tr class="title">
            <td>序号</td>
            <td>姓名</td>
            <td>密码</td>
            <td>操作</td>
        </tr>
        <tr v-for="(u,index) in dataUser" :key="index">
            <td>{{ index+1 }}</td>
            <td>{{ u.name }}</td>
            <td>{{ u.password }}</td>
            <td style="font-weight: 400;">
                <el-button style="font-weight: 400;"  size="small" type="primary" @click="change(u,index)">编辑</el-button>
                <el-button style="font-weight: 400;" size="small" type="success" @click="show(u)">查看</el-button>
                <el-button style="font-weight: 400;" size="small" type="danger" @click="del(index)">删除</el-button>
            </td>
        </tr>
    </table>
  </div>
  <el-dialog
    v-model="dialogVisible"
    title="用户信息"
    width="70%"
  >
    <el-descriptions :title="user.name">
        <el-descriptions-item label="name">{{ user.name }}</el-descriptions-item>
        <el-descriptions-item label="password">{{ user.password }}</el-descriptions-item>
        <el-descriptions-item label="sex">{{ user.sex }}</el-descriptions-item>
        <el-descriptions-item label="address">{{ user.address }}</el-descriptions-item>
    </el-descriptions>
  </el-dialog>


  <el-dialog
    v-model="dialogVisible11"
    title="编辑信息"
    width="50%"
  >
    <el-descriptions :title="user.name">
        <el-descriptions-item label="name">
            <el-input v-model="user.name" placeholder="Please input" clearable />
            <!-- {{ user.name }} -->
        </el-descriptions-item>
        <el-descriptions-item label="password">
            <el-input v-model="user.password" placeholder="Please input" clearable />
            <!-- {{ user.password }} -->
        </el-descriptions-item>
        <el-descriptions-item label="sex">
            <el-input v-model="user.sex" placeholder="Please input" clearable />
            <!-- {{ user.sex }} -->
        </el-descriptions-item>
        <el-descriptions-item label="address">
            <el-input v-model="user.address" placeholder="Please input" clearable />
            <!-- {{ user.address }} -->
        </el-descriptions-item>
    </el-descriptions>
    <el-button type="primary" @click="okk()">提交</el-button>
  </el-dialog>
</template>

<script setup>
import { onMounted ,ref} from "vue";
let dataUser = ref([])
let user = ref({})
onMounted(()=>{
    dataUser.value = JSON.parse(localStorage.getItem('userA'))
    console.log(dataUser.value)
})
const del = (index)=>{
    dataUser.value.splice(index,1)
    localStorage.setItem('userA',JSON.stringify(dataUser.value))
}
const show = (u)=>{
    dialogVisible.value = true
    user = u
}

let indexxx 
const change = (u,index)=>{
    dialogVisible11.value = true
    user = u
    indexxx = index
}
const okk = ()=>{
    dataUser.value[indexxx] = user
    localStorage.setItem('userA',JSON.stringify(dataUser.value))
}
const dialogVisible = ref(false)
const dialogVisible11 = ref(false)


</script>

<style scoped>
input{
    width: 100px;
}
.title{
    /* font-weight: 450; */
    color: #909399;
    
}
table{
    width: 100%;
}
tr{
    text-align: center;
    border: #f2f2f2 1px solid;
}
td{
    width: 200px;
    color: #909399;
    height:35px;
    border: #f0f0f0 1px solid;
    padding:0;
    margin: 0;
}
tr:hover{
    background:#f6f6f6;}
tr:nth-child(even){
    background:#f6f6f6;}
</style>

3、编写LookBookView.vue文件(图书查看)

在view目录下新建LookBookView.vue文件

<template>
  <div class="book">
    <div>
        <h1>{{ data['bookName'] }}</h1>
        <span>作者:{{ data['authorName'] }}</span>
        <br>
        <span>发布时间:{{ data['date'] }}</span>
        <div v-html="data['textarea']" style="margin-top: 20px;"></div>
    </div>
  </div>
</template>

<script setup>
import { useRouter, useRoute } from 'vue-router'
import { onMounted ,ref} from "vue";
const router = useRouter()
const route = useRoute()
let data = ref({})
onMounted(()=>{
    data.value = JSON.parse(localStorage.getItem('bookA'))[route.query['id']]
    console.log(data.value)
    // console.log(route.query['id'])

})
</script>

<style scoped>
.book{
    display: flex;
    width: 100%;
    height: 100vh;
    padding: 10px;
    justify-content: center;
    align-items: center;
}
.book>div{
    width: 80%;
    height: 100vh;
    background-color: #ebebeb;
}
span{
    font-weight: 550;
}
</style>

总结+源码地址

有些难度、不懂得如果留言达到50出视屏讲解
地址:源码地址

  • 3
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值