【前端框架】Vue2合集

一、Vue快速上手

1、Vue概念

vue 是一个用于构建用户界面的渐进式框架,由数据驱动

vue 的两种使用方式

  1. vue 核心包开发:局部模块改造
  2. vue 核心包与 vue 插件 工程化开发:整站 开发

2、 创建实例

1、准备容器

<div id="app"></div>

2、导包

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

3、创建Vue实例

const vue = new Vue()

4、指定配置项 => 渲染数据

const vue = new Vue({// el:配置选择器el: '#app',// data:提供数据data: {msg: 'hello vue',h: 'VUE!'}
})
<div id="app"><h1>{{ h }}</h1>{{ msg }}
</div>

3、插值表达式

插值表达式语法:{{ 表达式 }}

利用表达式插值,渲染到页面

<p>{{ title }}</p>

4、响应式特性

数据的响应式处理:数据变化,视图自动更新。数据驱动视图更新

  1. 访问数据: “实例.属性名”
  2. 修改数据: “实例.属性名”= “新值”

二、Vue指令

1、常用指令

指令(Directives)是 Vue 提供的带有 v- 前缀 的 特殊 标签属性

  • 内容渲染指令(v-html、v-text)
  • 条件渲染指令(v-show、v-if、v-else、v-else-if)
  • 事件绑定指令(v-on)
  • 属性绑定指令 (v-bind)
  • 双向绑定指令(v-model)
  • 列表渲染指令(v-for)

2、内容渲染指令

v-text(类似innerText):将 uame 值渲染到 p 标签中,覆盖 p 标签原有内容

<p v-text="uname">hello</p>

v-html(类似 innerHTML):将 intro 值渲染到 p 标签中,能够将HTML标签的样式呈现出来。

<p v-html="intro">hello</p>

3、条件渲染指令

条件判断指令,用来辅助开发者按需控制 DOM 的显示与隐藏。

v-show:(控制元素显示隐藏)切换 display:none 控制显示隐藏。

v-if:(条件渲染)基于条件判断,是否创建 或 移除元素节点。

语法:v-show = “表达式”,v-if = “表达式”。表达式值为 true 显示, false 隐藏。

v-else 和 v-else-if:

  1. 作用:辅助v-if进行判断渲染
  2. 语法:v-else v-else-if=“表达式”
  3. 需要紧接着v-if使用

4、事件绑定指令

<button v-on:事件名="内联语句">按钮</button>
<button v-on:事件名="处理函数">按钮</button>
<button v-on:事件名="处理函数(实参)">按钮</button>

v-on: 简写为 @

(1)内联语句:

<button @click="cnt++">+</button>
<div>{{ cnt }}</div>
<button @click="cnt--">+</button>

(2)处理函数:

事件处理函数写在methods中,methods中的函数内部的this都指向Vue实例

<div id="app"><button @click="hd">切换</button><h3 v-show="hide">method函数切换显示和隐藏</h3>
</div>
<script>const app = new Vue({el: '#app',data: {hide: true},methods: {hd() {this.hide = !this.hide}}})
</script>

(3)调用传参:

如果不传递任何参数,则方法无需加小括号;methods方法中可以直接使用 e 当做事件对象

如果传递了参数,则实参 $event 表示事件对象(固定用法)

<div id="app"><div class="box"><h3>小黑自动售货机</h3><button @click="fn(5)">可乐5元</button></div><p>银行卡余额:{{ money }}元</p>
</div>
const app = new Vue({el: '#app',data: {money: 100},methods: {fn(i) {this.money -= i}}
})

5、属性绑定指令

动态设置html的标签属性 比如:src、url、title

语法:**v-bind:**属性名=“表达式”,**v-bind:**可以简写成 :

<img :src="img">

6、列表渲染指令

v-for 列表渲染指令,用来基于一个数组来循环渲染一个列表结构。

<p v-for='(item, index) in arr'> </p>

v-for 的语法:

  • item 是数组中的每一项
  • index 是每一项的索引(可以省略)
  • arr 是被遍历的数组
<ul><li v-for="(item, index) in list">{{ index + '--' + item}}</li>
</ul>

v-for中的key:给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用

Vue 的默认行为会尝试原地修改元素(就地复用)

<ul><li v-for="(item, index) in booksList" :key="item.id"><span>{{ item.name }}</span><span>{{ item.author }}</span><button @click="del(item.id)">删除</button></li>
</ul>

7、双向绑定指令

1、数据变化 => 视图自动更新

2、视图变化 => 数据自动更新

**语法:**v-model=“变量”

姓名:<input type="text" v-model="username">

v-model绑定其他表单元素:

  • 输入框 input:text => value
  • 文本域 textarea => value
  • 复选框 input:checkbox => checked
  • 单选框 input:radio => checked
  • 下拉菜单 select => value

8、指令修饰符

所谓指令修饰符就是通过.指明一些指令后缀不同的后缀封装了不同的处理操作 (简化代码)

  • @keyup.enter => 当点击enter键的时候才触发
  • v-model.trim => 去除首位空格
  • v-model.number => 转数字
  • @事件名.stop => 阻止冒泡
  • @事件名.prevent => 阻止默认行为
  • @事件名.stop.prevent => 可以连用 即阻止事件冒泡也阻止默认行为

