无论我们的组件props属性写成数组还是对象,vue都会帮我们把属性值转化为{type: val}的形式。
function normalizeProps (options: Object, vm: ?Component) {
const props = options.props
if (!props) return
const res = {}
let i, val, name
if (Array.isArray(props)) {
i = props.length
while (i--) {
val = props[i]
if (typeof val === 'string') {
name = camelize(val)
res[name] = { type: null }
} else if (process.env.NODE_ENV !== 'production') {
warn('props must be strings when using array syntax.')
}
}
} else if (isPlainObject(props)) {
for (const key in props) {
val = props[key]
name = camelize(key)
res[name] = isPlainObject(val)
? val
: { type: val }
}
} else if (process.env.NODE_ENV !== 'production') {
warn(
`Invalid value for option "props": expected an Array or an Object, ` +
`but got ${toRawType(props)}.`,
vm
)
}
options.props = res
}
将所有子组件的props属性写成如下形式,免去vue内部的转换,并可以校验我们的传值是否正确。
props: {
[propName]: {
type: val,
default: val,
...
}
}
props: {
start: {
type: Date,
default: example;
},
},
},
报错 Invalid default value for prop "slides": Props with type Object/Array must use a factory function to return the default value.
// 数组/对象的默认值应当由一个工厂函数返回
props是date类型 不能直接赋值,因此改为
props: {
start: {
type: Date,
default() {
return example;
},
},
},
v-modal
会在组件内对传入值进行突变。
采用$emit
方式,通过事件抛给父组件处理,简写为.sync
。
是否可以替代v-modal
。
$refs
生效时机经过测试,$refs
最早在mounted
中生效。
在搜索框中进行学生报告的搜索,对应会显示该学生的学生报告。报告信息中有一项是学生课堂表现精彩瞬间的轮播图,由swiper实现。出现问题:刷新后第一个学生的精彩瞬间显示正常,接着搜索第二个学生的报告时,精彩瞬间的第一张图片是第一个学生的。
(1)查看后端返回数据是否正常:正常。 (2)watch做深度的监听,看返回的图片路径是否进行更换:更换。
vue-awesome-swiper 这个组件本身的问题
在每次切换学生报告的时候做swiper组件的重新渲染。用v-if做一个状态的判断。
// 结束端口号的校验,为空或小于起始端口号的时候使结束端口号的值等于起始端口号的值
startPort: [
{
required: true,
type: 'number',
validator: (rule, value, callback) => {
if (!Number.isInteger(+this.form.startPort) || !Number.isInteger(+this.form.endPort)){
callback(new Error('取值范围为1到65535的整数,结束端口不能小于起始端口'));
}
if (!this.form.endPort || this.form.endPort < this.form.startPort) {
this.form.endPort = this.form.startPort;
}
callback();
},
trigger: 'blur',
},
],
改为:
startPort: [
{
required: true,
type: 'number',
validator: (rule, value, callback) => {
if (!Number.isInteger(+this.form.startPort) || !Number.isInteger(+this.form.endPort)){
callback(new Error('取值范围为1到65535的整数,结束端口不能小于起始端口'));
}
if (!this.form.endPort || this.form.endPort < this.form.startPort) {
this.$nextTick(() => {
this.form.endPort = this.form.startPort;
});
}
callback();
},
trigger: 'blur',
},
],
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
对结束端口号进行判断:对结束端口号的值进行判断,在小于起始端口号的值或是为空时,校验要让结束端口号等于起始端口号的值。在结束端口号与起始端口号值相同时,删除结束端口号为空。再次校验时,在未加this.$nextTick()前,结束端口号的数据更新了,但是视图上的结束端口号的内容仍为空。
https://cn.vuejs.org/v2/guide/reactivity.html#异步更新队列
watch: {
inputValues: {
handler: 'getData',
immediate: true,
deep: true,
}
}
immediate
属性可以使handler在组件创建时立即执行一次,但是要避免有数据依赖created
和mounted
。
deep
属性可以使该监听器监听对象中属性的变化。
在mounted之后再传入menu数组,在nextTick中调用updateActiveName即可。
由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
可以使用 Vue.set(object, key, value)
方法将响应属性添加到嵌套的对象上
或可以使用 vm.$set
实例方法
向一个已有对象添加多个属性,可以创建一个新的对象,让它包含原对象的属性和新的属性:
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
// 代替 Object.assign(this.someObject, { a: 1, b: 2 })
this.$set(array, index, val); 对于数组,是用splice方法实现的 this.$set(object, property, val); 对于该属性已经在对象上有定义的,那么只需要直接设置该属性的值即可,这将自动触发响应,因为已存在的属性是响应式的 对于给对象添加一个全新属性的,用dep.notify() 触发响应。这就是添加全新属性触发响应的原理。
也可以用于强制替换元素/组件而不是重复使用它。
<zoom-element-tool :zoom="zoom" :key="fragment.source" view-height="800px" />
当组件中的key属性发生变化的时候会完整地触发组件的生命周期钩子,所以需要reload时可以用key实现。