Vue3 逻辑分离demo 附git地址

git地址:https://github.com/k1287988804/v3-vite

// vue2 写法
<template>
<div>
    <input v-model="id" />
    <table style="margin: 20px auto; width: 300px;">
        <thead style="width: 300px;">
            <tr>
                <th>编号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>喜好</th>
            </tr>
        </thead>
        <tr v-for="item in table">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.age}}</td>
            <td>{{item.love}}</td>
        </tr>
    </table>
    <input v-model="search" placeholder="请输入查询的姓名"/>
    <div style="margin-top: 20px;">他(她)喜欢:{{love[0].love}}</div>
    <div style="margin-top: 10px">
        转账给他:<input v-model="money"/>
        <button @click="sendMoney">确定转账</button>
    </div>
</div>
</template>

<script>
import { getMockData, sendMoney } from '../api/server'

// 逻辑功能1 根据用户输入的id请求借口返回数据并渲染在页面上
// 逻辑功能2 根据用户输入的姓名查询他的喜好
// 逻辑功能3 提交表单给他打钱

export default {
    data(){
        return {
            // 逻辑1
            id: 1,
            table: [], // id name
            // 逻辑2
            search: '',
            // 逻辑3
            money: 0
        }
    },
    watch: {
        // 逻辑1
        id: 'getMockData'
    },
    computed: {
        // 逻辑2
        love(){
            if(this.search){
                return this.table.filter(item => {
                    if(item.name.indexOf(this.search) !== -1){
                        return true
                    }
                })
            }else {
                return [{love: '无'}]
            }
        }
    },
    methods: {
        // 逻辑1
        async getMockData(){
            const { data } = await getMockData({id: this.id})
            this.table = data 
        },
        // 逻辑3
        async sendMoney(){
            const res = await sendMoney({money: this.money})
            if(res.code === 0){
                alert('打钱成功Q_Q!!'+ res.msg)
            }
        }
    },
    mounted(){
        this.getMockData()
    }
}
</script>

<style lang='less' scoped>
table
{
    border-collapse: collapse;
    margin: 0 auto;
    text-align: center;
}
table td, table th
{
    border: 1px solid #cad9ea;
    color: #666;
    height: 30px;
}
table thead th
{
    background-color: #CCE8EB;
    width: 100px;
}
table tr:nth-child(odd)
{
    background: #fff;
}
table tr:nth-child(even)
{
    background: #F5FAFA;
}

</style>
//vue3 逻辑分离写法
<template>
<div>
    <input v-model="id" />
    <table style="margin: 20px auto; width: 300px;">
        <thead style="width: 300px;">
            <tr>
                <th>编号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>喜好</th>
            </tr>
        </thead>
        <tr v-for="item in table">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.age}}</td>
            <td>{{item.love}}</td>
        </tr>
    </table>
    <input v-model="search" placeholder="请输入查询的姓名"/>
    <div style="margin-top: 20px;">他(她)喜欢:{{love && love[0].love}}</div>
    <div style="margin-top: 10px">
        转账给他:<input v-model="money"/>
        <button @click="sM">确定转账</button>
    </div>
</div>
</template>

<script>
import useTable from '/@/components/About4/useTable'
import useSearch from  '/@/components/About4/useSearch'
import useSend from '/@/components/About4/useSend'

// 逻辑功能1 根据用户输入的id请求借口返回数据并渲染在页面上
// 逻辑功能2 根据用户输入的姓名查询他的喜好
// 逻辑功能3 提交表单给他打钱

export default {
    setup(){
        // 逻辑1
        const { id, table, getMD } = useTable()

        // 逻辑2
        const { search, love } = useSearch(table)

        // 逻辑3
        const { money, sM} = useSend()

        console.log(id)    
        console.log(table)
        
        return {
            id,
            table,
            search,
            love,
            money,
            sM
        }
    },
}
</script>

<style lang='less' scoped>
table
{
    border-collapse: collapse;
    margin: 0 auto;
    text-align: center;
}
table td, table th
{
    border: 1px solid #cad9ea;
    color: #666;
    height: 30px;
}
table thead th
{
    background-color: #CCE8EB;
    width: 100px;
}
table tr:nth-child(odd)
{
    background: #fff;
}
table tr:nth-child(even)
{
    background: #F5FAFA;
}

</style>
// vue3 (tsx)
import { defineComponent, Fragment } from 'vue'
import useTable from '/@/components/About4/useTable'
import useSearch from  '/@/components/About4/useSearch'
import useSend from '/@/components/About4/useSend'
import './about5.less'

export default defineComponent({
    setup(){
        // 逻辑1
        const { id, table } = useTable()

        // 逻辑2
        const { search, love } = useSearch(table)

        // 逻辑3
        const { money, sM } = useSend()

        return () => (
            <div>
                <input  v-model={id.value} />
                <table style={{margin: '20px auto',width: '300px'}}>
                    <thead style={{width: '300px'}}>
                        <tr>
                            <th>编号</th>
                            <th>姓名</th>
                            <th>年龄</th>
                            <th>喜好</th>
                        </tr>
                    </thead>
                    {table.value.map(item => {
                        return <tr>
                            <td>{item.id}</td>
                            <td>{item.name}</td>
                            <td>{item.age}</td>
                            <td>{item.love}</td>
                        </tr>
                    })}
                </table>
                <input v-model={search.value} placeholder="请输入查询的姓名"/>
                <div style={{marginTop: '20px'}}>他(她)喜欢:{love.value && love.value[0].love}</div>
                <div style={{marginTop: '20px'}}>
                    转账给他:<input v-model={money.value}/>
                    <button onClick={sM}>确定转账</button>
                </div>
            </div>
        )
    }
})
// node server.js
const express = require('express')
const app = express()


console.log('server running...')

app.all("*",function(req,res,next){
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin","*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers","content-type");
    //跨域允许的请求方式 
    res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == 'options')
        res.send(200);  //让options尝试请求快速结束
    else
        next();
})

app.get('/api/getMockData', function(req, res){
	let { id } = req.query
	id = Number(id)
	const mockData = {
		1: [
			{id: 11, name: '张三1', age: 17, love: '吃', money: 200},
			{id: 12, name: '李四1', age: 18, love: '喝', money: 500},
			{id: 13, name: '王五1', age: 19, love: '玩', money: 20000},
		],
		2: [
			{id: 21, name: '张三2', age: 22, love: '狗', money: 8888},
			{id: 22, name: '李四2', age: 23, love: '猫', money: 1314},
			{id: 23, name: '王五2', age: 24, love: '鼠', money: 521},
		],
		3: [
			{id: 31, name: '张三3', age: 25, love: '游戏', money: 666},
			{id: 32, name: '李四3', age: 26, love: '音乐', money: 555},
			{id: 33, name: '王五3', age: 27, love: '体育', money: 333},
		]
	}
	if([1,2,3].includes(id)){
		res.send({
			code: 0,
			data: mockData[id]
		})
	}else{
		res.send({
			code: 412,
			data: '无数据'
		})
	}
})

app.post('/api/sendMoney', function(req, res){
	req.on('data', function(data){
		let obj = JSON.parse(data)
		let { money } = obj
		console.log('收到打款:'+ money + '元')
		res.send({
			code: 0,
			msg: '感谢老板'
		})
	})
})



app.listen(3000)