9、v-bind操作class

(1)数组

<div class="box" :class="[ 类名1, 类名2, 类名3 ]"></div>

(2)对象

当class动态绑定的是对象时,键就是类名,值就是布尔值,如果值是true,就有这个类,否则没有这个类

<div class="box" :class="{ 类名1: 布尔值, 类名2: 布尔值 }"></div>

10、v-bind操作style

<div class="box" :style="{ CSS属性名1: CSS属性值, CSS属性名2: CSS属性值 }"></div>

三、computed计算属性

1、计算属性概述

基于现有的数据,计算出来的新属性依赖的数据变化,自动重新计算。

  1. 声明在 computed 配置项中,一个计算属性对应一个函数
  2. 使用起来和普通属性一样使用 {{ 计算属性名 }}

2、计算属性与方法区别

  • computed计算属性:封装了一段对于数据的处理,求得一个结果
  • methods计算属性:给Vue实例提供一个方法,调用以处理业务逻辑

计算属性的优势:

  1. 缓存特性(提升性能):计算属性会对计算出来的结果缓存,再次使用直接读取缓存,依赖项变化了,会自动重新计算并再次缓存

  2. methods没有缓存特性

3、计算属性的完整写法

计算属性默认的简写,只能读取访问,不能 “修改”

四、watch侦听器

1、watch侦听器

监视数据变化,执行一些业务逻辑或异步操作

watch同样声明在跟data同级的配置项中

  1. 简单写法:简单类型数据直接监视
  2. 完整写法:添加额外配置项
data: { words: '苹果',obj: {words: '苹果'}
},watch: {// 该方法会在数据变化时,触发执行数据属性名 (newValue, oldValue) {一些业务逻辑 或 异步操作。 },'对象.属性名' (newValue, oldValue) {一些业务逻辑 或 异步操作。 }
}

2、侦听器完整语法

  1. deep:true 对复杂类型进行深度监听
  2. immdiate:true 初始化 立刻执行一次
data: {obj: {words: '苹果',lang: 'italy'},
},watch: {// watch 完整写法对象: {deep: true, // 深度监视immdiate:true,//立即执行handler函数handler (newValue) {console.log(newValue)}}
}

五、生命周期

1、Vue生命周期

生命周期四个阶段:① 创建 ② 挂载 ③ 更新 ④ 销毁

  1. 创建阶段:创建响应式数据
  2. 挂载阶段:渲染模板
  3. 更新阶段:修改数据,更新视图
  4. 销毁阶段:销毁Vue实例

2、Vue生命周期钩子

Vue生命周期过程中,会自动运行一些函数,被称为【生命周期钩子】→ 让开发者可以在【特定阶段】运行自己的代码

六、工程化开发

1、工程化开发和脚手架

  • 核心包传统开发模式:基于html / css / js 文件,直接引入核心包,开发 Vue。
  • 工程化开发模式:基于构建工具(例如:webpack)的环境中开发Vue。

工程化开发模式优点:提高编码效率,比如使用JS新语法、Less/Sass、Typescript等通过webpack都可以编译成浏览器识别的ES3/ES5/CSS等

脚手架Vue CLI: Vue CLI 是Vue官方提供的一个全局命令工具

## 1、全局安装(只需安装一次即可)
vue create project-nameyarn global add @vue/cli
## npm i @vue/cli -g## 2、查看vue/cli版本
vue --version## 3、创建项目架子
vue create project-name## 4、启动项目
yarn serve
## npm run serve

2、项目目录与运行流程

  1. main.js 入口文件
  2. App.vue App根组件
  3. index.html 模板文件

3、组件化开发

组件化:一个页面可以拆分成一个个组件,每个组件有着自己独立的结构、样式、行为。

好处:便于维护,利于复用 → 提升开发效率。

组件分类:普通组件、根组件。

Vue的三部分:

  • template:结构 (有且只能一个根元素)
  • script: js逻辑
  • style: 样式 (可支持less,需要装包)

<template><div class="App"><div class="box" @click="fn"></div></div>
</template><script>
// 导出的是当前组件的配置项
// 里面可以提供 data(特殊) methods computed watch 生命周期八大钩子
export default {created () {console.log('我是created')},methods: {fn () {alert('你好')}}
}
</script><style lang="less">
/* 让style支持less1. 给style加上 lang="less"2. 安装依赖包 less less-loaderyarn add less less-loader -D (开发依赖)
*/
.App {width: 400px;height: 400px;background-color: pink;.box {只能在注册的组件内使用width: 100px;height: 100px;background-color: skyblue;}
}
</style>

4、普通组件的注册使用

1)局部注册

特点:只能在注册的组件内使用

  1. 创建.vue文件(三个组成部分)
  2. 在使用的组件内先导入再注册
  3. 当成html标签使用即可 <组件名></组件名>

组件名规范:必须大驼峰命名法

