Vue学习记录

文章目录

1.简介

作为国内使用较多的前端开发框架,vue是渐进式框架,能够是我们减去繁杂的代码工作,简易了前端开发。

2.Vue的使用(Scirpt版本)

  • 1.下载vue.js,地址如下:

https://v2.cn.vuejs.org/v2/guide/installation.html#%E7%9B%B4%E6%8E%A5%E7%94%A8-lt-script-gt-%E5%BC%95%E5%85%A5

  • 2.引入到html文件中
<script src="../js/vue.js" type="text/javascript"></script>

3.HelloWord小案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js" type="text/javascript"></script>
</head>
<body>
    <div class="root">
        <!--插值表达式-->
        Hello,{{name}} 
    </div>
    <script>
      Vue.config.productionTip = false;
      new Vue({
          el: ".root", //el代表的是当前这个Vue对象服务的元素,el的值可以通常用元素选择器,或者也可用bom获取,比如el: document.getElementById("#root")
          data: { //data用于存储数据,用于el所指定的对象使用
              name: "尚硅谷"
          }
      });
    </script>
</body>
</html>

4.Vue注意点

  • 一个标签元素只能绑定一个Vue对象
  • 一个Vue对象只能绑定一个标签
  • 插值表达式需要些Js语法,同时不能使用Vue对象中未定义的数据变量
  • Vue对象中,可以定义两个相同名的变量,但是后者会把前者覆盖。

5.模板语法

5.1插值语法

语法:vue{{js表达式}}

用于解析标签体中的内容,括号内是JS表达式,可以直接绑定data中的所有内容。

5.2指令语法

5.2.1v-bind

单向数据绑定,用于绑定标签属性,同时可以简写如:v-bind:href="xxx"可以简写为:href=“xxx”.

5.2.2v-model

双向绑定,用于绑定标签中的value属性,因为绑定的是value属性,因此v-model支持表单中的标签,如input和selete。用于其他标签,如h1等,都会报错。语法如下:

<input v-model:value="data"/>

同时也有简写语法,个人表示,语法糖,yyds

<input v-model="data"/>
5.2.2.1v-mode的修饰符
  • .lazy:失去焦点在收集数据
  • .number:输入字符串转为有效的数字
  • .trim:输入首位空格过滤

5.2.3v-on

事件绑定,绑定Vm对象中methods中的方法,由于可以直接用方法名调用,因此在vm对象中做了声明,所以在methods中定义的函数,可以直接用函数名调用。但是可以使用method或者method(arg1,arg2…)。只是用前者未传递参数,后者传递了参数。

  • 简写:v-on:click -> @click
  • 传递事件event对象:@click=“add($event)”
5.2.3.1事件修饰符
  • 1.prevent:阻止默认事件
  • 2.stop:阻止事件冒泡
  • 3.once:事件只触发一次
  • 4.capture:使用时间的捕获模式
  • 5.self:只有event.target是当前操作的元素是才触发事件
  • 6.passive:时间的默认行为,无需等待事件回调执行完毕。

注意:

  • 可以同时使事件使用多次修饰符,@事件.修饰符1.修饰符2…,那个修饰符在前面,那个先被使用。
5.2.3.2键盘事件
  • @keyup

键盘松开

  • @keydown

键盘按下

注意:

  • Vue中常用的按键别名(使用方法为:@keyup.别名)
  • 回车 => enter
  • 删除 => delete(捕获删除和退格键)
  • 退出 => esc
  • 空格 => space
  • 换行 => tab
  • 上 =

5.2.4v-show

用来隐藏当前样式,但是不会破坏BOM结构,也displace:none相同

5.2.5v-if,v-else-if,v-else

  • 写法:
v-if="表达式"
v-else-if="表达式"
v-else="表达式"

不符号条件的DOM元素将直接被移除。同时v-if和v-else-if,v-else一起使用,但要求结构不能被打断。使用v-if的时,元素可能无法获得,而使用v-show一定能获得

5.2.5.1template

当我们想要用一个条件判断几个元素,通常的做法就是用div包裹。但是使用div破坏了BOM结构。因此template标签的出现解决了这个问题。template可以包裹元素,但是不会改变bom结构,就是不会增加template标签。但是template只能配合v-if使用

5.2.6v-for

用来遍历数据,可以遍历数组,对象,字符串以及次数。同时可以获取索引值
语法:

v-for="item in 数组/对象/字符串/次数"
v-for="(item,index) in 数组/对象/字符串/次数"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
    <!--遍历数组 i in forArr是只取出每一项的数据,(i, index) in forArr 是遍历每一项和索引值(从0开始)-->
    <ul>
        <li v-for="i in forArr">
            {{i.name}}--{{i.age}}
        </li>
    </ul>
    <!--遍历对象,value在前,key在后-->
    <ul>
        <li v-for="(value, key) in forObj">
            {{value}} -- {{key}}
        </li>
    </ul>
    <!--遍历字符串,同样也可以通过(i,index) in forStr 获取索引值-->
    <ul>
        <li v-for="i in forStr">{{i}}</li>
    </ul>
    <!--遍历次数-->
    <ul>
        <li v-for="item in forNum">{{item}}</li>
    </ul>
</div>
</body>
<script>
    new Vue({
        el: ".root",
        data() {
            return {
                forArr: [
                    {name: "mick", age:12},
                    {name: "anna", age:13}
                ],
                forObj: {
                    name: "mick",
                    age: "18"
                },
                forStr: "abadfaf",
                forNum: 3
            }
        }
    })
</script>
</html>
5.2.6.1key的原理和介绍
  • key的作用

key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较。比较规则如下:
在这里插入图片描述

  • key选择index带来的问题
    在这里插入图片描述

5.2.7v-text

将标签体中的内容替换为v-text绑定的属性,不能解析标签。

5.2.8v-html

将标签体中的内容替换为v-html绑定的属性,能解析标签。但是存在安全性问题,会产生XSS攻击

