查漏补缺方为上策!!两万六字总结vue的基本使用和高级特性,周边插件vuex和vue-router任你挑选
Posted 星期一研究室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了查漏补缺方为上策!!两万六字总结vue的基本使用和高级特性,周边插件vuex和vue-router任你挑选相关的知识,希望对你有一定的参考价值。
vue的基本使用和高级特性,周边插件vuex和vue-router
以下文章将讲解对 vue
的基本使用以及各种高级特性还有周边插件 vuex
和 vue-router
,融合大量案例🌰和动图🕹️进行展示。可以把它当成是 vue
的入门宝库,有不懂的语法知识点时或许在这里可以寻找到你的答案并且通过例子运用起来。
废话不多说,下面来开始探索 vue
的奥秘吧🙆
一、vue的使用
1、vue-cli
vue
项目是基于 vue-cli
脚手架搭建的项目。当我们要创建一个项目时,首先要先全局安装 vue-cli
脚手架,命令行为:
npm i -g @vue/cli
在搭建完成项目以后,我们需要来了解 src
目录下各个文件夹和文件的用法。
├── assets 放置静态资源
├── components 放组件
├── router 定义路由的相关配置
├── views 视图
├── views 视图
├── app.vue 应用主组件
├── main.js 入口文件
2、基本使用
(1)模板(插值,指令)
1)插值、表达式
<template>
<div>
<p>文本插值 {{message}}</p>
<p>JS 表达式 {{ flag ? 'yes' : 'no' }} (只能是表达式,不能是 js 语句)</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'I am Monday.',
flag: true
}
}
}
</script>
//浏览器显示结果
// 文本插值 I am Monday.
// JS 表达式 yes
2)动态属性
<template>
<div>
<p :id="dynamicId">动态属性:{{dynamicId}}</p>
</div>
</template>
<script>
export default {
data() {
return {
dynamicId: `id-${Date.now()}`
}
}
}
</script>
//浏览器显示结果
//动态属性:id-1622339576875
3)v-html指令
<template>
<div>
<p v-html="rawHtml">
<span>有 xss 风险</span>
<span>【注意】使用 v-html 之后,将会覆盖子元素</span>
</p>
</div>
</template>
<script>
export default {
data() {
return {
rawHtml: '指令 - 原始 html <b>加粗</b> <i>斜体</i>',
}
}
}
</script>
//浏览器显示结果
//指令 - 原始 html 加粗 斜体
值得注意的是, v-html
指令会有 xss
风险,且会覆盖子组件,要谨慎使用!!
(2)computed和watch
1)computed
computed
有缓存, data
不变则不会重新计算。如下代码所示:
<template>
<div>
<p>num {{num}}</p>
<p>double1 {{double1}}</p>
//用v-model一定要有get和set,否则会报错
<input v-model="double2"/>
</div>
</template>
<script>
export default {
data() {
return {
num: 20
}
},
computed: {
double1() {
return this.num * 2
},
double2: {
// 获取值
get() {
return this.num * 2
},
// 设置值
set(val) {
this.num = val/2
}
}
}
}
</script>
此时浏览器的打印结果如图所示。
大家可以看到,当 num
的值如果一直是 20
的值时,那么 double1
和 double2
的 get()
方法是不会重新计算的,它会被缓存下来,达到提高运算性能的效果。
2)watch
watch
监听基本数据类型时,可正常拿到oldVal
和val
的值。watch
如果监听引用数据类型时,需要进行深度监听,且拿不到oldVal
。因为指针相同,监听时,指针已经指向了新的val
。
如下代码所示:
<template>
<div>
<input v-model="name"/>
<input v-model="info.city"/>
</div>
</template>
<script>
export default {
data() {
return {
name: 'Monday',
info: {
city: 'FuZhou'
}
}
},
watch: {
name(oldVal, val) {
// eslint-disable-next-line
console.log('watch name', oldVal, val) // 值类型,即基本数据类型,可正常拿到 oldVal 和 val
},
info: {
handler(oldVal, val) {
// eslint-disable-next-line
console.log('watch info', oldVal, val) // 引用数据类型,拿不到 oldVal 。因为指针相同,此时已经指向了新的 val
},
deep: true // 深度监听
}
}
}
</script>
(3)class和style
-
使用动态属性,即
v-bind
绑定; -
使用驼峰式写法。
如下代码所示:
<template>
<div>
<p :class="{ black: isBlack, yellow: isYellow }">使用 class</p>
<p :class="[black, yellow]">使用 class (数组)</p>
<p :style="styleData">使用 style</p>
</div>
</template>
<script>
export default {
data() {
return {
isBlack: true,
isYellow: true,
black: 'black',
yellow: 'yellow',
styleData: {
fontSize: '40px', // 转换为驼峰式
color: 'red',
backgroundColor: '#ccc' // 转换为驼峰式
}
}
}
}
</script>
<style scoped>
.black {
background-color: #999;
}
.yellow {
color: yellow;
}
</style>
此时浏览器的显示效果如下。
(4)条件
v-if
、v-else
的用法:可使用变量,也可以使用 === 表达式。v-if
和v-show
的区别?v-if
会根据条件对元素进行渲染的控制,此处的控制渲染指的是将元素添加到dom
中或移除dom
,所以会存在dom的增删。假设页面初始化时,条件判断结果为false
,则不会将该元素添加到dom
当中。v-show
与v-if
不一样的是,不管条件是true
还是false
,都会将对应的元素添加到dom
中,在条件为false
时将元素的css
属性display
设置为none
,所以我们只是肉眼看到元素从页面中消失了,但是它还存在于dom
当中。
v-if
和v-show
的使用场景?v-if
适用于条件变化频率不高的时候,这样不会频繁的去对DOM
进行增删操作;v-show
适用于需要做频繁切换的时候,比如说A和B两个元素,需要一会显示A
,一会显示B
,这样就算比较频繁。如果去操作v-if
,让DOM
疯狂的增添和销毁是会非常耗费性能的,所以这个时候就应该用v-show
,display
属性原本就已经存放在DOM
当中,只是对display
属性进行修改修做即可。
具体使用方式如下代码所示:
<template>
<div>
<p v-if="type === 'a'">A</p>
<p v-else-if="type === 'b'">B</p>
<p v-else>other</p>
<p v-show="type === 'a'">A by v-show</p>
<p v-show="type === 'b'">B by v-show</p>
</div>
</template>
<script>
export default {
data() {
return {
type: 'a'
}
}
}
</script>
(5)循环(列表)渲染
-
vue
中如何遍历对象? —— 使用v-for
。 -
v-for
和v-if
不能一起使用。 -
key
的重要性。在对数据进行v-for
遍历时,需要加上key
值来保证数据的唯一性。同时,key
不能乱写,一般不要使用random
或者index
,而是绑定一个与该绑定数据相关的唯一值来确定。如果用random
或者index
时,在对数据进行删除或增添操作时,有可能会出现数据错乱等问题出现。 -
key
的作用。在对节点进行diff
的过程中,判断两个节点是否为相同节点的一个很重要的条件就是key
值是否相等,如果key
值相等,则说明两个节点是相同节点,所以会尽可能的复用原有的DOM
节点,减少不必要的DOM
操作,提升系统性能。
下面用一段代码演示 v-for
遍历数组和遍历对象时的效果。
<template>
<div>
<p>遍历数组</p>
<ul>
<li v-for="(item, index) in listArr" :key="item.id">
{{index}} - {{item.id}} - {{item.title}}
</li>
</ul>
<p>遍历对象</p>
<ul >
<li v-for="(val, key, index) in listObj" :key="key">
{{index}} - {{key}} - {{val.title}}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
listArr: [
{ id: 'a', title: '今天周一' }, // 在数据结构中,最好有 id ,目的是为了方便使用 key
{ id: 'b', title: '今天周二' },
{ id: 'c', title: '今天周三' }
],
listObj: {
a: { title: '今天周一' },
b: { title: '今天周二' },
c: { title: '今天周三' },
}
}
}
}
</script>
此时浏览器的显示效果如下所示:
(6)事件
1)event参数,自定义参数
下面通过绑定一个两个按钮事件,来观察 vue
中的事件,参数时怎么进行传递的,事件又会被绑定到哪里去?
<template>
<div>
<!-- <p>{{num}}</p> -->
<!-- event参数 -->
<button @click="increment1">+1</button>
<!-- 自定义参数 -->
<button @click="increment2(2, $event)">+2</button>
<div>递增值:{{num}}</div>
</div>
</template>
<script>
export default {
data() {
return {
num: 0
}
},
methods: {
increment1(event) {
console.log('event', event, event.__proto__.constructor) // 是原生的 event 对象
console.log(event.target) //vue中的event,放在什么元素下,就会被挂载在什么元素下
console.log(event.currentTarget) // 注意,事件是被注册到当前元素的,和 React 不一样
this.num++
// 1. event 是原生的
// 2. 事件被挂载到当前元素
// 和 DOM 事件一样
},
increment2(val, event) {
console.log(event.target)
this.num = this.num + val
}
}
}
</script>
大家可以看到,上面的 increment1
方法,没有传递参数,则它可以直接使用 event
来触发当前对象;而 increment2
方法中,通过传递了一个 2
的参数,我们可以通过 $event
的方式,把 2
传递进来,之后同样用 event
触发原生对象。
同时,当触发到当前元素时,事件会被挂载到当前元素,和 DOM
事件一样。
此时浏览器的打印效果如下:
2)自定义事件
上面的演示中, vue
事件是直接挂载到 vue
上面进行监听的。而下面的代码中,我们可以看到,如果我们需要自定义一个事件,而不进行直接挂载,则可以通过 addEventListener
来进行注册。
但值得注意的是,用 vue
绑定的事件,组件销毁时会自动进行解绑。但是呢,如果是自己定义的事件,需要自己再进行手动销毁!!这一点需要特别注意,不然写代码过程很容易因为没有销毁热导致后面引发的一系列 bug
出现。
<template>
<div>
</div>
</template>
<script>
export default {
data() {
return {
num: 0
}
},
methods: {
loadHandler() {
// do some thing
}
},
mounted() {
window.addEventListener('load', this.loadHandler)
},
beforeDestroy() {
//【注意】用 vue 绑定的事件,组建销毁时会自动被解绑
// 但如果是,自己绑定的事件,需要自己销毁!!!
window.removeEventListener('load', this.loadHandler)
}
}
</script>
3)事件修饰符
对于 vue
来说,经常用到的修饰符有下面6种事件修饰符和3种按键修饰符。
<!-- 事件修饰符 -->
<!-- 阻止单击事件继续传播 -->
<a v-on:stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<!-- 按键修饰符 -->
<!-- 即使Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有ctrl被按下时候才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click,exact="onClick">A</button>
(7)表单
在vue项目中,主要使用 v-model
指令在表单 input
、 textarea
、 checkbox
、 radio
、 select
等元素上创建双向数据绑定。
对于 v-model
来说,常见的修饰符有 trim
、 lazy
和 number
。 trim
表示去除输入内容前后的空格, lazy
表示需要按回车键数据才会进行创建, number
表示把用户输入的值转换为 number
类型,如果先输入字符,则整串数据都会被当成字符串 string
类型看待,如果先输入数字,后输入字母,则后面的字母无法输入到输入框当中。
接下来我们用代码演示一遍常见的表单。
<template>
<div>
<p>输入框: {{name}} {{age}}</pwebpack5 查漏补缺