// 导入需要注册的组件
import 组件对象 from '.vue文件路径'
import HmHeader from './components/HmHeader'export default {  // 局部注册components: {'组件名': 组件对象,HmHeader:HmHeaer,HmHeader}
}
2)全局注册

特点:全局注册的组件,在项目的任何组件中都能使用

  1. 创建.vue组件(三个组成部分)
  2. main.js中进行全局注册
  3. 当成HTML标签直接使用
// 导入需要全局注册的组件
import HmButton from './components/HmButton'
Vue.component('HmButton', HmButton)

5、scoped解决样式冲突

  1. 全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响

  2. 局部样式: 可以给组件加上scoped 属性,可以让样式只作用于当前组件

<template><div class="base">Base</div>
</template><script>
export default {}
</script><style scoped>
</style>

scoped原理:

  1. 当前组件内标签都被添加data-v-hash值 的属性
  2. css选择器都被添加 [data-v-hash值] 的属性选择器

6、data是一个函数

一个组件的 data 选项必须是一个函数

目的:保证每个组件实例,维护独立的一份数据对象。每次创建新的组件实例,都会新执行一次data 函数,得到一个新对象。

<script>
export default {data: function () {return {count: 100,}},
}
</script>

七、组件通信

1、组件通信

1)组件之间如何通信

2)通信解决方案

2、父子通信

1)父子通信
  1. 父组件通过 props 将数据传递给子组件
  2. 子组件利用 $emit 通知父组件修改更新

父传子:

  1. 给子组件以添加属性的方式传值
  2. 子组件内部通过props接收
  3. 模板中直接使用 props接收的值

**子传父:**子组件利用 $emit 通知父组件,进行修改更新

  1. $emit触发事件,给父组件发送消息通知
  2. 父组件监听$emit触发的事件
  3. 提供处理函数,在函数的性参中获取传过来的参数
2)props概述

Props:组件上 注册的一些 自定义属性

作用:向子组件传递数据

  • 可以 传递 任意数量 的prop
  • 可以 传递 任意类型 的prop
3)props校验

为组件的 prop 指定验证要求,不符合要求,控制台就会有错误提示。帮助开发者,快速发现错误。

类型校验:

props: {校验的属性名: 类型
},

完整写法:

props: {校验的属性名: {type: 类型,  // Number String Boolean ...required: true, // 是否必填default: 默认值, // 默认值validator (value) {// 自定义校验逻辑return 是否通过校验}}
},
5)props&data、单向数据流
  • data 的数据是自己的 → 随便改
  • prop 的数据是外部的 → 不能直接改,要遵循 单向数据流

单向数据流:父级 props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的

原则:谁的数据谁负责

3、非父子通信

1)event bus 事件总线

1、创建一个都能访问的事件总线 (空Vue实例)

import Vue from 'vue'
const Bus = new Vue()
export default Bus

2、A组件(接受方),监听Bus的 $on事件

created () {Bus.$on('sendMsg', (msg) => {this.msg = msg})
}

3、B组件(发送方),触发Bus的$emit事件

Bus.$emit('sendMsg', '这是一个消息')

2)provide&inject

作用:跨层级共享数据

1、父组件 provide 提供数据

export default {provide () {return {// 普通类型【非响应式】color: this.color, // 复杂类型【响应式】userInfo: this.userInfo, }}
}

2、子、孙组件 inject 获取数据

export default {inject: ['color','userInfo'],created () {console.log(this.color, this.userInfo)}
}
  • provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据)
  • 子/孙组件通过inject获取的数据,不能在自身组件内修改

八、进阶语法

1、v-model进阶

1)v-model原理

v-model本质上是一个语法糖。例如应用在输入框上,就是value属性 和 input事件 的合写

<input v-model="msg" type="text"><input :value="msg" @input="msg = $event.target.value" type="text">
  • 数据变,视图跟着变 :value
  • 视图变,数据跟着变 @input

$event 用于在模板中,获取事件的形参

2)表单类组件封装

v-model其实就是 :value@input事件的简写

  • 子组件:props通过value接收数据,事件触发 input
  • 父组件:v-model直接绑定数据

子组件

<select :value="value" @change="handleChange"><option value="1">yx1</option><option value="2">yx2</option>
</select>
<script>
export default {props: ['value'],methods: {handleChange(e) {this.$emit('input', e.target.value)}}
}
</script>

父组件

<VmolelTest v-model="select"></VmolelTest>

2、.sync修饰符

.sync:可以实现 子组件 与 父组件数据 的 双向绑定

本质:.sync修饰符 就是 :属性名@update:属性名 合写

父组件

//.sync写法
<BaseDialog :visible.sync="isShow" />
--------------------------------------
// 完整写法
<BaseDialog :visible="isShow" @update:visible="isShow = $event" 
/>

子组件

props: {visible: Boolean
},this.$emit('update:visible', false)

3、ref和$refs

利用ref$refs 可以用于 获取 dom 元素 或 组件实例

1、给要获取的盒子添加ref属性

<div ref="yx">我真是伊煊</div>
<button @click="change"></button>

2、通过 $refs 获取 this.\$refs.chartRef 获取

export default {methods: {change() {this.$refs.yx.innerText = '其实我是扑流萤!'}}
}

