Vue开发Tips与知识点整理

积小流,成江海

props的命名与使用

props属性中 html中 <template>模板中
username username username
userName或user-name user-name userName

单选框和多选框的封装

RizuUI中的单选和多选框使用如下方式封装

单选框

子组件封装

具体的代码中有可能添加额外的元素,不过重点关注input元素的属性即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<template>
<div>
<input type="radio" :id="label" :name="name" :value="label" v-model="model"/>
<label :for="label">
<slot></slot>
...
</label>
</div>
</template>
<script>
export default {
name: 'RadioComponent',
props: {
name: {
type: String,
required: true
},
label: {
required: true
},
value: {}
},
computed: {
model: {
get () {
return this.value
},
set (val) {
this.$emit('input', val)
}
}
}
}
</script>

在input元素上双向绑定的是一个计算属性”model”,由于v-model="val"相当于:value="val"@input="val = $event.target.value"的语法糖,因此上面的$emit中事件为”input”

父组件中调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div>
<RadioComponent name="fruit" label="Apple" v-model="rel">Apple</RadioComponent>
<RadioComponent name="fruit" label="Banana" v-model="rel">Banana</RadioComponent>
<RadioComponent name="fruit" label="Orange" v-model="rel">Orange</RadioComponent>
<span>Picked: {{ rel }}</span>
</div>
</template>
<script>
export default {
data () {
return {
rel: 'Banana'
}
}
}
</script>

多选框

子组件封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<template>
<div>
<input type="checkbox" :id="label" :name="name" :value="label" v-model="model"/>
<label :for="label">
<slot></slot>
...
</label>
</div>
</template>
<script>
export default {
name: 'CheckboxComponent',
props: {
name: {
type: String
},
label: {
required: true
},
value: {}
},
computed: {
model: {
get () {
return this.value
},
set (val) {
this.$emit('input', val) // 重要
}
}
}
}
</script>

父组件中调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
<CheckboxComponent label="yrq110" name="student" v-model="rel">YRQ110</CheckboxComponent>
<CheckboxComponent label="rizu" name="student" v-model="rel">RIZU</CheckboxComponent>
<span>Picked: {{ rel }}</span>
</div>
</template>
<script>
export default {
data () {
return {
rel: ['yrq110']
}
}
}
</script>

组件库插件的打包注册

这是RizuUI的打包与注册的方法,参考了iView等项目,感谢

我们知道,在编写一个Vue插件时,需要为对象添加install方法,在这个方法中可以添加全局方法、全局资源或者注入组件。由于在这里是一个组件库,因此需要在install方法中做的是注册组件库中的所有组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 导入组件
import RzAnima from './components/anima'
import RzButton from './components/button'
...
// 组件库对象
const rizu = {
RzAnima,
RzButton
...
}
// 创建install方法(遍历组件并注册)
const install = function (Vue, opts = {}) {
Object.keys(rizu).forEach((key) => {
Vue.component(key, rizu[key])
})
}
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
// 将install复制到组件库对象中
export default Object.assign(rizu, {install})

Vuex刷新后数据丢失问题

在写Bocs这个项目时发现,在跳转到列表页面或刷新列表页面时数据加载不出来,由于页面中的数据是从store中读取的,调试时发现每次跳转后或刷新后store中都没有数据

我的解决方案是在刷新或跳转时在created钩子中通过mutation或action将localStorage中所需数据写入store中即可,不过这种方法比较原始,也有一些其他方法可以解决

在操作localStorage时方便起见使用了一个库lockr

mutation:

1
2
3
4
5
6
7
8
...
[types.FLASH_BOOKS] (state) {
state.books = lockr.get('books')
},
[types.FLASH_PLANS] (state) {
state.plans = lockr.get('plans')
}
...

Vue.nextTick中的回调函数

在每次DOM更新后执行nextTick中的回调函数,为让这个回调函数延迟执行,vue优先用promise来实现,其次是html5的MutationObserver,然后是setTimeout。前两者属于microtask,后一个属于macrotask。

https://juejin.im/post/59b499e86fb9a00a4e677825

文章目录
  1. 1. props的命名与使用
  2. 2. 单选框和多选框的封装
    1. 2.1. 单选框
      1. 2.1.1. 子组件封装
      2. 2.1.2. 父组件中调用
    2. 2.2. 多选框
      1. 2.2.1. 子组件封装
      2. 2.2.2. 父组件中调用
  3. 3. 组件库插件的打包注册
  4. 4. Vuex刷新后数据丢失问题
  5. 5. Vue.nextTick中的回调函数
|