5.2.9v-cloak

  • 本质上是一个特殊的语法,没有属性值,Vue接管容器后,会删除这个属性
  • 可以配合css可以解决网速慢页面展示出{{xxx}}的问题

5.2.10v-once

  • 所在节点在初次动态渲染后,就视为静态属性
  • 以后数据的改变不会引起v-once所有结构的改变,可以用于优化性能

5.2.11v-pre

标记v-pre的元素标签不会受vue的编辑接管,即写出的是什么,表示的就是什么

5.2.12自定义标签

5.2.12.1自定义语法
5.2.12.1.1局部指令
new Vue({
	directives:{指令名:配置对象}
})
或者
new Vue({
	directives{指令名:回调函数}
})
5.2.12.1.2全局指令
Vue.directive(指令名,配置对象)
或者
Vue.directive(指令名,回调函数)
5.2.12.2常用的三种回调
  • bind:指令与元素成功绑定时调用
  • inserted:元素被插入页面时调用
  • update:指令所在模板结构被重新解析时调用
5.2.12.3注意:
  • 指令定义时不加v-,但是用要加v-
  • 指令名如果是多个单词,要使用kebab-case,不要用camelCase命名

6.MVVM模型

  • M:模型:data中的数据
  • V:试图:DOM代码
  • VM:视图模型,也就是Vue实例

通过定义到data中的所有属性,最后都出现在vm上了,vm上的所有属性,都可以通过插值语法和模板语法使用。

7.数据代理

7.1Object.defineProperty方法介绍

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="box"></div>
<script>
    let person = {
        name: "mick",
        sex: "man"
    }
    let num = 20;
    Object.defineProperties(person, 'age', {
        //给age赋值的值
        value: 19,
        //可枚举,默认值为false
        enumerable: true,
        //可修改,默认为false
        writable: true,
        //可删除,默认为false
        configurable: true,
        //当读取person的age时,get方法会被调用
        get() {
            return num;
        },
        //当修改person的age时,set方法会被调用
        set(value) {
            num = value;
        }
    })
    new Vue({
        el: ".box",
        data() {
            return {}
        }
    });
</script>
</body>
</html>

7.2定义

通过一个对象可以对另一个对象进行读/写

7.3Vue中的应用

Vue将我们定义的data对象存放在了vm的_data属性中,同时通过defineProperty方法来实现data对象与vm对象的数据绑定。而之所以将_data的属性有放到外面一份,是为了操作方便。不至于每次开发人员都要用{{_data.属性}}来获取属性。

在这里插入图片描述

8.el和data的两种写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div class="div">
      你好,{{name}}
    </div>
    <script>
      const v = new Vue({
        //el的第一种写法,在vue对象中直接定义
        el: ".div",
        // data的第一种写法,对象式,以后使用组件会报错。
        data: {
          name: "世界"
        },
        //data的第二种写法,函数式
        data: function() {
          return {
            name: "世界"
          }
        },
        //当然也可以用es6的语法糖做一个简化
        data() {
          return {
            name: "世界"
          }
        }
      });
      //el的第二种写法,使用$mount挂载,不一样的是,这种方法比较方法,可以实现懒加载
      v.$mount(".div");
    </script>
</body>
</html>

9.计算属性

9.1定义

定义在computed中,是通过现有属性计算获得的属性(data中的数据),底层调用了Object.defineproperty方法提供的get和set方法

9.2.get方法的执行时机

  • 在第一读取计算属性的时候,会调用get方法
  • 当计算属性依赖的属性发生变化时,会调用get方法

9.3注意

  • 计算属性会出现在vm上,直接读取即可
  • 如果计算属性要被修改,那必须定义set函数,否则将会报错

9.4简写

computed: {
 //属性名
    fullName() {
        //get方法的函数体
        return this.firstName + "-" + this.secondName;
    }
}

10.监听属性

定义在watch中的属性,这些属性会监听属性的变化,然后调用回调函数(handle),实现数据的监听

10.1语法

watch: {
//属性名,默认是“属性名”,但是如果只是监听属性,而不是data中对象的属性,则不需要添加引号
flag: {
    //是否立即执行,即加载页面的时候就执行,false代表只有flag发生变化的时候调用
    immediate: true,
    //默认watch是不能够监听data中对象的属性(增加效率),使用deep可以监听
    deep: true,
    //属性发生变化时,执行的函数。
    handler(newValue, oldValue) {
        console.log("newValue", newValue, "oldValue", oldValue);
    }
}
}

当然Vue也给我们提供了另一种方式来定义watch

