【前端框架】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…

python 八大排序_python-打基础-八大排序

## 排序篇 #### 二路归并排序 - 介绍 - 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列…

乐意购项目前端开发 #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;自然语言处理领域的两个引领…

linux报错bash: ./configure:/bin/sh^M:

bash: ./configure&#xff1a;/bin/sh^M&#xff1a;解释器错误: 没有那个文件或目录 用cat -A urfile时你可以看到这个\r字符被显示为^M&#xff0c;这时候只需要删除这个字符就可以了。可以使用命令sed -i s/\r$// urfile 。

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;请大…

动态规划算法的应用

动态规划算法的应用 LeetCode&#xff1a;一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 思考&#xff1a; /*** 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总…

为什么会被诊断为发作性睡病?

发作性睡病的诊断主要基于患者的症状和相关医学检查的结果。具体来说&#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 …

vue3-类与样式绑定

Class 与 Style 绑定 class 和 style 都是 attribute&#xff0c;我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。 Vue 专门为 class 和 style 的 v-bind 用法提供了特殊的功能增强。除了字符串外&#xff0c;表达式的值也可以是对象或数组。 绑定cla…

工智能基础知识总结--朴素贝叶斯

什么是朴素贝叶斯 朴素贝叶斯是基于贝叶斯定理与特征条件独立假设的分类方法。 给定训练集 T = ( x 1 , y 1 ) , ( x 2 , y 2 ) ,

Python 点云处理总目录

一、点云滤波 原始点云包含过多噪点和冗余点&#xff0c;滤波和采样往往是点云预处理的必要步骤 1.滤波 直通滤波 统计滤波 半径滤波 2.采样 下采样抽稀 二、邻近搜索 如何组织点云快速获取当前点邻域范围&#xff0c;是面对海量点云保证处理速度的重要前提 3.KD树与八…

linux如何创建文件教程分享

在Linux中创建文件通常通过使用命令行完成。这里有几种不同的方法来创建一个新文件&#xff1a; 1. 使用 touch 命令 touch 命令是最简单的创建空文件的方式。这个命令将更新文件的访问和修改时间戳。如果指定的文件不存在&#xff0c;它将创建一个空文件。 touch newfile.t…