只用document.querySelect(‘.box’) 获取的是整个页面中的盒子

4、异步更新 与 $nextTick

Vue 是异步更新DOM (提升性能)

$nextTick等 DOM更新后,才会触发执行此方法里的函数体

语法: this.$nextTick(函数体)

this.$nextTick(() => {this.$refs.inp.focus()
})

$nextTick 内的函数体 一定是箭头函数,这样才能让函数内部的this指向Vue实例

九、自定义指令

1、基本语法

自定义指令:封装一些DOM操作,扩展额外的功能

全局注册

//在main.js中
Vue.directive('指令名', {"inserted" (el) {// 可以对 el 标签,扩展额外功能el.focus()}
})

局部注册

//在Vue组件的配置项中
directives: {"指令名": {inserted (el) {// 可以对 el 标签,扩展额外功能el.focus()}}
}

在使用指令的时候,一定要先注册再使用,否则会报错

使用指令语法: v-指令名。

<input type="text"  v-focus/>  

注册指令时不用v-前缀,但使用时一定要加v-前缀

2、自定义指令传参

在绑定指令时,可以通过“等号”的形式为指令 绑定 具体的参数值

<div v-color="color">我是内容</div>

通过 binding.value 可以拿到指令值,指令值修改会 触发 update 函数

directives: {color: {inserted (el, binding) {el.style.color = binding.value},update (el, binding) {el.style.color = binding.value}}
}

十、插槽

1、默认插槽

让组件内部的一些 结构 支持 自定义

  1. 组件内需要定制的结构部分,改用<slot></slot>占位
  2. 使用组件时, <MyDialog></MyDialog>标签内部, 传入结构替换slot
  3. 给插槽传入内容时,可以传入纯文本、html标签、组件

2、后备内容(默认值)

封装组件时,可以为预留的 <slot> 插槽提供后备内容(默认内容)。

  • 外部使用组件时,不传东西,则slot会显示后备内容
  • 外部使用组件时,传东西了,则slot整体会被换掉
<template><div class="dialog-test"><slot>我是默认内容</slot></div>
</template>
<template><div id="app"><DialogTest>我是自定义内容</DialogTest><DialogTest></DialogTest></div>
</template>

3、具名插槽

一个组件内有多处结构,需要外部传入标签,进行定制

  • 多个slot使用name属性区分名字
  • template配合v-slot:名字来分发对应标签

v-slot的简写: v-slot —> #

<template><div class="dialog-test2"><div>name:<slot name="name"></slot></div></div>
</template>
<DialogTest2><template #name>伊煊</template>
</DialogTest2>

4、作用域插槽

定义slot 插槽的同时, 是可以传值的。给 插槽 上可以 绑定数据,将来 使用组件时可以用

1、给 slot 标签, 以 添加属性的方式传值

<slot :id="item.id" msg="测试文本"></slot>

2、所有添加的属性, 都会被收集到一个对象中

{ id: 3, msg: '测试文本' }

3、在template中, 通过 #插槽名= "obj" 接收,默认插槽名为 default

<MyTable :list="list"><template #default="obj"><button @click="del(obj.id)">删除</button></template>
</MyTable>

十一、路由

1、单页应用程序介绍

单页应用程序SPA:是指所有的功能都在一个html页面上实现

网易云音乐 https://music.163.com/

  • 单页应用类网站:系统类网站 / 内部网站 / 文档类网站 / 移动端站点
  • 多页应用类网站:公司官网 / 电商类网站

优点:页面按需更新

Vue中的路由:路径和组件映射关系

2、路由的基本使用

路由作用:修改地址栏路径时,切换显示匹配的组件

VueRouter的使用(5+2)

固定5个固定的步骤

1、下载 VueRouter 模块到当前工程,版本3.6.5

yarn add vue-router@3.6.5

2、main.js中引入VueRouter

import VueRouter from 'vue-router'

3、安装注册

Vue.use(VueRouter)

4、创建路由对象

const router = new VueRouter()

5、注入,将路由对象注入到new Vue实例中,建立关联

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

两个核心步骤

1、创建需要的组件(views目录),配置路由规则

2、配置导航,配置路由出口(路径匹配的组件显示的位置)

<div class="footer_wrap"><a href="#/find">发现音乐</a><a href="#/my">我的音乐</a><a href="#/friend">朋友</a>
</div>
<div class="top"><router-view></router-view>
</div>

3、组件的存放目录

.vue文件 本质无区别,分类开来的目的就是为了 更易维护

  1. src/views文件夹:页面组件 - 页面展示 - 配合路由用

  2. src/components文件夹:复用组件 - 展示数据 - 常用于复用

4、路由的封装抽离

拆分模块,利于维护

脚手架环境下 @指代src目录,可以用于快速引入组件

5、声明式导航

1)导航链接

vue-router 提供了一个全局组件 router-link (取代 a 标签)

  • 能跳转,配置 to 属性指定路径(必须) 。本质还是 a 标签 ,to 无需 #
  • 能高亮,默认就会提供高亮类名,可以直接设置高亮样式
<div><div class="footer_wrap"><router-link to="/find">发现音乐</router-link><router-link to="/my">我的音乐</router-link><router-link to="/friend">朋友</router-link></div><div class="top"><!-- 路由出口 → 匹配的组件所展示的位置 --><router-view></router-view></div>
</div>

实现高亮:

当前点击的链接默认加了两个class的值 router-link-exact-activerouter-link-active

  1. router-link-active:模糊匹配
  2. router-link-exact-active:精确匹配

自定义类名:

用于定制默认的两个类名

const router = new VueRouter({routes: [...],linkActiveClass: "类名1",linkExactActiveClass: "类名2"
})
2)查询参数传参

传递参数:

<router-link to="/path?参数名=值"></router-link>

接受参数:

this.$route.query.参数名
3)动态路由传参

