vue基础

vue基础

1.0 vue上手

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>{{message}}</h1>
    </div>
    <script type="module" >
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data(){
                return {
                    message:"hello vue",
                }
            }
        }).mount("#app");
        
    </script>
</body>
</html>

我们在这里通过es模式进行导入,通过远程cdn拉取 Vue 的 ES 模块构建版本。然后创建vue实例,

1.1 v-for

我们使用v-for实现循环渲染 基于原始数据多次渲染元素或模板块。

基础用法:

<div v-for="item in items">
  {{ item.text }}
</div>

看一个例子:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
      <p v-for="name in names">{{name}}</p>
    </div>
    <script type="module" >
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data(){
                return {
                    names:["张三","李四","王五"],
                }
            }
        }).mount("#app");
        
    </script>
</body>
</html>

1.2 v-bind

我们在属性中如果想要获取到数据,直接使用插值表达式是不行的,这里需要使用到v-bind

具体的用法为:

v-bind:属性="变量"

将其可以简化为
:属性="变量"

我们来看一个复杂点的例子:

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用户列表示例</title>
    <style>
        table {
            width: 80%;
            margin: 20px auto;
            border-collapse: collapse;
        }

        th,
        td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        th {
            background-color: #f2f2f2;
        }

        img {
            width: 40px;
            height: 40px;
            object-fit: cover;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <div id="app">
        <table>
            <thead>
                <tr>
                    <th>序号</th>
                    <th>姓名</th>
                    <th>头像</th>
                    <th>性别</th>
                    <th>职位</th>
                    <th>入职时间</th>
                    <th>更新时间</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(user, index) in userList" :key="user.id">
                    <td>{{index+1}}</td>
                    <td>{{user.name}}</td>
                    <td><img :src="user.image" alt="头像" /></td>
                    <td>{{user.gender}}</td>
                    <td>{{user.job}}</td>
                    <td>{{user.entrydate}}</td>
                    <td>{{user.updatetime}}</td>
                </tr>
            </tbody>
        </table>
    </div>

    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    userList: [
                        {
                            id: 1,
                            name: 'Tom',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 1,
                            job: '班主任',
                            entrydate: '2015-03-01',
                            updatetime: '2015-05-01 12:05:00'
                        },
                        {
                            id: 2,
                            name: 'Jerry',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 2,
                            job: '学生',
                            entrydate: '2018-07-10',
                            updatetime: '2020-08-15 10:30:00'
                        }
                    ]
                }
            }
        }).mount('#app');
    </script>
</body>

</html>

其中我们在渲染表格的时候,遇到图片需要渲染,这里就需要使用到v-bind

1.3 条件渲染

条件渲染指令有两个,v-ifv-show

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用户列表示例</title>
    <style>
        table {
            width: 80%;
            margin: 20px auto;
            border-collapse: collapse;
        }

        th,
        td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        th {
            background-color: #f2f2f2;
        }

        img {
            width: 40px;
            height: 40px;
            object-fit: cover;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <div id="app">
        <table>
            <thead>
                <tr>
                    <th>序号</th>
                    <th>姓名</th>
                    <th>头像</th>
                    <th>性别</th>
                    <th>职位</th>
                    <th>入职时间</th>
                    <th>更新时间</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(user, index) in userList" :key="user.id">
                    <td>{{index+1}}</td>
                    <td>{{user.name}}</td>
                    <td><img :src="user.image" alt="头像" /></td>
                    <td>
                        <span v-if="user.gender==1">
                            男
                        </span>
                        <span v-else-if="user.gender==2">
                            女
                        </span>
                        <span v-else>
                            人妖
                        </span>
                    </td>
                    <td>{{user.job}}</td>
                    <td>{{user.entrydate}}</td>
                    <td>{{user.updatetime}}</td>
                </tr>
            </tbody>
        </table>
    </div>

    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    userList: [
                        {
                            id: 1,
                            name: 'Tom',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 1,
                            job: '班主任',
                            entrydate: '2015-03-01',
                            updatetime: '2015-05-01 12:05:00'
                        },
                        {
                            id: 2,
                            name: 'Jerry',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 2,
                            job: '学生',
                            entrydate: '2018-07-10',
                            updatetime: '2020-08-15 10:30:00'
                        }
                    ]
                }
            }
        }).mount('#app');
    </script>
