Skip to content

🛫 快速上手 VUE3



一、快速入门


1.1 创建一个 vue 应用程序


  • Vue 官网:https://cn.vuejs.org/

  • 渐进式 JavaScript 框架

    • 引入渐进式:可以按需引入 Vue.js 的部分功能 , 而不必全量引入整个框架
    • 学习渐进式:学多少用多少,不需要大篇幅学习才能使用

  • 先学习通过 CDN 导入 VUE
    • 全局构建版本:https://unpkg.com/vue@3/dist/vue.global.js
    • ES 模块构建版本:https://unpkg.com/vue@3/dist/vue.esm-browser.js

  • 1). 全局构建版本:
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>

    <!-- 通过 CDN 导入 VUE -->
    <script src="./vue.global.js"></script>

</head>
<body>
    <!-- 指定一个 id 为 app 的 div 元素 -->
    <div id="app">

        <!-- 
        {{ }} 插值表达式, 可以将 Vue 实例中定义的数据在视图中进行渲染
        如: Vue 实例中定义一个 msg 变量, 值为 "Hello world", 
        在模板中若使用插值表达式 {{ msg }} 则会被渲染成 "Hello world" 

        响应式数据是指当数据发生变化时, 模板中依赖于该数据的部分会自动更新
        -->

        <h2>msg : {{ msg }}</h2>

        <h2>title : {{ web.title }}</h2>
        <h2>url : {{ web.url }}</h2>
        
    </div>

    <script>
        // 解构赋值语法
        const {createApp, reactive} = Vue;
        
        //创建一个 Vue 应用程序
        Vue.createApp({
            //Composition API(组合式 API) 的 setup 选项 用于设置响应式数据和方法等
            setup(){
                //  Composition API 的 reactive() 函数 用于创建响应式数据
                //  Vue.reactive 创建一个响应式数据对象 web, 其中包含 title 和 url 属性
                const web = reactive({  
                    title : "irai",
                    url : "iraionly.cn"
                })

                return {
                    msg : "success",
                    web
                }
            }
        }).mount("#app")    //将 Vue 应用程序挂载(mount) 到 app 元素上

    </script>
    
</body>
</html>

  • 📌 注意:​需要安装 VsCode 扩展:Live Server

  • 2). 模块式开发:

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
</head>
<body>
    <div id="app">
        <h2>msg : {{ msg }}</h2>

        <h2>title : {{ web.title }}</h2>
        <h2>url : {{ web.url }}</h2>
    </div>


    <script type="module">
        // type="module" : 声明为模块式开发

        // 模块式开发导入
        import {createApp, reactive} from './vue.esm-browser.js'

        createApp({
            setup(){

                const web = reactive({  
                    title : "irai",
                    url : "iraionly.cn"
                })

                return {
                    msg : 'success',
                    web
                }
            }
        }).mount("#app")

    </script>
    
</body>
</html>

1.2 ref & reactive


  • ref 用于存储单个基本类型的数据, 如 : 数字、字符串等,

    使用 ref 创建的响应式对象, 需要通过 .value 属性来访问和修改其值


  • reactive 用于存储复杂数据类型, 如 : 对象或数组等,

    使用 reactive 创建的响应式对象, 可以直接通过属性名来访问和修改值


  • 示例代码:
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
</head>
<body>
    <div id="app">
        <h2>num : {{ num }}</h2>

        <h2>title : {{ web.title }}</h2>
        <h2>url : {{ web.url }}</h2>
        <hr>
        <button @click="changeUrl">修改 url </button>
        <button @click="changeNum">num ++ </button>
    </div>


    <script type="module">
        // type="module" : 声明为模块式开发

        // 模块式开发导入
        import {createApp, reactive, ref} from './vue.esm-browser.js'

        createApp({
            setup(){

                // 数据
                const num = ref(10);

                const web = reactive({  
                    title : "irai",
                    url : "iraionly.cn"
                })

                // 方法 
                function changeUrl(){
                    web.url = "http:iraionly.cn"
                }

                function changeNum(){
                    num.value ++
                }

                return {
                    msg : 'success',
                    web,
                    num,
                    changeUrl,
                    changeNum
                }
            }
        }).mount("#app")

    </script>
    
</body>
</html>

1.3 v-on & @


  • 作用:为 html 标签绑定事件

  • 语法:

    • v-on:事件名="方法名"

    • 简写形式:@事件名="..."


  • 注:前面的 demo 已经使用过 @click 下面示例代码演示一些 按键修饰符

  • 示例代码:

html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>demo</title>
    </head>
    <body>
        <div id="app">
            <h3>{{ msg }}</h3>
            <h3>{{ web.url }}</h3>
            <h3>{{ web.user }}</h3>
            <h3>{{ sub(100, 20) }}</h3>

            <!-- v-on:click 表示在 button 元素上监听 click 事件 -->
            <button v-on:click="edit">修改</button> <br />

            <!-- @click 简写形式 -->
            <button @click="add(20, 30)">加法</button> <br />

            <!-- 
                enter space tab 按键修饰符
                keyup 是在用户松开按键时才触发
                keydown 是在用户按下按键时立即触发
            -->
            回车 <input type="text" @keyup.enter="add(40, 60)" /> <br />
            空格 <input type="text" @keyup.space="add(20, 30)" /> <br />
            Tab <input type="text" @keydown.tab="add(10, 20)" /> <br />
            w <input type="text" @keyup.w="add(5, 10)" /> <br />

            <!-- 组合快捷键 -->
            Ctrl + Enter <input type="text" @keyup.ctrl.enter="add(40, 60)" />
            <br />
            Ctrl + A <input type="text" @keyup.ctrl.a="add(20, 30)" />
        </div>

        <script type="module">
            // type="module" : 声明为模块式开发

            // 模块式开发导入
            import { createApp, reactive, ref } from "./vue.esm-browser.js";

            createApp({
                setup() {
                    const web = reactive({
                        title: "irai",
                        url: "iraionly.cn",
                        user: 0,
                    });

                    const edit = () => {
                        web.url = "http:iraionly.cn";
                    };

                    const add = (a, b) => {
                        web.user += a + b;
                    };

                    const sub = (a, b) => {
                        return a - b;
                    };

                    return {
                        msg: "success", //普通变量, 非响应式数据, 在模板中普通变量不会自动更新
                        web, //响应式数据
                        edit, //方法
                        add,
                        sub,
                    };
                },
            }).mount("#app");
        </script>
    </body>
</html>

1.4 v-show


  • 语法:v-show="表达式",表达式值为 true,显示;false,隐藏
  • 原理:基于 CSS 样式 display 来控制显示与隐藏
  • 场景:频繁切换显示隐藏的场景

  • 示例代码:
html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>demo</title>
    </head>
    <body>
        <div id="app">
            <h3>{{ web.show }}</h3>
            <h2 v-show="web.show">irai iraionly.com</h2>

            <button @click="toggle">点击切换显示状态</button>
        </div>

        <script type="module">
            // type="module" : 声明为模块式开发

            // 模块式开发导入
            import { createApp, reactive, ref } from "./vue.esm-browser.js";

            createApp({
                setup() {
                    const web = reactive({
                        show: true,
                    });

                    const toggle = () => {
                        web.show = !web.show;
                    };

                    return {
                        web,
                        toggle,
                    };
                },
            }).mount("#app");
        </script>
    </body>
</html>

1.5 v-if


  • 语法:v-if="表达式" ,表达式值为 true,显示;false,隐藏
  • 原理:基于条件判断,来控制创建或移除元素节点(条件渲染)
  • 场景:要么显示,要么不显示,不频繁切换的场景
  • 其它:可以配合 v-else-if / v-else 进行链式调用条件判断
  • 注意:v-else-if 必须出现在 v-if 之后,可以出现多个; v-else 必须出现在 v-if/v-else-if 之后 。

  • 示例代码:
html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>demo</title>
    </head>
    <body>
        <div id="app">
            <h3>{{ web.show }}</h3>
            <h3>user : {{ web.user }}</h3>
            <p v-show="web.show">irai</p>
            <p v-if="web.show">iraionly.cn</p>

            <button @click="toggle">点击切换显示状态</button>
            <button @click="addNum">用户量 + 1000 </button>

            <p v-if="web.user < 1000">新网站</p>
            <p v-else-if="web.user >= 1000 && web.user < 10000">优秀网站</p>
            <p v-else-if="web.user >= 10000 && web.user < 50000">资深网站</p>
            <p v-else>超级网站</p>
        </div>

        <script type="module">
            // type="module" : 声明为模块式开发

            // 模块式开发导入
            import { createApp, reactive, ref } from "./vue.esm-browser.js";

            createApp({
                setup() {
                    const web = reactive({
                        show: true,
                        user: 500
                    })

                    const toggle = () => {
                        web.show = !web.show
                    }

                    const addNum = () => {
                        web.user += 1000
                    }

                    return {
                        web,
                        toggle,
                        addNum
                    }
                }
            }).mount("#app");
        </script>
    </body>
</html>

1.6 v-bind & :


  • 作用:动态为 HTML 标签绑定属性值,如设置 hrefsrcstyle 样式等。
  • 语法:
    • v-bind:属性名="属性值"
    • 简写::属性名="属性值"

  • 示例代码:
html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>demo</title>
        <style>
            .textColor { 
                color: blue;
                font-weight: bold;
                font-style: italic;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <!-- :value -->
            <h3>value="iraionly.cn"</h3>
            <input type="text" value="iraionly.cn" />

            <h3>v-bind:value="web.url"</h3>
            <input type="text" v-bind:value="web.url" />

            <h3>简写 :value="web.url"</h3>
            <input type="text" :value="web.url" />

            <!-- :src -->
            <h3>src="window.png"</h3>
            <img src="window.png" style="width: 300px;"/>

            <h3>:src="web.img"</h3>
            <img :src="web.img" style="width: 300px;"/>

            <!-- :class -->
            <h3>class="textColor"</h3>
            <b class="textColor">irai</b>

            <h3>:class="{textColor:web.fontStatus}"</h3>
            <b :class="{textColor:web.fontStatus}">iraionly.cn</b>
            <br><br>    
            <button @click = "changeFontStatus">changeFontStatus</button>
        </div>

        <script type="module">
            // type="module" : 声明为模块式开发

            // 模块式开发导入
            import { createApp, reactive, ref } from "./vue.esm-browser.js";

            createApp({
                setup() {
                    const web = reactive({
                        url: "http:iraionly.cn",
                        img: "window.png",
                        fontStatus: false,
                    });

                    const changeFontStatus = () => {
                        web.fontStatus = !web.fontStatus
                    }

                    return {
                        web,
                        changeFontStatus
                    };
                },
            }).mount("#app");
        </script>
    </body>
</html>

1.7 v-for


  • 作用:列表渲染,遍历容器的元素或者对象的属性
  • 语法:
html
<tr v-for="(item,index) in items" :key="item.id">{{item}}</tr>
  • 参数说明:

  • items 为遍历的数组

  • item 为遍历出来的元素

  • index 为索引/下标,从 0 开始 ;可以省略,省略 index 语法: v-for = "item in items"

  • key :

    • 作用:给元素添加的唯一标识,便于 vue 进行列表项的正确排序复用,提升渲染性能
    • 推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key (会变化,不对应)

  • 示例代码:

  • 示例代码:

html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>demo</title>
    </head>
    <body>
        <div id="app">
            <!-- 遍历数组 value index-->
            <ul>
                <li v-for="(value, index) in data.number">
                    index=> {{ index }} : value=> {{ value }}
                </li>
            </ul>

            <!-- 遍历对象 value -->
            <ul>
                <li v-for="value in data.user">value=> {{ value }}</li>
            </ul>
            <!-- 遍历对象 value key -->
            <ul>
                <li v-for="(value, key) in data.user">
                    key=> {{ key }} : value=> {{ value }}
                </li>
            </ul>
            <!-- 遍历对象 value key index -->
            <ul>
                <li v-for="(value, key, index) in data.user">
                    index=> {{ index }} : key=> {{ key }} : value=> {{ value }}
                </li>
            </ul>

            <ul>
                <!-- <template> 标签可以用来包装多个元素或者多行代码, 不会在页面中渲染  -->
                <template v-for="(value, key, index) in data.user">
                    <li v-if="index == 1">
                        index=> {{ index }} : key=> {{ key }} : value=> {{ value }}
                    </li>
                </template>
            </ul>

            <ul>
                <!-- :key="value.id" 为 每个 li 元素设置一个唯一的 key 值 -->
                <li
                    v-for="(value, index) in data.teacher"
                    :title="value.name"
                    :key="value.id"
                >
                    index=> {{ index }} : value.id=>{{ value.id }}
                    value.name=>{{ value.name }} value.web=>{{ value.web }}
                </li>
            </ul>
        </div>

        <script type="module">
            // type="module" : 声明为模块式开发

            // 模块式开发导入
            import { createApp, reactive, ref } from "./vue.esm-browser.js";

            createApp({
                setup() {
                    const data = reactive({
                        number: ["十", "十一", "十二"], //数组
                        user: {
                            //对象
                            name: "Luna",
                            gender: "女",
                        },
                        teacher: [
                            //包含两个对象的数组
                            { id: 100, name: "irai", web: "iraionly.cn" },
                            {
                                id: 101,
                                name: "艾瑞",
                                web: "http:iraionly.cn",
                            },
                        ],
                    });

                    return {
                        data,
                    };
                },
            }).mount("#app");
        </script>
    </body>
</html>

1.8 v-model


  • 作用:在表单元素上使用,双向数据绑定。可以方便的 获取设置 表单项数据

  • 语法:v-model="变量名"

  • 这里的双向数据绑定,是指 Vue 中的数据变化,会影响视图中的数据展示 。

    视图中的输入的数据变化,也会影响 Vue 的数据模型 。

    • 单向数据绑定:<input type="text" :value="data.text">
    • 双向数据绑定:<input type="text" v-model="data.text">
  • 注意:v-model 中绑定的变量,必须在 data 中定义。


  • 示例代码:
html

二、案例篇


2.1 介绍


  • 1). 图片轮播
    • 插值表达式
    • 模板字符串
    • 绑定点击事件
    • 遍历循环 v-for


  • 2). 记事本
    • 添加记录
    • 删除记录
    • 清空记录

  • 3). 购物车
    • 全选/反选
    • 商品数量增减
    • 计算总价
    • 删除商品

  • 4). 购物车优化
    • 引入计算属性
    • 购物车代码优化

  • 5). 商品搜索
    • 使用 Axios 获取后端数据
    • 根据搜索内容展现搜索结果

2.2 图片轮播


2.3 记事本


2.4 购物车


2.5 购物车优化


2.6 商品搜索



三、组件篇


四、关于 Pinia