动态路由后面的参数可以随便起名,但要有语义

配置动态路由:

const router = new VueRouter({routes: [...,{ path: '/search/:words', component: Search }]
})

配置导航链接:

<router-link to="/path/参数值"></router-link>

对应页面组件接受参数:

this.$route.params.参数名

params后面的参数名要和动态路由配置的参数保持一致

4)动态路由参数的可选符

/search/:words 表示,必须要传参数。如果不传参数,也希望匹配,可以加个可选符?

const router = new VueRouter({routes: [...,{ path: '/search/:words?', component: Search }]
})

8、Vue路由

1)重定向

网页打开时, url 默认是 / 路径,未匹配到组件时,会出现空白

重定向 → 匹配 / 后, 强制跳转 /home 路径

{ path: 匹配路径, redirect: 重定向到的路径 },
// 比如:
{ path:'/' ,redirect:'/home' }
2)404

当路径找不到匹配时,给个提示页面。一般都配置在其他路由规则的最后面。

import NotFind from '@/views/NotFind'const router = new VueRouter({routes: [...{ path: '*', component: NotFind } // 最后一个]
})
3)路由模式设置

路由的路径看起来不自然, 有个#

  • hash路由(默认) 例如: http://localhost:8080/#/home
  • history路由(常用) 例如: http://localhost:8080/home

以后上线需要服务器端支持,开发环境webpack给规避掉了history模式的问题

const router = new VueRouter({mode:'history', //默认是hashroutes:[]
})

9、编程式导航

1)path路径跳转

不传参:

// 简单写法
this.$router.push('路由路径')// 完整写法
this.$router.push({path: '路由路径'
})

传参:

// 1、query传参
// 简单写法
this.$router.push('/路径?参数名1=参数值1&参数2=参数值2')
// 完整写法
this.$router.push({path: '/路径',query: {参数名1: '参数值1',参数名2: '参数值2'}
})// 2、动态路由传参
// 简单写法
this.$router.push('/路径/参数值')
// 完整写法
this.$router.push({path: '/路径/参数值'
})
2)name命名路由

适合 path 路径长的场景

不传参:

路由规则,必须配置name配置项

{ name: '路由名', path: '/path/xxx', component: XXX },

通过name来进行跳转

this.$router.push({name: '路由名'
})

传参:

// 1、query传参
this.$router.push({name: '路由名字',query: {参数名1: '参数值1',参数名2: '参数值2'}
})// 2、动态路由传参
this.$router.push({name: '路由名字',params: {参数名: '参数值',}
})

10、二级路由