</body>

</html>

此时渲染出的结果:

image-20250813142717532

可以看到性别可以顺利显示了

使用v-show同理 :

                        <span v-show="user.job==1">
                            班主任
                        </span>
                        <span v-show="user.job==2">
                            学生
                        </span>

那这两种条件控制语句到底有什么区别呢?v-if控制的是元素是否创建,v-show控制的是元素是否显示

也就是说当我们使用v-if时,根据条件创建元素,使用v-show时,一次将所有元素全部创建,根据css的样式属

性display控制是否显示对于频繁切换的情况用v-show好一点

1.4 v-model

v-model 可以在组件上使用以实现双向绑定。

对于下面的代码:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="name">
        <h1>{{name}}</h1>
    </div>
    <script type="module">
            import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
            createApp({
                data(){
                    return{
                        name:"bob",
                    }
                }
            }).mount("#app");
    </script>
</body>
</html>

渲染后的结果为:

image-20250813144326151

当我们更改输入框中的值,因为这个值就是我们使用v-model绑定的值,下面使用插值显示的值会随着改变,这

就是一个双向绑定的过程,本质上改变的是我们一开始定义的值

再看一个应用:

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用户列表示例</title>
    <style>
        table {
            width: 80%;
            margin: 20px auto;
            border-collapse: collapse;
        }

        th,
        td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        th {
            background-color: #f2f2f2;
        }

        img {
            width: 40px;
            height: 40px;
            object-fit: cover;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <div id="app">
        <span>sex:</span>
        <select name="usersex" v-model="sex">
            <option value="1">男</option>
            <option value="2">女</option>
        </select>
        <span>job</span>
            <select name="usersex" v-model="job">
                <option value="1">班主任</option>
                <option value="2">学生</option>
        </select>
        <div>性别{{sex}} 职业:{{job}}</div>
            
        <table>
            <thead>
                <tr>
                    <th>序号</th>
                    <th>姓名</th>
                    <th>头像</th>
                    <th>性别</th>
                    <th>职位</th>
                    <th>入职时间</th>
                    <th>更新时间</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(user, index) in userList" :key="user.id">
                    <td>{{index+1}}</td>
                    <td>{{user.name}}</td>
                    <td><img :src="user.image" alt="头像" /></td>
                    <td>
                        <span v-if="user.gender==1">
                            男
                        </span>
                        <span v-else-if="user.gender==2">
                            女
                        </span>
                        <span v-else>
                            人妖
                        </span>
                    </td>
                    <td>
                        <span v-show="user.job==1">
                            班主任
                        </span>
                        <span v-show="user.job==2">
                            学生
                        </span>
                    </td>
                    <td>{{user.entrydate}}</td>
                    <td>{{user.updatetime}}</td>
                </tr>
            </tbody>
        </table>
    </div>

    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    userList: [
                        {
                            id: 1,
                            name: 'Tom',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 1,
                            job: 1,
                            entrydate: '2015-03-01',
                            updatetime: '2015-05-01 12:05:00'
                        },
                        {
                            id: 2,
                            name: 'Jerry',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 2,
                            job: 2,
                            entrydate: '2018-07-10',
                            updatetime: '2020-08-15 10:30:00'
                        }
                    ],
                    sex:"",
                    job:""
                }
            }
        }).mount('#app');
    </script>
</body>

</html>

1.5 v-on

v-on的目的是简化事件绑定的过程

用法就是v-on:事件="函数或者代码"

<input type="button" name="点一下试试" value="test" v-on:click="handle()">

v-on: 可以简化成 @ 需要注意的是,我们可以直接将代码写入到后面,但是由于作用域等问题可能会出问题,

所以我们采取函数调用的方式

