Cat73 Blog

喵星人占领地球战略指挥部

0%

Vue 学习笔记

前言

此文章用于学习Vue相关技术时记录笔记

由于模板冲突,可能存在部分内容显示异常的问题

基础

生命周期

模板

插值

  • 文本
    <span>{{ msg }}</span>
  • html(注意 XSS 风险)
    <span v-html="rawHtml"></span>
  • 绑定属性
    <span v-bind:id="dynamicId">123456</span>
    <span v-on:click="doSomething">123456</span>
  • 绑定动态名称的属性(注意,名称对应的数据必须全部小写)
    <span v-bind:[attrName]="dynamicValue">123456</span>
    <span v-on:[eventName]="doSomething">123456</span>
  • 表达式支持
    <span>{{ msg + '.' }}</span>
    <span>{{ flag ? 1 : 2 }}</span>
  • 表达式是在沙盒中运行的,只能访问白名单中的全局变量

Class 和 Style 绑定

TODO

事件

<span @click="fn">123456</span>
<span @click="fn(row)">123456</span>
<span @click="fn(row, $event)">123456</span>
<input @keyup.enter="fn" />
<input @keyup.ctrl.enter="fn" /> <!-- 组合键 -->
<input @click.ctrl="fn" /> <!-- 按下 Ctrl 时点击 -->
<input @click.ctrl.exact="fn" /> <!-- Ctrl 和其它修饰键同时按下时不触发 -->
<input @click.exact="fn" /> <!-- 只有未按下任何修饰键时才触发 -->

在事件后增加修饰符可以自动调用一些处理
修饰符可以存在多个,且会按顺序执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 阻止事件继续传播 -->
<span @click.stop="fn">123456</span>

<!-- 阻止默认行为 -->
<span @click.prevent="fn">123456</span>

<!-- 在捕获阶段处理事件 -->
<span @click.capture="fn">123456</span>

<!-- 只有 event.target 是自身元素时才处理事件 -->
<span @click.self="fn">123456</span>

<!-- 只会触发一次 -->
<span @click.once="fn">123456</span>

<!-- 阻止处理代码调用 preventDefault,如果真的调用了,将只会在控制台打印警告 -->
<span @click.passive="fn">123456</span>

缩写

v-bind:href=”xxx” 可简写为 :href=”xxx”
v-on:click=”xxx” 可简写为 @click=”xxx”

属性

计算属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div>
<p>{{ msg }}</p>
<p>{{ reversedMsg }}</p>
</div>

<script>
new Vue({
data() {
return {
msg: '123'
}
},
computed: {
reversedMsg() {
return this.msg.split('').reverse().join('')
}
}
})
</script>

指令

  • v-if 当条件成立时才插入元素
    • 切换状态开销大于 v-show
  • v-else-if 在上一个条件不成立,且这一个条件成立时插入元素
  • v-else 当条件不成立时插入元素
  • v-show 只有条件成立时显示元素
    • 初始化开销大于 v-if
  • v-for 循环渲染多个元素
    • v-for="(item, index) in list"
    • v-for="(value, name, index) in object"
    • 可以用 :key 提示 Vue 节点和数据的绑定关系,一般应该使用字符串或数字
    • 由于 JS 的限制,Vue 无法检测到下列变动
      • list[x] = newVal
      • list.length = newLength
      • obj.b = 1 // 创建以前不存在的属性
  • v-model 将某个属性绑定到元素上
    • v-model.number 自动在写回属性时转换为 Number
    • v-model.trim 自动在写回属性时去掉首尾的空白字符

如果需要,可以给计算属性设置 setter

1
2
3
4
5
6
7
8
9
10
computed: {
reversedMsg: {
get() {
return this.msg.split('').reverse().join('')
},
set(newVal) {
this.msg = newVal.split('').reverse().join('')
}
}
}

监听属性变化

1
2
3
4
5
6
7
8
9
10
11
12
new Vue({
data() {
return {
msg: '123'
}
},
watch: {
msg(newVal, oldVal) {
// do something
}
}
})

Vuex

Store(仓库)用于存储 State(状态),状态变化会关联影响组件
不能直接修改 Store 中的状态,改变状态的唯一途径是显示的 Commit(提交) mutation,它非常类似于事件,它会接收state作为第一个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 创建仓库
const store = new Vuex().Store({
state: {
count: 0
},
mutations: {
inc (state, n) {
state.count += n
}
}
})

// 提交,触发更变
store.commit('inc', 5)

在将 Vuex 注入到 Vue 后,可以在组件中直接用this.$store来访问 Store 对象
可以通过mapState辅助生成计算属性,来方便的将状态绑定到计算属性上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { mapState } from 'vuex'

export default {
computed: mapState({
count: state => state.count,
// 别名
countAlias: 'count',
// 为了使用 this,必须使用常规函数
countPlusLocalState(state) {
return state.count + this.localCount
},
// 计算属性名和 state 中属性名相同时,可直接传给 mapState 一个字符串
'prop01'
})
}

将 mapState 和局部计算属性混合使用

1
2
3
4
5
6
7
8
import { mapState } from 'vuex'

export default {
computed: {
localComputed() { /* ... */ },
...mapState({ /* ... */ })
}
}

当需要对属性做一些计算后再返回时,为了不在每个组件都写一次代码,可以用 getter

1
2
3
4
5
6
7
8
9
10
const store = new Vuex.Store({
state: {
count: 1
},
getters: {
prop1: (state, getters) => state.count + 1
// 传参访问
prop2: (state) => (num) => state.count + num
}
})

用 mapGetters 可以将 getter 映射到计算属性中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { mapGetters } from 'vuex'

export default {
computed: {
localComputed() { /* ... */ },
...mapGetters({
renameProp: 'prop1'
}),
...mapGetters([
'prop1',
'prop2'
])
}
}

参考资料