const router = new VueRouter({routes: [{path: '/',component: Layout,children:[//children中的配置项 跟一级路由中的配置项一模一样 { path:'xxxx', component:xxxx.vue },{ path:'xxxx', component:xxxx.vue },]}]
})

这些二级路由对应的组件渲染到哪个一级路由下,children就配置到哪个路由下边

配置了嵌套路由,一定配置对应的路由出口,否则不会渲染出对应的组件

11、组件缓存

keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。

keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件中。

<template><div class="h5-wrapper"><keep-alive><router-view></router-view></keep-alive></div>
</template>

keep-alive的三个属性:

  1. include:组件名数组,只有匹配的组件会被缓存
  2. exclude:组件名数组,任何匹配的组件都不会被缓存
  3. max:最多可以缓存多少组件实例

keep-alive的两个生命周期钩子:

  1. activated 当组件被激活(使用)的时候触发 → 进入这个页面的时候触发
  2. deactivated 当组件不被使用的时候触发 → 离开这个页面的时候触发

十二、代码规范

1、VueCli 自定义创建项目

1、安装脚手架

npm i @vue/cli -g

2、创建项目

vue create demo

3、选自定义

4、选择配置

5、选择vue的版本

6、选择是否使用history模式

7、选择css预处理

8、选择eslint的风格

9、选择校验的时机

10、选择配置文件的生成方式

11、不保存预设

image-20230812214636401

2、ESlint代码规范及手动修复

ESLint:是一个代码检查工具,用来检查你的代码是否符合指定的规则(你和你的团队可以自行约定一套规则)。在创建项目时,我们使用的是 JavaScript Standard Style 代码风格的规则。

根据错误提示来一项一项手动修正。

如果你不认识命令行中的语法报错是什么意思,你可以根据错误代码去 ESLint 规则列表中查找其具体含义。

打开 ESLint 规则表,使用页面搜索(Ctrl + F)这个代码,查找对该规则的一个释义。

3、通过eslint插件来实现自动修正

  1. eslint会自动高亮错误显示
  2. 通过配置,eslint会自动帮助我们修复错误

十三、Vuex

1、Vuex 概述

Vuex 是一个 Vue 的 状态管理工具,状态就是数据。

Vuex 是一个插件,可以帮我们管理 Vue 通用的数据 (多组件共享的数据)

优点:

  • 共同维护一份数据,数据集中化管理
  • 响应式变化
  • 操作简洁 (vuex提供了一些辅助函数)

2、Vuex的使用

1、安装vuex

yarn add vuex@3
## npm i vuex@3

2、新建 store/index.js 专门存放 vuex

为了维护项目目录的整洁,在src目录下新建一个store目录其下放置一个index.js文件。

3、创建仓库 store/index.js

// 导入 vue
import Vue from 'vue'// 导入 vuex
import Vuex from 'vuex'// vuex也是vue的插件, 需要use一下, 进行插件的安装初始化
Vue.use(Vuex)// 创建仓库 store
const store = new Vuex.Store()// 导出仓库
export default store

4、在 main.js 中导入挂载到 Vue 实例上

import Vue from 'vue'
import App from './App.vue'
import store from './store'Vue.config.productionTip = falsenew Vue({render: h => h(App),store
}).$mount('#app')

3、state 状态

State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。

打开项目中的store.js文件,在state对象中可以添加我们要共享的数据。

// 创建仓库 store
const store = new Vuex.Store({// state 状态, 即数据, 类似于vue组件中的data,// 区别:// 1.data 是组件自己的数据, // 2.state 中的数据整个vue项目的组件都能访问到state: {count: 101}
})

访问Vuex中的数据

1、模板中使用

<h1>state的数据 - {{ $store.state.count }}</h1>

2、组件逻辑中使用

this.$store.state.xxx

3、js文件中使用

//main.jsimport store from "@/store"console.log(store.state.count)

4、提供计算属性

<h1>state的数据 - {{ count }}</h1>
// 把state中数据,定义在组件内的计算属性中
computed: {count () {return this.$store.state.count}
}

4、辅助函数mapState

mapState是辅助函数,帮助我们把store中的数据映射到 组件的计算属性中, 它属于一种方便的用法

1、导入mapState (mapState是vuex中的一个函数)

import { mapState } from 'vuex'

2、采用数组形式引入state属性

mapState(['count']) 

上面代码的最终得到的是 类似于

count () {return this.$store.state.count
}

3、利用展开运算符将导出的状态映射给计算属性

computed: {...mapState(['count'])
}
 <div> state的数据:{{ count }}</div>

5、严格模式和Vuex的单项数据流

明确 vuex 同样遵循单向数据流,组件中不能直接修改仓库的数据

通过 strict: true 可以开启严格模式,开启严格模式后,直接修改state中的值会报错。

state数据的修改只能通过mutations,并且mutations必须是同步的

6、mutations

1)mutations

mutations是一个对象,对象中存放修改state的方法。mutations必须是同步的。

1、定义mutations

const store  = new Vuex.Store({// 定义mutationsmutations: {}
})

2、组件中提交 mutations

this.$store.commit('addCount')
2)带参数的 mutations

1、定义mutations(带参数)

const store  = new Vuex.Store({addCount (state, count) {state.count = count}
})

2、组件中提交 mutations

this.$store.commit('addCount', 10)

提交的参数只能是一个,如果有多个参数要传,可以传递一个对象

this.$store.commit('addCount', {count: 10
})
3)mapMutations

mapMutations类似于mapState,把位于mutations中的方法提取了出来

import  { mapMutations } from 'vuex'
methods: {...mapMutations(['addCount'])
}

7、actions

1)actions

state是存放数据的,mutations是同步更新数据 (便于监测数据的变化,更新视图等,方便于调试工具查看变化)

actions则负责进行异步操作

1、

mutations: {changeCount (state, newCount) {state.count = newCount}
}actions: {setAsyncCount (context, num) {// 一秒后, 给一个数, 去修改 numsetTimeout(() => {context.commit('changeCount', num)}, 1000)}
}

2、组件中通过dispatch调用

setAsyncCount () {this.$store.dispatch('setAsyncCount', 666)
}

2)mapActions

mapActions 是把位于 actions中的方法提取了出来,映射到组件methods中

import { mapActions } from 'vuex'
methods: {...mapActions(['changeCountAction'])
}

8、getters

1)getters

除了state之外,有时我们还需要从state中筛选出符合条件的一些数据(类似于computed计算属性),这些数据是依赖state的,此时会用到getters

1、定义getters

getters: {// getters函数的第一个参数是 state// 必须要有返回值filterList:  state => state.list.filter(item => item > 5)
}

2、使用getters

<div>{{ $store.getters.filterList }}</div>
2)mapGetters
computed: {...mapGetters(['filterList'])
}
 <div>{{ filterList }}</div>

9、module模块化

1)module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