给一个实例代码:

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用户列表示例</title>
    <style>
        table {
            width: 80%;
            margin: 20px auto;
            border-collapse: collapse;
        }

        th,
        td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        th {
            background-color: #f2f2f2;
        }

        img {
            width: 40px;
            height: 40px;
            object-fit: cover;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <div id="app">
        <span>sex:</span>
        <select name="usersex" v-model="sex">
            <option value="男">男</option>
            <option value="女">女</option>
        </select>
        <span>job</span>
            <select name="usersex" v-model="job">  
                <option value="班主任">班主任</option>
                <option value="学生">学生</option>
        </select>
        <span>性别{{sex}} 职业:{{job}}</span>
        <input type="button" name="user" value="查询" @click="handle()">

        <table>
            <thead>
                <tr>
                    <th>序号</th>
                    <th>姓名</th>
                    <th>头像</th>
                    <th>性别</th>
                    <th>职位</th>
                    <th>入职时间</th>
                    <th>更新时间</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(user, index) in userList" :key="user.id">
                    <td>{{index+1}}</td>
                    <td>{{user.name}}</td>
                    <td><img :src="user.image" alt="头像" /></td>
                    <td>
                        <span v-if="user.gender==1">
                            男
                        </span>
                        <span v-else-if="user.gender==2">
                            女
                        </span>
                        <span v-else>
                            人妖
                        </span>
                    </td>
                    <td>
                        <span v-show="user.job==1">
                            班主任
                        </span>
                        <span v-show="user.job==2">
                            学生
                        </span>
                    </td>
                    <td>{{user.entrydate}}</td>
                    <td>{{user.updatetime}}</td>
                </tr>
            </tbody>
        </table>
    </div>

    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    userList: [
                        {
                            id: 1,
                            name: 'Tom',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 1,
                            job: 1,
                            entrydate: '2015-03-01',
                            updatetime: '2015-05-01 12:05:00'
                        },
                        {
                            id: 2,
                            name: 'Jerry',
                            image: 'https://web-framework.oss-cn-hangzhou.aliyuncs.com/cat.jpg',
                            gender: 2,
                            job: 2,
                            entrydate: '2018-07-10',
                            updatetime: '2020-08-15 10:30:00'
                        }
                    ],
                    sex:"",
                    job:""
                }
            },
            methods:{
                handle(){
                    console.log(`性别:${this.sex} 工作:${this.job}`);
                }
            }

        }).mount('#app');
    </script>
</body>

</html>

当我们在我们的函数中想要触发获得数据时,直接使用this指针即可

1.6 axios

axios是对ajax的封装版,用于异步请求,在不刷新整个页面的情况下更改区域数据,使用方式如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        axios({
            method: 'GET',
            url: "https://mock.apifox.cn/m1/3083103-0-default/emps/list"
        }).then((result) => {
            console.log(result);
        }).catch((err) => {
            console.log(err);
        });        
    </script>
</body>
</html>

我们通过 <script src="https://unpkg.com/axios/dist/axios.min.js"></script> 远程访问cdn加载

axios的js文件,也可以下载到本地然后在本地加载

上面是get请求的写法,下面是post请求的写法:

        axios({
            method: 'GET',
            url: "https://mock.apifox.cn/m1/3083103-0-default/emps/list",
            data:"id=1"
        }).then((result) => {
            console.log(result.data.data);
        }).catch((err) => {
            console.log(err);
        });   

只需要再传递一个data字段即可,将我们想要传递的数据传递过去

除了上面的写法,还要另一种写法:

axios.get("https://mock.apifox.cn/m1/3083103-0-default/emps/list")
                    .then(res => {
                        console.log(res)
                    })
                    .catch(err => {
                        console.error(err); 
                    })

直接用axios+请求方法+Url和发送的数据即可,数据属于可选参数,可加可不加