vm.$watch(”监听属性", 回调函数);

10.2简写

如果不用定义watch的及时性和深度监听,我们可以将上述代码简写如下

watch: {
 flag(newValue, oldValue) {
        console.log(newValue);
        console.log(oldValue);
    }
}

11.computed和watch的区别

  • computed能完成的,watch都能完成,watch能完成的,computed不一定能完成,比如异步任务
  • 所有被Vue管理的函数都写成普通函数,不被Vue管理的函数,如:ajax的回调函数,Promise的回调函数,定时器的回调函数,都写成箭头函数

12.绑定样式

12.1绑定class样式

可以利用:class属性绑定data中的变量,变量的形式可以为字符串,数组,对象。:class绑定的class样式,vue会将此数据与原来class样式绑定。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="../js/vue.js"></script>
    <style type="text/css">
        .a {
            background-color: yellowgreen;
        }

        .b {
            border: 1px solid black;
        }

        .c {
            color: red;
        }

        .d {
            font-size: 10px;
        }
    </style>
</head>
<body>
<div class="root">
    <!--样式绑定为属性,用来绑定一个class样式,且样式未知-->
    <div class="d" :class="classAttr">测试</div>
    <button @click="click1">点击1</button>
    <br/>
    <br/>
    <!--样式绑定为数组,用来绑定多个class样式,且样式未知-->
    <div class="d" :class="classArr">测试</div>
    <button @click="click2">点击2</button>
    <br/>
    <br/>
    <!--样式绑定为对象,用来绑定范围确定的样式-->
    <div class="d" :class="classObj">测试</div>
    <button @click="click3">点击3</button>
</div>
</body>
<script>
    new Vue({
        el: ".root",
        data() {
            return {
                classAttr: "",
                classArr: [],
                classObj: {
                    "a": false,
                    "b": false
                }
            }
        },
        methods: {
            click1() {
                this.classAttr = "a"
            },
            click2() {
                this.classArr = ["a", "b", "c"];
            },
            click3() {
                this.classObj.a = true;
            }
        }
    })
</script>
</html>

12.2绑定style样式

Vue提供了两种解决行内样式的方式,样式对象和数组,通常使用样式对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
    <!--样式对象,注意间隔线要用下划线表示-->
    <span :style="styleObj">测试1</span>
    <!--数组形式,数组捏包含的是样式对象,不常见-->
    <span :style="styleArr">测试2</span>
</div>
</body>
<script>
    new Vue({
        el: ".root",
        data() {
            return {
                styleObj: {
                    fontSize: "50px",
                    color: "red"
                },
                styleArr: [
                    {
                        fontSize: "50px"
                    },
                    {
                        color: "red"
                    }
                ]
            }
        }
    })
</script>
</html>

13.数据监测原理

13.1Vue.set()和vm.$set()

当我们想要在现有数据(也就是data中的数据,不能是data)中新增一个属性,可以使用set方法,具体的使用方式有两种,如下:

语法:

Vue.set(data中的数据,属性名,属性值)
vm.$set(data中的数据,属性名,属性值)

13.2如何检测数组中的数据

在Vue中,vm对push、pop()、shift()、unshift()、splice()、sort()、reverse()进行了封装,只要使用了这7个方法,Vue都会更新数组,当然也可以用ser方法来改变数组元素,但是set方法不能给vm或者vm的跟对象添加属性。。

14.收集表单数据:

  • 1.如果表单类型为非text类型,如radio,checkbox,select那么需用自己定义value
  • 2.checkbox为多选时,绑定的为数组,单个checkbox,绑定的为boolean,并且不需要定义value
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
    <form action="www.baidu.com" @submit.prevent="save">
        <label>
            <span>账号:</span>
            <input type="text" v-model="info.account">
        </label>
        <br/>
        <label>
            <span>密码:</span>
            <input type="password" v-model="info.password">
        </label>
        <br/>
        <span>性别:</span>
        <label>
            <span></span>
            <input type="radio" v-model="info.sex" value="man">
        </label>
        <label>
            <span></span>
            <input type="radio" v-model="info.sex" value="woman">
        </label>
        <br/>
        <span>爱好:</span>
        <label>
            <span>抽烟</span>
            <input type="checkbox" v-model="info.hobby" value="smoke">
        </label>
        <label>
            <span>喝酒</span>
            <input type="checkbox" v-model="info.hobby" value="drink">
        </label>
        <label>
            <span>烫头</span>
            <input type="checkbox" v-model="info.hobby" value="head">
        </label>
        <br/>
        <label>
            <span>所属校区:</span>
            <select v-model="info.school">
                <option>请选择校区</option>
                <option value="bj">北京</option>
                <option value="sh">上海</option>
                <option value="nj">南京</option>
            </select>
        </label>
        <br/>
        <label>
            <span>其他信息:</span>
            <textarea v-model="info.other"></textarea>
        </label>
        <br/>
        <label>
            <input type="checkbox" v-model="info.accept">
            <span>
            阅读并接受
            <a href="www.baidu.com">《用户协议》</a>
        </span>
        </label>
        <br/>
        <button type="submit">提交</button>
    </form>
</div>
</body>
<script>
    new Vue({
        el: ".root",
        data() {
            return {
                info: {
                    account: "",
                    password: "",
                    sex: "",
                    hobby: [],
                    school: "",
                    other: "",
                    accept: false
                }
            }
        },
        methods: {
            save() {
                console.log("信息", this.info)
            }
        }
    })
</script>
</html>

15.过滤器(Vue3.0已移除)

15.1语法

<h1>{{time | 过滤属性}}</h1>

new Vue({
	filters: {
		过滤属性() {
		}
	}
}

16.生命周期

16.1定义

一个组件从创建->更新->销毁的阶段,而在此期间,Vue给我们提供了一些函数,这些函数会在生命周期特定的时间段被VUE调用。而这些函数被称为钩子函数。

16.2介绍

在这里插入图片描述

17.组件

17.1定义

用来实现局部功能效果的代码集合。

17.2多文件组件的使用

组件的使用过程分为三个步骤:创建,注册,使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
    <!--第三步:组件使用-->
    <school></school>
    <br/>
    <student></student>
</div>
</body>
<script>
    //第一步:组件创建
    const school = Vue.extend({
        template: `
            <div>
                <h2>学校名字:{{schoolName}}</h2>
                <h2>学校地址:{{schoolAddr}}</h2>
            </div>`,
        data() {
            return {
                schoolName: "尚硅谷",
                schoolAddr: "北京"
            }
        }
    });
    const student = Vue.extend({
        template: `
            <div>
                <h2>学生名字:{{studentName}}</h2>
                <h2>学生地址:{{studentAddr}}</h2>
            </div>`,
        data() {
            return {
                studentName: "Mick",
                studentAddr: "上海"
            }
        }
    });
    new Vue({
        el: ".root",
        data() {
            return {}
        },
        //第二步:组件注册,这种方式即变量名即为组件名,还有一种写法是:student:student
        components: {
            student,
            school
        }
    })
</script>
</html>

17.2.1全局注册

//全局注册
Vue.component({
    template: `
        <div>
            <h2>学生名字:{{studentName}}</h2>
            <h2>学生地址:{{studentAddr}}</h2>
        </div>`,
    data() {
        return {
            studentName: "Mick",
            studentAddr: "上海"
        }
    }
})

注意

  • 在组件的使用过程中,data不可以使用变量的形式。因为如果使用变量的形式,多个组件实际是直接操作的是同一个变量,一个组件修改了,就会影响另一个组件。
  • 可以在组件中定义一个属性name,这个属性对应的值,可以影响开发者工具中显示的标签。

17.2.3简写

const student = {
   template: `
        <div>
            <h2>学生名字:{{studentName}}</h2>
            <h2>学生地址:{{studentAddr}}</h2>
        </div>`,
    data() {
        return {
            studentName: "Mick",
            studentAddr: "上海"
        }
    }
};

17.2.4VueCompoent

  • 组件本质是一个VueComponent,当执行Vue.extend后,由Vue创建的
  • 每次调用一次,返回的都是全新的VueComponent
  • 组件中的this是VueComponent
  • VueComponent简称vm

17.2.5内置关系

VueComponent.prototype.__proto__ === Vue.prototype

在这里插入图片描述

17.3单文件组件的使用

Vue将单文件组件分为了三个部分,分别为template,script,style

<template>
    DOM结构
</template>

<script>
	以默认方式暴露当前文件,可使用import引入
    export default {
        vue中的方法,比如data,methods,component,watch,computeds,钩子函数等
    }
</script>

<style scoped>
        样式
</style>

注意

  • 用import引入组件
import 组件名 from 相对地址
  • 组件名通常首字母大写

18.Vue脚手架

18.1创建脚手架

  • 1.首先在命令中输入vue命令,查看vue是否安装,如果没有安装,安装vue
  • 2.创建vue
vue create 项目名

18.2脚手架结构

.文件目录
├── node_modules 
├── public
│   ├── favicon.ico: 页签图标
│   └── index.html: 主页面
├── src
│   ├── assets: 存放静态资源
│   │   └── logo.png
│   │── component: 存放组件
│   │   └── HelloWorld.vue
│   │── App.vue: 汇总所有组件
│   └── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件 
├── README.md: 应用描述文件
├── package-lock.json: 应用包版本控制文件
└── vue.config.js:定制化脚手架的一些功能,比如入口文件的路径等

18.2.1入口文件介绍(main.js)

//引入APP
import Vue from 'vue'
import App from './App.vue'

//关闭开发提示
Vue.config.productionTip = false

//创建实例
new Vue({
  //由于Vue在脚手架中引入的并不是完整版的Vue.js,而是vue.runtime.js,虽然较少了vue.js的体积大小,
  // 但是在这个版本中没有模板解析器,所以Vue官方提供了render函数,由render函数接收到createElement函数去指定具体内容。
  render: h => h(App),
}).$mount('#app') //将vue实例挂载到app元素上

19ref属性

用来给元素或子组件注册引用信息,也就是id的替代者,可以获取组件实例对象(vc)
使用方式

this.$refs.

20props属性

20.1定义:

props主要用于组件的传值,他的工作就是为了接收外面传过来的数据,与data、methods、computed是一个级别的配置项。

20.2语法:

  • 定义props:
props: {
	属性名:{
		type: 属性类型,
		required: 是否必须,
		default: 默认值	
	}
}

例子:

props: {
	name: {
       type: String,
       required: true
   },
   age: {
       type: Number,
       required: true
   },
   sex: {
       type: String,
       required: true
   }
}
  • 定义组件
<person-name sex="男" :age="18" name="Mick"/>

20.3定义简写

props: ['属性名'...]

注意:

  • props中的属性是不能修改的,如果想要修改,可以在data中创建一个中间变量,将props中的变量赋值给中间变量,通过修改中间变量修改数据,
<template>
    <div>
        <h1>{{msg}}</h1>
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{tempAge}}</h2>
        <h2>性别:{{sex}}</h2>
        <button @click="changeAge">按钮</button>
    </div>
</template>

<script>
export default {
    name: "PersonName",
    data() {
        return {
            msg: "欢迎学习尚硅谷!",
            tempAge: this.age
        }
    },
    props: {
        name: {
            type: String,
            required: true
        },
        age: {
            type: Number,
            required: true
        },
        sex: {
            type: String,
            required: true
        }
    },
    methods: {
        changeAge() {
            this.tempAge ++;
        }
    }
}
</script>

<style scoped>

</style>

21.mixin(混入)

21.1定义

混入是可以单独抽出重复配置,这些配置可以是Vue中的一些属性如:methods,并通过引入mixin的形式,解决重复配置的问题

21.2语法:

  • 定义一个混入
//a代表的是混合的名
export const a = {
    methods: {
        sayHello() {
            console.log("你好啊");
        }
    }
}
  • 引入一个混入
<script>
import {a} from "@/mixins/sayHello";
export default {
    name: "CustomerName",
    props: {
        name: {
            type: String,
            required: true
        },
        address: {
            type: String,
            required: true
        }
    },
    mixins: [a]
}
</script>

22.插件(plug)

22.1定义:

用于增强Vue,包含install方法的一个对象,install的第一个参数是Vue,第二个及以后的函数是使用者传递的函数

22.2语法:

  • 定义插件:
export default {
    install(Vue) {

    }
}
  • 使用插件
Vue.use();

23.scoped样式

在单文件组件中写的样式最终会汇总到一起来,这时候就可能会造成class名重复,导致后引入的样式覆盖原来的样式,如何解决这个问题呢?引出了scoped

23.1作用

让样式在局部内生效

23.2语法

<style scoped>
</style>

24.webStroage

存储器大小一般支持5MB左右(不同浏览器还不一样),分为loclaStorage和sessionStorage

24.1localStorage

浏览器关闭,依然存在,保存在本地磁盘上,用户清空缓存,就会消失。

  • 增加
localStorage.setItem("name", "anna");
  • 查询
localStorage.getItem("name")
  • 删除
localStorage.removeItem("name");
  • 清空
localStorage.clear();

24.2sessionStorage

浏览器关闭,存储的信息就会丢失。

  • 增加
sessionStorage.setItem("name", "anna");
  • 查询
sessionStorage.getItem("name")
  • 删除
sessionStorage.removeItem("name");
  • 清空
sessionStorage.clear();

25组件的自定义事件

一种组件间通信的方式,适用于:子组件=>父组件,需要提前准备父组件的回调函数,函数的声明放在子组件中。

25.1绑定自定义事件

  • 1.在父组件中使用@事件名="回调函数" 或者v-on:事件名
  • 2.在父组件中使用this.$refs.refName.$on("事件名'', 回调函数)

注意:使用这种方式,回调函数中的this为子组件的vm

  • 3.子组件使用this.$emit(自定义事件名,参数0

25.2组件中绑定原生组件

@事件名.native

25.3解除绑定

this.$off("事件名")

26.全局事件总线

一种组件间通信的方式,适用于任意组件间的通信

26.1安装全局事件总线

new Vue() {
	.....
	beforeCreate() {
		Vue.$propertype.$bus = this;
	}
}

26.2使用

1.接受数据

methods() {
	demo(data) {
		.....
	}
}
this.$bus.$on('xxxx', this.demo)

2.发送数据

this.$bus.$emit('xxxx', 数据)

注意

最好在beforeDestory中,用 o f f 去解绑当前组件所有的事件,因为如果 off去解绑当前组件所有的事件,因为如果 off去解绑当前组件所有的事件,因为如果bus不会被销毁

27.消息订阅与发布

一种组件间通信的方式,适用于任意组件间通信

27.1使用步骤

  • 1.安装:pubsub:npm i pubsub-js
  • 2.引入:import pubsub from ‘pubsub-js’
  • 3.接受数据:
methods() {
 dome(data) {
 	....
 }
 }
 mounted() {
 this.pid = pubsub.subscribe('xxx',this.demo);
}
  • 4.提供数据:```pubsub.publish(‘xxx’,数据)
  • 5.在beforeDestory中取消订阅:pubsub.unsubscribe(this.pid)

28.$nextTick

当数据渲染之后,执行此API内的回调函数,用于一些特殊场合,比如,当我们想要在数据渲染后获取焦点,而不是数据渲染前执行,示例代码如下

changeName(id, event) {
  let name = event.target.value;
    if (!name.trim()) {
        return alert("修改不能为空");
    }
    this.$bus.$emit("changeName", id, name);
    this.$nextTick(function() {
        this.$refs.inputTitle.focus();
    })
}

29.Vue封装的过度与动画

再插入、更新或移除DOM元素时,再合适的时候给元素添加样式元素
在这里插入图片描述

29.1基本语法

  • 元素进入时的样式
    • v-enter:进入的起点
    • v-enter-active:进入的过程中
    • v-enter-to:进入的起点
  • 元素离开时的样式
    • v-leave:离开时的起点
    • v-leave-active:离开过程中
    • v-leave-to:离开的终点
      注意
  • 使用时,要用transition包裹使用动画的元素
  • 如果多个元素需要过度,则需要使用transition-group,且每个元素要制定key值

30.Axios

30.1使用

  • 安装
npm install axios;
  • 引入
import axios from 'axios'
  • 使用
axios("url",回调函数)

30.2解决跨域

30.2.1单个地址

  • vue.config.js配置代理地址:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    proxy: 'http://localhost:5000'
  }
})
  • 请求地址改为项目启动地址:
axios.get("http://localhost:8080/students", (data) => {
    console.log(data);
})

30.2.2多个地址

devServer: {
 proxy: {
    '/api1': { //url匹配规则
      target: 'http://localhost:5000', //转发地址
      pathRewrite: {'^/api1' : ''}, //重写规则,第一个参数写正则表达式
      ws: true, //是否支持webStock请求
      changeOrigin: true //是否显示正确地址
    },
    '/api2': {
      target: 'http://localhost:5001',
      ws: true,
      pathRewrite: {'^/api2' : ''},
      changeOrigin: true
    }
  }
}

31.插槽

父组件向子组件传递带数据的标签,当一个组件有不确定的结构时, 就需要使用slot 技术,注意:插槽内容是在父组件中编译后, 再传递给子组件的。

31.1分类

31.1.1默认插槽

在这里插入图片描述

31.1.2具名插槽

在这里插入图片描述

31.1.3作用域插槽

数据在组件的自身,但根据数据生成的结构需要组建的使用者决定
在这里插入图片描述
在这里插入图片描述

32.Vuex

32.1概念

在Vue中实现集中式管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件。

32.2原理图

在这里插入图片描述

  • state:Vuex使用单一状态树,我的理解是就是单一的数据源,类似于java中的单例模式,在vue中是全局唯一的。

如何使用state:每一个compoent中都会有一个$store对象,stroe对象中含有state对象,可以通过this.$store.state.状态名访问Vuex状态对象。

  • getter:类似于computed,我们如果想要从state中根据属性派生出来一些属性,就需要用到getter
const getters = {
	bigSum(State) {
		return state.sum * 10;
	}
}

export default new Vue.store(
	getters
)
  • 组件中读取getters
$store.getters.bigSum
  • mutations:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,类似于事件,需要注意的是,mutation的名称建议为大写,并且采用_作为分隔符,并且第一个参数为state,且mutations中必须使用同步方法,因为mutations作为devtool监控的入口,如果采用异步方法,devtool就无法准确的监控对象的变化,语法如下:
mutations: {
	 SET_TOKEN: (state, token) => {
	    state.token = token
	 }
 }
  • action:Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。
    Action 可以包含任意异步操作。语法如下:
actions: {
	Login({ commit }, userInfo) {
	      const username = userInfo.username.trim()
	      return new Promise((resolve, reject) => {
	        login(username, userInfo.password).then(response => {
	          const data = response.result
	          console.log(data)
	          setToken(data.token)
	          commit('SET_TOKEN', data.token)
	          resolve()
	        }).catch(error => {
	          reject(error)
	        })
	      })
	    }
}
  • module: 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
    在这里插入图片描述
    在这里插入图片描述

32.3搭建Vuex环境

  • 创建store/index.js文件
import Vuex from "vuex"
import Vue from 'vue'

Vue.use(Vuex)

const actions = {};

const mutations = {};

const state = {};

export default new Vuex.Store({
    actions,
    mutations,
    state
});
  • 在main.js引入store
import Vue from 'vue'
import App from './App.vue'
import store from "./store"

Vue.config.productionTip = false

const vm = new Vue({
  render: h => h(App),
  store
}).$mount('#app');

注意:

不能再main.js中引入Vuex

32.4.mapState和mapGetter(放在计算属性中)

由于在组件中获取状态对象需要使用this.$store.state.状态名的方法,当我们在组件中需要获取多个state对象时,就会显得代码很繁杂,所以vue官方引出了mapState和mapGetter,并结合对象解析符号...,可以轻松的获取装填对象。

32.4.1使用

  • 引入
import {mapState, mapGetters} from "vuex";
  • 定义
computed: 
 ...mapState(["sum"]),
 ...mapGetters(["bigSum"])
}
  • 两种写法
对象写法:
...mapState({
	sum : "sum"
}),
...mapGetters({
    bigSum : "bigSum"
}),
数组写法:
...mapState(["sum"]),
...mapGetters(["bigSum"])

32.5.mapActions和mapMutations(放在methos中)

32.5.1使用

  • 引入
import {mapState, mapGetters, mapActions, mapMutations} from "vuex";
  • 使用
methods: {
  ...mapActions({
        incrementWait: "incrementWait",
        incrementOdd: "incrementOdd",
    }),
    ...mapMutations({
        INCREMENT: "INCREMENT",
        DECREMENT: "DECREMENT"
    })
}
  • 两种写法
对象写法
...mapActions({
  incrementWait: "incrementWait",
  incrementOdd: "incrementOdd",
}),
...mapMutations({
    INCREMENT: "INCREMENT",
    DECREMENT: "DECREMENT"
})
数组写法
...mapActions(["incrementWait", "incrementOdd"]),
...mapMutations(["INCREMENT", "DECREMENT"])

32.6模块化编码+ 命名空间

在这里插入图片描述
在这里插入图片描述

33.路由

路由就是一组映射关系(key-value),key为路径,value可能为function和component

33.1分类

  • 后端路由(了解)

value是function,用于处理客户端提交的请求,指的是服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据。

  • 前端路由

value就是component,用于展示页面内容,当浏览器的类路径改变时,对应的组件就会显示。

33.2使用

  • 1.下载插件
npm install vue-router@3
  • 2.脚手架使用
    main.js
import Vue from 'vue'
import App from './App.vue'
import router from "@/router";
import VueRouter from "vue-router";

Vue.use(VueRouter);
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

App.vue

<template>
    <div id="app">
        <div>
            <div class="row">
                <div class="col-xs-offset-2 col-xs-8">
                    <div class="page-header"><h2>Vue Router Demo</h2></div>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-2 col-xs-offset-2">
                    <div class="list-group">
                        <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
                        <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
                    </div>
                </div>
                <div class="col-xs-6">
                    <div class="panel">
                        <div class="panel-body">
                            <router-view/>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: 'App'
}
</script>

<style>
</style>
  • 3.在router目录下创建index.js中注册路由
import VueRouter from "vue-router";
import About from "@/components/About.vue";
import Home from "@/components/Home.vue";

export default new VueRouter({
    routes: [{
        path: "/about",
        component: About
    },{
        path: "/home",
        component: Home
    }]
})

33.3注意点

  • 1.路由组件通常存放在pages文件夹,一般组件通常放在component文件夹
  • 2.通过切换,“隐藏“了的路由组件,默认是被销毁的,需要的时候再被挂载
  • 3.每个组件都有自己的$route属性,里面存储着自己的路由信息
  • 4.整个应用只有一个router,可以通过组件的$router属性获取

33.4多级路由

  • 1.配置路由规则
import VueRouter from "vue-router";
import About from "@/pages/About.vue";
import Home from "@/pages/Home.vue";
import HomeMsg from "@/pages/HomeMsg.vue";
import HomeNew from "@/pages/HomeNew.vue";

export default new VueRouter({
    routes: [{
        path: "/about",
        component: About
    },{
        path: "/home",
        component: Home,
        children: [
            {
                path: "homeMsg", //不要加‘/’
                component: HomeMsg
            },
            {
                path: "homeNew",
                component: HomeNew
            }
        ]
    }]
})

注意:使用的时候要把路径补全

<router-link to="/home/homeMsg" class="list-group-item">Message</router-link>

33.5路由传递参数

33.5.1query方式

  • 路径方式
<template>
    <div>
        <ul>
            <li v-for="item in msgList" :key="item.id">
                <!-- query形式 -->
                <router-link :to="`/home/homeMsg/details?id=${item.id}&title=${item.title}`"> {{item.title}}{{item.id}}</router-link>
            </li>
        </ul>
        <router-view/>
    </div>
</template>

<script>
export default {
    name: "HomeMsg",
    data() {
        return {
            msgList: [
                {id: "001", title: "消息"},
                {id: "002", title: "消息"},
                {id: "003", title: "消息"}
            ]
        }
    }
}
</script>

<style scoped>

</style>

注意

  • 与get请求方式相同
  • to必须使用v-bind绑定,并配合${}使用
  • 对象方式
<template>
    <div>
        <ul>
            <li v-for="item in msgList" :key="item.id">
                <!-- 对象形式 -->
                <router-link :to="{
                	<!-- 请求路径 -->
                    path: '/home/homeMsg/details',
                    <!-- 请求参数 -->
                    query: {
                        id: item.id,
                        title: item.title
                    },
                    <!-- 路由名,如果太长可以用路由名代替路径 -->
                    name: 'name’
                }">{{item.title}}{{item.id}}</router-link>
            </li>
        </ul>
        <router-view/>
    </div>
</template>

<script>
export default {
    name: "HomeMsg",
    data() {
        return {
            msgList: [
                {id: "001", title: "消息"},
                {id: "002", title: "消息"},
                {id: "003", title: "消息"}
            ]
        }
    }
}
</script>

<style scoped>

</style>
  • 使用
<template>
    <div>
        <ul>
            <li>
                消息编号:{{$route.query.id}}
            </li>
            <li>
                消息标题:{{$route.query.title}}
            </li>
        </ul>
    </div>
</template>

33.5.2params方式(不能使用path,只能用name.另外,一定要再路由中配置占位符(:id,:title))

  • 路径方式
<template>
    <div>
        <ul>
            <li v-for="item in msgList" :key="item.id">
                <!-- 对象形式 -->
                <router-link :to="`/home/homeMsg/details/${item.id}/${item.title}`">
                    {{item.title}}{{item.id}}
                </router-link>
            </li>
        </ul>
        <router-view/>
    </div>
</template>

<script>
export default {
    name: "HomeMsg",
    data() {
        return {
            msgList: [
                {id: "001", title: "消息"},
                {id: "002", title: "消息"},
                {id: "003", title: "消息"}
            ]
        }
    }
}
</script>

<style scoped>

</style>
{
    path: "homeMsg", //不要加‘/’
    component: HomeMsg,
    children: [
        {
            path: "details/:id/:title", //:代表占位
            component: MsgDetails
        }
    ]
}
  • 参数方式
<template>
    <div>
        <ul>
            <li v-for="item in msgList" :key="item.id">
                <!-- 对象形式 -->
                <router-link :to="{
                    name: 'details',
                    params: {
                        id: item.id,
                        title: item.title
                    }
                }">
                    {{item.title}}{{item.id}}
                </router-link>
            </li>
        </ul>
        <router-view/>
    </div>
</template>
import VueRouter from "vue-router";
import About from "@/pages/About.vue";
import Home from "@/pages/Home.vue";
import HomeMsg from "@/pages/HomeMsg.vue";
import HomeNew from "@/pages/HomeNew.vue";
import MsgDetails from "@/pages/MsgDetails.vue";

export default new VueRouter({
    routes: [{
        path: "/about",
        component: About
    }, {
        path: "/home",
        component: Home,
        children: [
            {
                path: "homeMsg", //不要加‘/’
                component: HomeMsg,
                children: [
                    {
                        name: "details",
                        path: "details",
                        component: MsgDetails
                    }
                ]
            },
            {
                path: "homeNew",
                component: HomeNew
            }
        ]
    }]
})

33.5props属性

让路由组件更方便的收到参数

在这里插入图片描述

33.6的repalce属性

控制路由跳转时操作浏览器历史记录的模式

  • 浏览器的历史操作记录有两种方式,分别为push和replace,push是追加历史记录,replace是替换当前记录,路由跳转默认为push
  • 如何开始replace模式:router-link replace .....>News</router-link>

33.7编程式路由导航

/**
 * push跳转
 */
queryOfPush(item) {
    this.$router.push({
        name: 'details',
        params: {
            id: item.id,
            title: item.title
        }
    })
},
/**
 * replace跳转
 */
queryOfReplace(item) {
    this.$router.replace({
        name: 'details',
        params: {
            id: item.id,
            title: item.title
        }
    })
}

33.6.1常用的一些方法

  • 路由后退:jsthis.$router.back();
  • 路由前进:jsthis.$router.forward();
  • 路由指定前进几步:jsthis.$router.go(指定步数);

33.7缓存路由组件

作用:让不展示的路由组件保持挂载,不被销毁

实现

<keep-alive include="组件名,name要与组件名相同,不然不行,我觉得这边可能是组件的name值">
    <router-view/>
</keep-alive>

也可以使用组件::include="数组"

33.8路由的特有钩子

路由组件所独有的两个钩子,用于捕获路由组件的激活状态

  • activated:路由组件被激活时触发
  • deactivated:路由组件失活时触发

33.9路由守卫

/**
 * 前置路由守卫
 */
vueRouter.beforeEach((to, from, next) => {
    if (to.path.includes("about")) {
        if (to.meta.isAuth) {
            next();
        }
    } else {
        next();
    }
});

/**
 * 后置路由守卫
 */
vueRouter.afterEach((to, from) => {
    document.title = to.meta.title;
})
//独享路由守卫
beforeEnter(to, from, next) {
	next();
}
//组件内守卫(进入)
beforeRouterEnter(to,from,next) {
}
//组件内守卫(离开)
beforeRouterLeave(to,from,next) {
}

33.10history模式和hash模式

  • hash值就是#及其后面的内容,并且hash值不会包含在http请求中,即:hash值不会带给服务器。
    在这里插入图片描述
  • hash模式
    • 地址中永远带着#,不美观
    • 若以后地址通过第三方手机app分享,若app校验严格,则地址会标记为不合符
    • 兼容性好
  • history模式
    • 地址干净,美观
    • 兼容性比hash差
    • 应用上线需要后端人员支持,解决404问题。

34.UI组件库

34.1常用的UI库

在这里插入图片描述

34.2引入elementui

import Vue from 'vue'
import App from './App.vue'
import router from "@/router";
import VueRouter from "vue-router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(VueRouter);
Vue.config.productionTip = false
Vue.use(ElementUI);

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

35.Vue3

35.1创建Vue3项目

vue create <project-name>
npm init vite-app <project-name>

注意点:

  • 如果是用vite创建的项目,是不会自动下载依赖,所以需要手动下载一下依赖

35.2main.js介绍

//引入vm工厂
import { createApp } from 'vue'
import App from './App.vue'

//createApp:vm工厂,用来生成vm实例,相比于Vue2中通过构造函数创建vm,使用工厂创建vm,减轻了vm的体积,轻量化
createApp(App).mount('#app')

35.3setup函数

  • 组件中所有到的:数据、方法等等,均要配置在setup中
  • setup的返回值:
    • 若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用(重点)
    • 若返回一个渲染函数,则可以自定义渲染内容。(了解)

注意点:

  • 不要与Vue2昏庸
  • setup不能是一个async函数
  • setup是在beforeCreate之前执行一次,this是undefined
  • setup有两个参数,props就是父组件传递给子组件的参数,context是上下文对象,包括attrs(相当于this.$attrs),slots(相当于this.$slots),emit:(相当于this.$emit)

35.4ref函数

  • 作用:定义一个响应式数据
  • 语法:const xxx = ref(initValue),JS操作数据:xxx.value,模板中读取数据:不需要.value

注意点:

  • 接受的数据可以是:基本类型,也可以是对象类型,基本类型响应式通过Object.defineProperty()函数的get和set实现的,对象类型的数据,内部使用了reactive函数

35.5reactive函数

  • 作用:定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
  • 语法:const 代理对象 = reactive(原对象),返回一个代理对象(Proxy的实例对象,简称proxy对象)
  • reactive定义的响应式数据是深层次的
  • 内部基于ES6的proxy实现,通过代理对象操作原对象内部数据进行操作

35.6响应式原理

  • 实现过程:
  • 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。
  • 通过Reflect(反射):对源对象的属性进行操作
  • 代码
new Proxy(data, {
 get(target, prop) {
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    return Reflect.set(target, prop, value);
  },
  deleteProperty(target, p) {
    return Reflect.deleteProperty(target, p);
  }
})

35.7reactive与ref的对比

  • 从定义调度

ref是用来定义基础类型的,reactive使用来定义引用类型的,当然ref也可以定义引用类型,内部时会自动使用reactive的

  • 从原理角度

ref是通过Object.defineProperty()的set、get方法实现的
reactive是通过Proxy实现的

  • 从使用角度对比

ref定义的数据,操作的时候需要.value,而reactive定义的数据就不需要

35.8计算属性的使用

<script>
import {reactive, computed} from 'vue'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  setup() {
    let person = reactive({
      firstName: "tom",
      lastName: "li"
    });
    //计算属性,简写
    person.fullName = computed(() => {
      return person.firstName + "-" + person.lastName;
    });

    //计算属性,全写
    person.fullName2 = computed({
      get() {
        return person.firstName + "-" + person.lastName
      },
      set(value) {
        const nameArr = value.split("-");
        person.firstName = nameArr[0];
        person.lastName = nameArr[1];
      }
    })
    return {person}

  }
}
</script>

35.9watch函数

  • 与Vue2中watch的功能一致

注意点:

  • 监视reactive定义的响应式数据时:oldValue无法正确获取,强制开启了深度监视(deep配置失效)
  • 监视reactive定义的响应式数据的某个属性时,deep配置失效

35.10watchEffect函数

  • watch的思路是:既要指明监视的属性,也要指明监视的回调
  • watchEffect的套路是:不用知名监视哪个属性,坚实的回调中用到那个属性,那就监视那个属性
  • watchEffect类似于computed,只不过computed注重计算的计算的结果,watch注重计算的过程

35.11生命周期

在这里插入图片描述

注意事项:

  • vue3用beforeUnMounte和mouted代替了beforeDestory和Destory
  • 如果要将生命周期钩子写到组合式API中,created和beforeCreate都又setup代替,需要在每个生命周期函数上加个on

35.12hook函数

  • hook函数就是把setup中的Composition Api进行了封装(命名以use开头,例如:useMessage)
  • 类似于vue2.x中的mixin
  • 使用方法:
    • 将setup中复用代码封装到一个js文件中,在vue文件中引用即可

35.13toRef

  • 作用:创建一个ref对象,其value值指向另一个对象中的某个属性
  • 语法:const name = toRef(person, 'name')
  • 应用:要将响应式对象中的某个属性单独提供给外部使用
  • 扩展:toRefs与toRef功能一致,但可以批量创建多个ref对象,语法:```toRefs(person)``

35.14shallReactive和shallowRef

  • shallowReactive:只处理最外层属性的响应式
  • shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理
  • 如果有一个对象数据,结构比较深,但变化只是做外层属性变化用shallowReactive
  • 如果有个一对象数据,后续功能不会修改该属性就用shallowRef

35.15readonly和shallowReadonly

readonly是禁止对一个对象进行修改,shallowReadonly是禁止对一个对象的第一层进行修改

35.16toRaw和markRaw

toRaw是将一个ractive函数处理的变量失去reactive的处理,markRaw是标记一个对象,使其永远不会成为响应式对象

35.17customRef

  • 作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制。

35.18provide和inject

  • 作用:组件与后代组件间的通信方式,一般不用再父子组件上,父子组件上还是用props
  • 语法:
provide('car', car);
let cat = inject('car')

35.19响应式数据的判断

  • isRef:检查一个对象是否为ref对象
  • isReactive:检查一个对象是否由reactive创建的响应式对象
  • isReadonly:检查一个对象是否由readonly创建的只读代理
  • isProxy:检查一个对象是否由reactive或者readonly创建的对象

35.20Fragment标签

在Vue2中,每个组件中必须有个一个根标签,而在vue3中,将由Fragment标签代替这个根标签,当然Fragment标签和template标签相似,都是个虚拟标签,不会产生真实的bom结构

35.21Teleport

  • 作用:将标签可以瞬移到某个位置
  • 代码
#当显示的时候,将h1标签放到body下
<teleport v-if='isShow' to='body'>
	<h1>{{person.name}}</h1>
</telepor>

35.22Suspense

  • 等待异步组件时渲染一些额外内容,让应用有更好的体验
  • 在这里插入图片描述

35.23Vue3的其他调整

在这里插入图片描述

常用配置:

1.关闭esline检查

module.exports = defineConfig({
  lintOnSave: false
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值