1、npm install -g @vue/cli
2、vue create my-app
3、cd my-app
4、npm run serve
1、插槽:可以设置自定义样式
`
xxx.vue中书写
{{item}}
应用:在相应的组建中书写
`
1、属性:
自定义属性props:组件props中声明的属性
props:['name','type','list']
或者:
name:String,
type:{
validator:function(value){
return ['success','warning','danger'].includes(value)
}
},
list:{
type:Array,
default:() => []
}
原生属性attr: 没有声明的属性,默认自动挂载到组件根元素上,设置inheritAttrs为false可以关闭自动挂载
特殊属性class、style:挂载到组件根元素上,支持字符串、对象、数组等多种语法
2、事件:
普通事件:@click @input @change @xxx等事件,通过this.$emit('xxx',...)触发
handleChange(e){
this.$emit('change',e.target.value)
}
修饰符事件:@input.trim @click.stop @submit.prevent等,一般用于原生HTML元素,自定义组件需要自行开发支持
3、插槽:
普通插槽:... 或者 ...
作用域插槽:...
...
对应插槽组件应用:
大属性的应用:
export default {
components:{
VNodes:{
function: true,
render:(h,ctx) => ctx.props.vnodes
}
},
}
Vue是单向数据流,不是双向绑定
Vue的双向绑定不过是语法糖
Object.defineProperty是用来做响应式更新的,和双向绑定没关系
v-model语法糖:
(phoneInfo = val)'
:zip-code='zipCode'
@updata:zipCode='val => (zipCode = val)'
/>
1、数据驱动:操作虚拟DOM
2、数据来源(单向的)
来自父元素的属性
来自组件自身的状态 data
来自状态管理器,如vuex Vue.observable
3、数据响应式更新
必备条件:
(1)template模板中应用了此数据、
(2)data return中返回了相应的字段。
如template模板中应用了{{msg.name}},
并且data return回来的数据中声明了 msg:{name:null,info:null},这样才能实现响应式更新
1、计算属性computed
减少模板中逻辑运算
数据缓存
依赖固定的数据类型(响应式数据)
2、侦听器 watch
更加灵活、通用
watch中可以执行任何逻辑,如函数节流,Ajax异步获取数据,甚至操作DOM
3、computed vs watch
computed能做的,watch都能做,反之则不行
能用computed的尽量用computed
1、生命周期:
创建阶段:
初始化事件和生命周期 ->
beforeCreate ->
数据观测、属性、侦听器配置等 ->
created ->
编译到render ->
beforeMount ->
render ->
mounted ->
异步请求、操作DOM、定时器等(以来this.$nextTick(()=>)事件对子组件进行监听、更新)
更新阶段:
依赖数据改变或者$forceUpdate强制刷新 ->
beforeUpdate ->
移除已经添加的事件监听器等 万万不可更改依赖数据 ->
render ->
updated ->
操作DOM添加事件监听器等 万万不可更改依赖数据等(以来this.$nextTick(()=>)事件对子组件进行监听、更新)
销毁阶段:
beforeDestroy -> 移除已经添加的事件监听器,计时器等 -> destroyed
2、函数式组件:
functional:true
无状态、无实例、没有this上下文、无生命周期
应用:
组建中tempvar.js文件中
export default {
functional: true,
render: (h,ctx) => {
return ctx.scopedSlots.default && ctx.scopedSlots.default(ctx.props || {})
}
}
index.vue应用函数式组件
{{var1}} {{var2}}
1、内置指令:v-text v-html v-show v-model v-if 等等 语法糖、标志位
2、自定义指令:
生命周期钩子:
bind
inserted
update
componentUpdated
unbind
1、通过provide 和 inject 实现跨组件传值 可使用API Vue.observable优化响应式provide
例如:A B C之间,A直接传值给C,就可以采用provide和inject实现
A组件中:
export default {
provide(){
//监听整个this上绑定的属性,即可实现响应式更新,否则若是color值没有在组件中应用,就不能实现响应式更新
return {
theme:{
this
}
}
},
data(){
return {
color:'blue'
}
}
}
C组件中:
C节点
export default {
inject:{
theme:{
default:() => ({}) //默认使用传过来的theme的值
}
}
}
1、ref 引用信息: this.$refs.name获取组件实例信息 获取当前页面的组件信息
2、递归查找 : 代码繁琐、性能低效
3、callback ref :主动通知(serXXXRef) 主动获取(getXXXRef)
例如:A节点中:绑定自定义的跨组件传值方法
export default {
provide(){
setChildrenRef:(name, ref) => {
this[name] = ref
},
getChildrenRef: name => {
return this[name]
},
getRef: () => {
return this
}
},
}
C节点中:insert中绑定相应的传值方法
export default {
inject: {
setChildRef:{
default:() => {}
}
}
}
1、template:
模板语法(HTML的扩展)
数据绑定使用Mustache语法(双大括号)
Message:{{msg}}
特点:
学习成本低、大量内置指令简化开发、组件作用域css、but灵活性地
2、JSX:
JavaScript的语法扩展
数据绑定使用单引号
Message:{msg}
特点:灵活
3、更抽象一点来看,我们可以把组件区分成两类:一类是偏视图表现的,一类则是偏逻辑的。我们推荐在前者中使用模板,在后者中使用JSX或渲染函数。这两类组件的比例会根据应用类型的不同有所变化,但整体来说我们发现表现类的组件远远多于逻辑类组件 --Vue官方文档
1、子组件修改传入的值,为什么vue中有提示:
Object.defineProperty() 底层原理控制,若子组件直接修改父组件内容,会触发底层原理为true的事件,导致vue中警告,若是将改变让父组件触发,即通过$emit(‘change’,e.target.value)事件发从给父组件,从而改变绑定的值
2、this.$emit的返回值是什么:
是this,若需要传递参数,则使用callback函数将参数返回
this.$emit('change',e.target.value,val => {
console.log(val)
})
handleEventChang(val,callback){
this.name = val
callback('hello')
}
3、相同名称的插槽是合并还是替换:
目前2.6版本以上都是替换,之前是合并
4、为什么不能用index作为key
更新DOM性能问题以及会引入状态bug问题
5、数组有哪些方法支持响应式更新,如果不支持如何处理,底层原理如何实现的
支持:push() pop() shift() unshift() splice() sort() reverse()
不支持:filter() concat() slice()
原理同样是使用Object.defineProperty对数组方法进行改写