摘要

众所周知,Vue3的易用性比Vue2提升了许多,尤其是Vue3的组合式API语法糖,ref响应式,大大提高了开发效率,因此使用Vue3如果不使用组合式的写法,可以说是白用了。本文直接在html中使用Vue的组合式API编写简单的例子,可以在不依赖构建工具的条件下快速编写查询单页和列表单页,甚至可以直接使用。

开发准备

准备Vue.js的生产环境版本,准备axios.js文件,本地使用。

vue.global.prod.js
axios.min.js

线上CDN:

https://cdn.bootcdn.net/ajax/libs/vue/3.4.30/vue.global.prod.js
https://cdn.bootcdn.net/ajax/libs/axios/1.7.2/axios.min.js

后端示例代码

getData.php

本文主要是讲Vue3在html中编写的单页,所以后端这边就用固定的示例数据做演示。

<?php
    
    // 数据格式
    header("Content-type:application/json");
    
    // 示例数据
    $data = array(
        array(
            'title' => '[你想活出怎样的人生][WEB-MKV/2G][日语中字][1080p][2023][日本][奇幻] ',
        ),
        array(
            'title' => '[挑战/深空拯救者][WEB-MKV/2G][英语中字][1080p][2023][欧美][科幻]',
        ),
        array(
            'title' => '[哥斯拉-1.0][BD-MKV/5.46GB][简繁字幕][1080P][2023][日本][剧情]',
        ),
        array(
            'title' => '[太空孤航][WEB-MKV/2G][英语中字][1080p][2024][美国][科幻]',
        ),
        array(
            'title' => '[超能敢死队:冰封之城][BD-MKV/7G][英语中字][1080p][2024][美国][动作]',
        ),
        array(
            'title' => '[海热症/深海扩散][BD-MKV/5G][英语中字][1080p][2019][美国][科幻]',
        ),
        array(
            'title' => '[明日边缘/异空战士][BD-MKV/7G][英语中字][1080p][2014][美国][动作]',
        ),
    );
    
    // 返回结果
    $ret = array(
        'code' => 0,
        'msg' => '查询成功',
        'datalist' => $data
    );
    
    echo json_encode($ret);
?>

查询单页

search.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, viewport-fit=cover">
    <title>Vue3查询单页</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            font-family: -apple-system-font,BlinkMacSystemFont,"Helvetica Neue","PingFang SC","Hiragino Sans GB","Microsoft YaHei UI","Microsoft YaHei",Arial,sans-serif;
        }
        /*v-cloak指令被添加到根元素上*/
        /*在CSS中定义了一个display: none;的规则*/
        /*这样在Vue实例渲染前*/
        /*根元素和其子元素都会被隐藏*/
        /*当Vue实例渲染完成后,v-cloak指令会被自动移除*/
        /*同时CSS规则不再生效*/
        /*因此根元素和其子元素会显示出来*/
        /*请将v-cloak指令放在你希望受影响的根元素上*/
        [v-cloak] {
            display: none;
        }
        body {
            background: rgb(250, 157, 59);
        }
        .page_title {
            margin: 30px auto 0;
            text-align: center;
            color: #fff;
            font-size: 25px;
        }
        .formView {
            width: 90%;
            margin: 30px auto;
            display: flex;
            height: 50px;
        }
        .formView .inputView {
            flex: 1;
            border-radius: 10px;
            outline: none;
            text-indent: 15px;
            font-size: 16px;
            background: #fff;
            border: none;
        }
        .formView .buttonView {
            width: 100px;
            border-radius: 10px;
            outline: none;
            border: none;
            margin-left: 15px;
            font-size: 16px;
            color: #333;
            background: #fff;
        }
        .loadding {
            text-align: center;
            font-size: 15px;
            margin: 10px auto 30px;
            display: block;
            color: #fff;
        }
        .data_list {
            width: 88%;
            margin: 0 auto;
        }
        .data_list .data-li {
            background: #fff;
            padding: 15px;
            list-style: none;
            border-bottom: 1px solid #eee;
        }
    </style>
</head>
<body>
    <div id="app" v-cloak>
        <p class="page_title">
            Vue3查询单页
        </p>
        <form @submit.prevent="handleSubmit" class="formView">
            <input type="text" v-model="keyword" class="inputView" placeholder="输入关键词" />
            <button type="submit" class="buttonView">查询</button>
        </form>
        <p v-if="loading" class="loadding">{{ ret_text }}</p>
        <div v-if="error" class="loading">加载错误:{{ error }}</div>
        <div v-if="datalist">
            <ul class="data_list">
                <li v-for="item in datalist" v-key="index" class="data-li">
                    {{item.title}}
                </li>
            </ul>
        </div>
    </div>
    
    <!--引入全局js-->
    <script src="vue.global.prod.js"></script>
    <script src="axios.min.js"></script>
    <script>
        const { createApp, ref } = Vue;

        createApp({
            setup() {
                
                // 定义响应式数据
                const keyword = ref('');
                const loading = ref(false);
                const ret_text = ref('');
                const error = ref(null);
                const datalist = ref(null);
                
                // 网络请求
                const fetchData = async () => {
                    
                    loading.value = true;
                    ret_text.value = '查询中';
                    error.value = null;
                    
                    try {
                        const response = await axios.get(`getData.php?kw=${keyword.value}`);
                        if(response.data.code == 0) {
                            
                            // 渲染数据列表
                            datalist.value = response.data.datalist;
                        }else {
                            
                            // 查询反馈
                            ret_text.value = response.data.msg;
                        }
                        
                        // 隐藏lodadding
                        loading.value = false;
                    } catch (err) {
                        
                        // 查询错误
                        error.value = err.message;
                        ret_text.value = '查询错误';
                        
                        // 隐藏lodadding
                        loading.value = false;
                    }
                };
                
                // 提交表单
                const handleSubmit = () => {
                    
                    // 表单验证
                    if(keyword.value) {
                        fetchData();
                    }else {
                        loading.value = true;
                        ret_text.value = '请输入关键词';
                    }
                };
                
                // 将以上涉及到的响应式数据返回
                return {
                    datalist,
                    keyword,
                    loading,
                    ret_text,
                    error,
                    handleSubmit,
                };
            }
        }).mount('#app');
    </script>