如果把所有的状态都放在state中,当项目变得越来越大的时候,Vuex会变得越来越难以维护

1、准备user模块 modules/user.js

const state = {userInfo: {name: 'zs',age: 18}
}const mutations = {}const actions = {}const getters = {}export default {state,mutations,actions,getters
}

2、在store/index.js文件中的modules配置项中,注册模块

import user from './modules/user'const store = new Vuex.Store({modules:{user}
})

数据的访问:

this.$store.state.模块名.xxx
2)state模块化

尽管已经分模块了,但其实子模块的状态,还是会挂到根级别的 state 中,属性名就是模块名

  1. 直接通过模块名访问 $store.state.模块名.xxx
  2. 通过 mapState 映射:
    1. 默认根级别的映射 mapState([ 'xxx' ])
    2. 子模块的映射 :mapState('模块名', ['xxx']) (需要开启命名空间namespaced:true
export default {namespaced: true,...
}
3)getters模块化
  1. 直接通过模块名访问 $store.getters['模块名/xxx ']
  2. 通过 mapGetters 映射
    1. 默认根级别的映射 mapGetters([ 'xxx' ])
    2. 子模块的映射 mapGetters('模块名', ['xxx']) (需要开启命名空间)
4)mutations模块化
  1. 直接通过 store 调用 $store.commit('模块名/xxx ', 额外参数)
  2. 通过 mapMutations 映射
    1. 默认根级别的映射 mapMutations([ 'xxx' ])
    2. 子模块的映射 mapMutations('模块名', ['xxx'])(需要开启命名空间)
5)actions模块化
  1. 直接通过 store 调用 $store.dispatch('模块名/xxx ', 额外参数)
  2. 通过 mapActions 映射
    1. 默认根级别的映射 mapActions([ 'xxx' ])
    2. 子模块的映射 mapActions('模块名', ['xxx']) (需要开启命名空间)

10、补:json-server

json-server用于模拟后端接口服务环境

1、安装全局工具 json-server (全局工具仅需要安装一次)

yarn global add json-server
npm i json-server -g

2、代码根目录新建一个 db 目录

3、将资料 index.json 移入 db 目录

4、进入 db 目录,执行命令,启动后端接口服务 (使用–watch 参数 可以实时监听 json 文件的修改)

json-server  --watch  index.json

十四、打包优化

1、publicPath

默认情况下,需要放到服务器根目录打开,如果希望双击运行,需要配置 publicPath 配成相对路径

module.exports = {// 设置获取.js,.css文件时,是以相对地址为基准的。// https://cli.vuejs.org/zh/config/#publicpathpublicPath: './'
}

2、路由懒加载

当打包构建应用时,Javascript 包会变得非常大影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

const ProDetail = () => import('@/views/prodetail')
const Pay = () => import('@/views/pay')
const MyOrder = () => import('@/views/myorder')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/623386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站万词霸屏推广系统源码:实现关键词推广,轻松提高关键词排名,带完整的安装部署教程

现如今&#xff0c;互联网的快速发展&#xff0c;网站推广成为企业网络营销的重要手段。而关键词排名作为网站推广的关键因素&#xff0c;一直备受关注。罗峰给大家分享一款网站万词霸屏推广系统源码&#xff0c;该系统可实现关键词推广&#xff0c;有效提高关键词排名&#xf…

【教3妹学编程-算法题】回文串重新排列查询

3妹&#xff1a;好冷啊&#xff0c; 冻得瑟瑟发抖啦 2哥 : 这已经是你今年的第几次抖啦&#xff1f; 3妹&#xff1a;昨天20度&#xff0c;今天7度&#xff0c;直降13度呢&#xff0c;能不抖嘛 2哥 : 继哈尔滨之后&#xff0c;全国各地的城市也在发展旅游业。 河北喊话赵丽颖回…

使用mamba替换conda和anaconda配置环境安装软件

使用mamba替换miniconda和anaconda&#xff0c;原因是速度更快&#xff0c;无论是创建新环境还是激活环境 conda、mamba、anaconda都是蟒蛇的意思… 下载mambaforge wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh ba…

乐意购项目前端开发 #3

一、icon的使用 前往网站挑选要的图标 iconfont-阿里巴巴矢量图标库https://www.iconfont.cn/?spma313x.manage_type_myprojects.i3.2.2f173a81fQSVOU 创建项目添加图标 选择Font Class 下载到本地 解压后会看到这个页面 在asserts目录下创建iconfont目录,然后将最底下的6…

数据库第一次作业

