Vue3基础知识(二)--购物车、v-model、组件化、vuecli

178 阅读5分钟

一. 阶段案例

1.1. 购物车代码

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        table {
            border-collapse: collapse;
            text-align: center;
        }

        thead {
            background-color: #f5f5f5;
        }

        th,
        td {
            border: 1px solid #aaa;
            padding: 6px 16px;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 1.搭建界面内容 -->
        <template v-if="books.length>0">
            <table>
                <thead>
                    <tr>
                        <th>序号</th>
                        <th>书籍名称</th>
                        <th>出版日期</th>
                        <th>价格</th>
                        <th>购买数量</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(item,index) in books" :key="item.id">
                        <th>
                            {{index+1}}
                        </th>
                        <th>{{item.name}}</th>
                        <th>{{item.date}}</th>
                        <th>{{formatPeice(item.price)}}</th>

                        <th>
                            <!-- 1.获取当前的索引index,item,两个都可以 -->
                            <button :disabled="item.count<=0" @click="decrement(index,item)">-</button>
                            {{item.count}}
                            <button @click="increment(index,item)">+</button>
                        </th>
                        <th><button @click="remove(index,item)">移除</button></th>
                    </tr>
                </tbody>

            </table>
            <h2>总价:{{formatPeice(totalPrice)}}</h2>
        </template>
        <template v-else>
            <h1>购物车为空,请添加喜欢的书籍~</h1>
        </template>
       
    </div>

    <script src="../lib/vue.js"></script>
    <script src="./data//data.js"></script>
    <script>
        console.log(books);
        // 1.创建app
        const app = Vue.createApp({//vue全局对象。调用Vue.createApp(),返回一个函数。
            data() {
                return {
                    message: "hello vue",
                    books,

                }
            },
            methods: {
                formatPeice(price) {
                    return "¥" + price;
                },
                increment(index) {
                    console.log("点击+", index);
                    this.books[index].count++;
                },
                decrement(index, item) {
                    console.log("点击-", index);
                    // this.books[index].count--;
                    item.count--;
                },
                remove(index) {
                    this.books.splice(index, 1);
                }
            },
            computed: {

                totalPrice() {
                    // 1.for循环
                    let price = 0;
                    for (const item of this.books) {
                        price += item.price * item.count;
                    }
                    return price;
                    // 2.使用reduce函数
                    // return this.books.reduce((preVlaue, item) => {
                    //     return preVlaue + item.price * item.count;
                    // },0)
                }
            }
        })
        // 2.挂载app
        app.mount("#app");//app调用mount函数,挂载到#app里面。底层通过querySelector找到div元素
    </script>
</body>

</html>

1.2. 列表的选择(点击一项, 变成选中状态)

  • currentIndex记录点击,列表选中。
 <div id="app">
        <ul>
            <!-- <h2 :class="{title:true}"></h2> -->
            <!-- 对active的class进行动态绑定 -->
            <li :class="{active:index==currentIndex}" @click="liClick(index)" v-for="(item,index) in movies"> {{item}}
            </li>
        </ul>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({//vue全局对象。调用Vue.createApp(),返回一个函数。
            data() {
                return {
                    message: "hello vue",
                    movies: ["星际穿越", "海蜇王", "蛊真人", "javascript设计"],
                    currentIndex: -1,
                }
            },
            methods: {
                liClick(index) {
                    console.log("点击~", index);
                    this.currentIndex = index;
                }
            },
        })

二. v-model双向绑定

2.1. v-model基本使用

手动实现双向绑定 v-model 本质上不过是语法糖,它负责监听用户的输入事件来更新数据,创建双向数据绑定;

v-bind绑定value属性的值;

v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中;

<div id="app">
        <!-- 手动实现双向绑定  -->
        <!-- 在input中输入东西时会触发input事件 -->
        <input type="text" :value="message" @input="inputChange">
        <button>登录</button>
        v-model指令
         <input type="text" v-model="message">
        <h2>{{message}}</h2>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({//vue全局对象。调用Vue.createApp(),返回一个函数。
            data() {
                return {
                    message: "hello vue",
                }
            },
            methods: {
                inputChange(event) {
                    console.log(event);
                    console.log(event.target);
                    console.log(event.target.value);
                    this.message=event.target.value;
                }
            },

v-model指令可以在表单 input、textarea以及select元素上创建双向数据绑定。

2.2. v-model其他类型

我们来看一下v-model绑定checkbox:单个勾选框和多个勾选框

单个勾选框:

v-model即为布尔值。

此时input的value属性并不影响v-model的值。

image-20230228185403501.png

多个复选框:

当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。

当选中某一个时,就会将input的value添加到数组中。

image-20230228185336860.png

  • radio v-model绑定radio,用于选择其中一项;

image-20230228185632467.png

  • select

    checkbox一样,select也分单选和多选两种情况。

    单选:只能选中一个值

    v-model绑定的是一个值;

    当我们选中option中的一个时,会将它对应的value赋值到fruit中;

image-20230228190306614.png

多选:可以选中多个值

v-model绑定的是一个数组;

当选中多个值时,就会将选中的option对应的value添加到数组fruit中;

image-20230228190336826.png

2.3. v-model值绑定

在真实开发中,我们的数据可能是来自服务器的,那么我们就可以先将值请求下来,绑定到data返回的对象中,再通过v-bind来进行值的绑定,这个过程就是值绑定

2.4. v-model修饰符

  • lazy

    lazy修饰符是什么作用呢?

    默认情况下,v-model在进行双向绑定时,绑定的是input事件,那么会在每次内容输入后就将最新的值和绑定的属性进行同步;

    如果我们在v-model后跟上lazy修饰符,那么会将绑定的事件切换为 change事件,只有在提交时(比如回车)才会触发;

  • number,绑定成数字类型。

    message总是string类型,即使在我们设置type为number也是string类型;

image-20230228225720203.png

  • trim,去除首尾空格

如果要自动过滤用户输入的守卫空白字符,可以给v-model添加 trim 修饰符

三. 组件化的基础

3.1. 组件化的思想

我们将一个完整的页面分成很多个组件;

每个组件都用于实现页面的一个功能块;

而每一个组件又可以进行细分;

而组件本身又可以在多个地方进行复用;

组件化Vue、React、Angular的核心思想

前面我们的createApp函数传入了一个对象App,这个对象其实本质上就是一个组件,也是我们应用程序的根组件;

组件化提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用;

任何的应用都会被抽象成一颗组件树;

image-20230301091906709.png

3.2. 注册全局组件

app.component("my-cpn", {
    template:"#item"
})

image-20230301105234388.png

3.3. 注册局部组件

const App = {
    // 告诉当前组件会用到那些组件
  components: {
      "my-cpn": {}//局部组件
  }
}

四. Vue脚手架

4.1. Vue的开发模式

  1. html

  2. .vue文件

  3. 单文件的特点在这个组件中我们可以获得非常多的特性:

    1. 代码的高亮;
    2. ES6、CommonJS的模块化能力;
    3. 组件作用域的CSS;
    4. 可以使用预处理器来构建更加丰富的组件,比如TypeScript、Babel、Less、Sass等;
  4. single-file components (单文件组件:SFC)

  5. VSCode对SFC的支持:

    插件一:Vetur,从Vue2开发就一直在使用的VSCode支持Vue的插件;

    插件二:Volar,官方推荐的插件;

4.2. Vue CLI安装和使用

  1. Vue的脚手架就是Vue CLI(2023-3:版本为5.0.8):

2.CLI是Command-Line Interface, 翻译为命令行界面;

我们可以通过CLI选择项目的配置和创建出我们的项目;

Vue CLI已经内置了webpack相关的配置,我们不需要从零来配置;

3.安装Vue CLI

进行全局安装,这样在任何时候都可以通过vue的命令来创建项目;

npm install @vue/cli -g

升级VueCLI:

如果是比较旧的版本,可以通过下面的命令来升级

npm update @vue/cli -g

通过Vue的命令来创建项目

Vue create 项目的名称

查看vue脚手架版本

 vue --version

项目创建命令含义

image-20230301155434424.png

image-20230301155452352.png

image-20230301155556843.png

image-20230301155543588.png

//1.Vue create project

Vue CLI v5.0.8
? Please pick a preset: (Use arrow keys)//preset 预设,下面有两种预设提供选择
> n ([Vue 3] babel, eslint)
  y ([Vue 3] babel, typescript, router, vuex)
  Default ([Vue 3] babel, eslint)//默认vue3预设
  Default ([Vue 2] babel, eslint)//默认vue2预设
  Manually select features//手动选择新特性
  
  
  //2.手动选择新特性后进入一下界面,选择配置项目那些特性
? Please pick a preset: Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)   
>(*) Babel  //Babel对es的代码做一个转化
 ( ) TypeScript//ts
 ( ) Progressive Web App (PWA) Support
 ( ) Router//路由
 ( ) Vuex//vuex
 ( ) CSS Pre-processors //css预处理
 ( ) Linter / Formatter//对代码做格式化
 ( ) Unit Testing //单元测试
 ( ) E2E Testing//端对端测试

//3.版本选择
? Choose a version of Vue.js that you want to start the project with 
(Use arrow keys)
> 3.x
  2.x
  
  
 //4.如果有bable相关的配置,你想要放到单独的配置文件还是package.json,建议放到独立的文件,方便查找。
  ? Where do you prefer placing config for Babel, ESLint, etc.? (Use   
arrow keys)
> In dedicated config files
  In package.json

//5.是否将这次的配置生成预设
Save this as a preset for future projects? (y/N)

Vue CLI的运行原理

image-20230301193354208.png

4.3. Vue项目目录结构

image-20230301155617130.png

vue.config.js文件:对默认的配置不满意,可以通过这个配置合并配置的文件,相同配置会覆盖默认的配置.

image-20230301155634785.png

js.config.json文件是给VSCode的使用的,vscode读取该文件有更好的代码提示。

根据配置文件使用更友好的提示.

4.4. browserslistrc文件作用(了解)

它的作用是指定项目的目标浏览器范围。这个值会被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。