</body>

</html>

截图

image.png

在线演示:https://demo.likeyunba.com/Vue3-SPA/search.html

列表单页

list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, viewport-fit=cover">
    <title>Vue3查询单页</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            font-family: -apple-system-font,BlinkMacSystemFont,"Helvetica Neue","PingFang SC","Hiragino Sans GB","Microsoft YaHei UI","Microsoft YaHei",Arial,sans-serif;
        }
        /*v-cloak指令被添加到根元素上*/
        /*在CSS中定义了一个display: none;的规则*/
        /*这样在Vue实例渲染前*/
        /*根元素和其子元素都会被隐藏*/
        /*当Vue实例渲染完成后,v-cloak指令会被自动移除*/
        /*同时CSS规则不再生效*/
        /*因此根元素和其子元素会显示出来*/
        /*请将v-cloak指令放在你希望受影响的根元素上*/
        [v-cloak] {
            display: none;
        }
        body {
            background: rgb(250, 157, 59);
        }
        .page_title {
            margin: 30px auto 0;
            text-align: center;
            color: #fff;
            font-size: 25px;
        }
        .formView {
            width: 90%;
            margin: 30px auto;
            display: flex;
            height: 50px;
        }
        .formView .inputView {
            flex: 1;
            border-radius: 10px;
            outline: none;
            text-indent: 15px;
            font-size: 16px;
            background: #fff;
            border: none;
        }
        .formView .buttonView {
            width: 100px;
            border-radius: 10px;
            outline: none;
            border: none;
            margin-left: 15px;
            font-size: 16px;
            color: #333;
            background: #fff;
        }
        .loadding {
            text-align: center;
            font-size: 15px;
            margin: 10px auto 30px;
            display: block;
            color: #fff;
        }
        .data_list {
            width: 88%;
            margin: 0 auto;
        }
        .data_list .data-li {
            background: #fff;
            padding: 15px;
            list-style: none;
            border-bottom: 1px solid #eee;
        }
    </style>
</head>
<body>
    <div id="app" v-cloak>
        <p class="page_title">
            Vue3列表单页
        </p><br>
        <p v-if="loading" class="loadding">{{ ret_text }}</p>
        <div v-if="error" class="loading">加载错误:{{ error }}</div>
        <div v-if="datalist">
            <ul class="data_list">
                <li v-for="item in datalist" v-key="index" class="data-li">
                    {{item.title}}
                </li>
            </ul>
        </div>
    </div>
    
    <!--引入全局js-->
    <script src="vue.global.prod.js"></script>
    <script src="axios.min.js"></script>
    <script>
        const { createApp, ref, onMounted } = Vue;

        createApp({
            setup() {
                
                // 定义响应式数据
                const loading = ref(false);
                const ret_text = ref('');
                const error = ref(null);
                const datalist = ref(null);
                
                // 网络请求
                const fetchData = async () => {
                    
                    loading.value = true;
                    ret_text.value = '获取中';
                    error.value = null;
                    
                    try {
                        const response = await axios.get(`getData.php`);
                        if(response.data.code == 0) {
                            
                            // 渲染数据列表
                            datalist.value = response.data.datalist;
                        }else {
                            
                            // 请求反馈
                            ret_text.value = response.data.msg;
                        }
                        
                        // 隐藏lodadding
                        loading.value = false;
                    } catch (err) {
                        
                        // 请求错误
                        error.value = err.message;
                        ret_text.value = '请求错误';
                        
                        // 隐藏lodadding
                        loading.value = false;
                    }
                };
                
                // 生命周期函数:挂载完成后
                onMounted(() => {
                    
                    // 发起网络请求
                    fetchData();
                });
                
                // 将以上涉及到的响应式数据返回
                return {
                    datalist,
                    loading,
                    ret_text,
                    error
                };
            }
        }).mount('#app');
    </script>
</body>

</html>

截图

image.png

演示:https://demo.likeyunba.com/Vue3-SPA/list.html

完整代码结构

image.png

本文作者

TANKING


TANKING
4.8k 声望493 粉丝

热爱分享,热爱创作,热爱研究。