1.创建一个英雄表 create table t_hero ( id int primary key auto_increment, name varchar(10) unique not null, gender char(5) check (gender in (男,女)), grade char(5) default 5星, groups char(5) check (groups in (毁灭,巡猎,智识,存护,…

GPT与文心一言大模型的比较与展望

目录 前言1 GPT和文心一言简介2 GPT和文心一言的技术原理和基础架构3 GPT和文心一言的模型规模和参数数量4 GPT和文心一言的语言理解表现5 展望GPT和文心一言未来的发展5.1 技术改进5.2 应用扩展 结语 前言 随着人工智能技术的飞速发展&#xff0c;自然语言处理领域的两个引领…

swing快速入门(四十四)拖动、编辑JTree结点

注释很详细&#xff0c;直接上代码 新增内容&#xff08;源码细节知识点巨多&#xff0c;建议细看&#xff09; 1.设置JTree可编辑 2.使用JTree关联的数据模型实现节点的增删改 3.鼠标拖动节点事件设计及处理方法 4.手动刷新视图与自动刷新的方法区别 5.自定位节点视图方法 源码…

linux环境中一次启动多个jar包,并且设置脚本开机自启

1、编写启动脚本 我们在通过jar启动项目时&#xff0c;有时候会比较多&#xff0c;启动会比较麻烦&#xff0c;需要编写shell脚本启动&#xff0c;将启动脚本存放在需要启动的jar包路径下。&#xff08;文档存放在 /home/process_parent &#xff09; vim start.sh#! /bin/sh…

【python】11.文件和异常

文件和异常 实际开发中常常会遇到对数据进行持久化操作的场景&#xff0c;而实现数据持久化最直接简单的方式就是将数据保存到文件中。说到“文件”这个词&#xff0c;可能需要先科普一下关于文件系统的知识&#xff0c;但是这里我们并不浪费笔墨介绍这个概念&#xff0c;请大…

Vue报错 Cannot find module ‘../../modules/es6.symbol‘解决办法

在进行webpack打包的时候&#xff0c;会出现Cannot find module XXX’的错误&#xff0c;找不到某个模块的错误&#xff0c;今天给出解决方法&#xff1a; 直接进行npm install重新打包&#xff1b;如果npm install重新打包之后&#xff0c;仍然出现这个问题&#xff0c;可以进…

NLP论文阅读记录 - 2021 | WOS 智能树提取文本摘要深度学习

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.前提三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 An Intelligent Tree Extractive Text Summarization Deep Learning …

迁移mysql8.x数据到monggodb数据库

因流量逐步增加随即数据库要从mysql换成monggodb&#xff0c;所以有了数据迁移的需求 首先需要导出mysql的数据&#xff0c;导出格式为.CSV的文件 使用navicat链接mysql数据库注意&#xff0c;需要使用拥有所有权限的用户 登录mysql mysql -u root -pZxcvbnm2024 CREATE USER …

实战指南:如何在Spring Boot中无缝整合Dubbo【四】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 实战指南&#xff1a;如何在Spring Boot中无缝整合Dubbo【四】 前言项目结构主项目(作为主pom)接口服务提供者properties文件实现类 服务消费者properties接口层 实现效果图 前言 微服务架构已经成为…

BUUCTFMisc (我flag呢???)

刚好&#xff0c;更完密码学&#xff0c;然后就到下一个对新手还算 “友好” 的地方了--->Misc&#xff08;但他还是比密码学难&#xff09; 找不出flag belike &#xff1a; 看了别人的找法以后be like&#xff1a; 这里我就来讲几道我觉得比较有意思的题目吧&…

python 字符串的详细处理方法

当前版本&#xff1a; Python 3.8.4 简介 字符串是由字符组成的序列&#xff0c;可以用单引号、双引号或三引号&#xff08;单引号或双引号的连续使用&#xff09;括起来。一般用来表示和处理文本信息&#xff0c;可以是字母、数字、标点符号以及其他特殊字符&#xff0c;用于…

CAN/CANFD数据记录仪汽车电子售后神器

CAN数据记录仪是一种用于采集和存储CAN总线数据的工具&#xff0c;广泛应用于汽车、轨道车辆、工业控制等大数据量且不易排查故障的系统中。它可以实时存储总线上的数据&#xff0c;方便后续的研究和分析。解决工程师售后难点。 在选择CAN数据记录仪时&#xff0c;需要根据实…

春节回家前,请一定给你的电脑装上KKView远程控制软件

马上春节了&#xff0c;电脑不能带回家&#xff0c;有时候要处理点意外的事情&#xff0c;怎么办&#xff1f;只要走之前&#xff0c;给你电脑装上KKView远程控制软件&#xff0c;就可以随时随地用手机或电脑控制你的工作电脑&#xff0c;远程办公、传文件、看摄像头都没问题。…

2024.1.15每日一题

LeetCode 82.删除排序链表中的重复元素 II 82. 删除排序链表中的重复元素 II - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例…

docker安装部署Elasticsearch(ES)以及相关配置

Elasticsearch简介 mysql用作持久化存储&#xff0c;ES用作检索 基本概念&#xff1a;index库>type表>document文档 index索引&#xff08;相当于MySQL的数据库&#xff09; 动词&#xff1a;相当于mysql的insert 名词&#xff1a;相当于mysql的db Type类型&#xff…

Jenkins-自动化

定时构建 使用Cron表达式指定执行时间。 # 格式 # ┌──分&#xff08;0 - 59&#xff09; # │ ┌──时&#xff08;0 - 23&#xff09; # │ │ ┌──日&#xff08;1 - 31&#xff09; # │ │ │ ┌─月&#xff08;1 - 12&#xff09; # │ │ │ │ ┌─星期&#…