1.7 结合axios和vue实现动态查询

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用户列表示例</title>
    <style>
        table {
            width: 80%;
            margin: 20px auto;
            border-collapse: collapse;
        }

        th,
        td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        th {
            background-color: #f2f2f2;
        }

        img {
            width: 40px;
            height: 40px;
            object-fit: cover;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <div id="app">
        <span>sex:</span>
        <select name="usersex" v-model="sex">
            <option value="1">男</option>
            <option value="2">女</option>
        </select>
        <span>job</span>
            <select name="usersex" v-model="job">  
                <option value="1">班主任</option>
                <option value="2">学生</option>
        </select>
        <span>性别{{sex}} 职业:{{job}}</span>
        <input type="button" name="user" value="查询" @click="handle()">

        <table>
            <thead>
                <tr>
                    <th>序号</th>
                    <th>姓名</th>
                    <th>头像</th>
                    <th>性别</th>
                    <th>职位</th>
                    <th>入职时间</th>
                    <th>更新时间</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(user, index) in userList" :key="user.id">
                    <td>{{index+1}}</td>
                    <td>{{user.name}}</td>
                    <td><img :src="user.image" alt="头像" /></td>
                    <td>
                        <span v-if="user.gender==1">
                            男
                        </span>
                        <span v-else-if="user.gender==2">
                            女
                        </span>
                        <span v-else>
                            人妖
                        </span>
                    </td>
                    <td>
                        <span v-show="user.job==1">
                            班主任
                        </span>
                        <span v-show="user.job==2">
                            学生
                        </span>
                        <span v-show="user.job!=2&&user.job!=1">
                            学生
                        </span>
                    </td>
                    <td>{{user.entrydate}}</td>
                    <td>{{user.updatetime}}</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    userList: [],
                    sex:"",
                    job:""
                }
            },
            methods:{
                handle(){
                    axios.get(`https://web-server.itheima.net/emps/list?gender=${this.sex}&job=${this.job}`)
                    .then(res => {
                        this.userList= res.data.data;
                    })
                    .catch(err => {
                        console.error(err); 
                    })
                }
            }

        }).mount('#app');

    </script>
</body>

</html>

此时这个查询功能就基本实现了

1.8 vue生命周期

vue的生命周期有八个阶段:创建,挂载,更新,销毁,我们可以人为设计一些函数在生命周期的前后自动的执

image-20250813212312073

对于上面的案例,如果我们想要页面完成加载后立马查询到所有的信息,就可以使用钩子函数mounted,在

挂载完毕后自动执行

    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    userList: [],
                    sex:"",
                    job:""
                }
            },
            methods:{
                handle(){
                    axios.get(`https://web-server.itheima.net/emps/list?gender=${this.sex}&job=${this.job}`)
                    .then(res => {
                        this.userList= res.data.data;
                    })
                    .catch(err => {
                        console.error(err); 
                    })
                }
            },
            created(){
                console.log("对象创建完成");
            },
            mounted(){
                this.handle();
            }

        }).mount('#app');

    </script>

1.9 案例

  1. https://web-server.itheima.net/province
  2. https://web-server.itheima.net/city?pid=xxx
  3. https://web-server.itheima.net/area?cid=xxx
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <title>省市区三级下拉</title>
    <style>
        body {
            font-family: sans-serif;
            padding: 20px;
        }

        select {
            margin-right: 16px;
            padding: 4px 8px;
        }

        label {
            margin-right: 4px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div id="center">
            省:
            <select v-model="province">
                <option v-for="p in provinces" :key="p.id" :value="p.id">{{ p.name }}</option>
            </select>
            市:
            <select v-model="city">
                <option v-for="c in cities" :key="c.id" :value="c.id">{{ c.name }}</option>
            </select>
            区:
            <select v-model="area">
                <option v-for="a in areas" :key="a.id" :value="a.id">{{ a.name }}</option>
            </select>
        </div>
        <p>当前选择:</p>
    </div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script type="module">
        import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";

        createApp({
            data() {
                return {
                    province: '',
                    city: '',
                    area: '',

                    provinces: [],
                    cities: [],
                    areas: []
                }
            },
            methods:{
                async search(){

                    const presult =await axios("https://web-server.itheima.net/province");
                    this.provinces = presult.data.data;
                    this.province = this.provinces[0].id;
                    const cresult = await axios("https://web-server.itheima.net/city?pid=" + this.province);
                    this.cities = cresult.data.data;
                    this.city = this.cities[0].id;
                    const aresult = await axios("https://web-server.itheima.net/area?cid=" + this.city);
                    this.areas = aresult.data.data;
                    this.area = this.areas[0].id;
                }
            },
            mounted() {
                this.search();
            }
        }).mount('#app');
    </script>
</body>

</html>

因为axios的方法是异步方法,我们需要等他执行完获得返回结果再继续执行,就需要使用await 需要注意的是

await不阻塞线程

posted @ 2025-08-13 23:49  折翼的小鸟先生  阅读(15)  评论(0)    收藏  举报