1.基础
1. 理解mvvm
m 是vue实例中的data,自定义的数据或后端返回的数组 不是后端mvc里的model概念不同。 vm 是vue的实例 m和v之间的调度者 是mvvm的核心思想 v是 html 要渲染的。
2. 常用指令
v-cloak 解决{{}}插值闪烁问题 v-text 会先执行 覆盖 元素中原本的内容 但是插值表达式只会覆盖自己的占位符,默认不会闪烁 v-html 渲染 html标签 覆盖元素中原有元素内容 v-bind: 简写为: 用来绑定数据 可以写合法的js表达式 v-on: 简写为 @ 用来点击事件
3.常用事件修饰符
stop 阻止冒泡 :外层和里层都有方法 点击里层会产生冒泡,也会触发外层的事件。顺序 从里到外产生事件 prevent 阻止浏览器默认行为 :a标签有浏览器默认行为。 capture 捕获事件 :点击里层先触发外层再触发里层 顺序从外到里产生事件 self 只触发自己本身的事件 不会产生冒泡和捕获事件 类似于阻止冒泡 但只针对自己那一层 最外层还是会被最里层冒泡冒到 stop 是阻止所有层次 once 事件只执行一次
4.数据的绑定
v-bind: 数据的单向绑定 v-modle :数据的双向绑定 这个只能用于表单元素中 tips: 表单元素 radio text address email select checkbox textarea
5.class 绑定
1.数组带对象<div : >
data(){
return{
flag:true
}
}
tips:可以在类中的数组中写三元表达式,但推荐使用对象来代替它控制是否渲染
2.单纯的对象
<div : />
data(){
return{
falg1:true,
falg2:true
}
}
3.数组带三元<div : / >
data(){
return{
falg:true,
}
}
4.对象升级<div : />
data(){
return{
classObj:{classA:falg1,classB:flag2}
}
}
tips:直接使用一个对象数组来控制样式
5.使用style 的对象来实现样式的修改<div : />
data(){
return{
styleObj:{color:red}
}
}
6.使用style 的数组带对象来实现样式的修改<div : />
data(){
return{
styleObj1:{color:red},
styleObj2:{color:red}
}
}
7.v-for的使用
1. 可以遍历: 普通数组,对象数组,对象,还可以是数字<div v-for='(item,key,index) in object' :key='index'>
{{item}}--{{key}}--{{index}}
</div>
<div v-for='(count in 10)'> </div>
8.v-if、v-show
v-if 有较高的切换性能 , 适合元素可能永远不会被用户看到。 v-show 有较高的初始渲染消耗,适合元素频繁切换。
9.调试插件
在谷歌商店找vue-devtools插件,使用这个插件。并设置插件,允许访问文件网址。 会在调试中出现vue相关的东西 debugger 直接写可以调试
10.过滤器
全局和私有过滤器<div v-for='(item,key) in object' :key='index'>
{{item | dateFormat}}
</div>
<div v-for='(count in 10)'> </div>
全局vue.filter('过滤器名称',function(){ }) 私有(局部)filters:{ dateFormat:function(data,param){ do some }}
tips:
data 就是 | 第一个参数已经被定死了,永远是, 管道左边要被转换的数据,param 是过滤方法传进来的其他参数,过滤器采用就近优先原则,如果私有和全局的名称一样就优先采用私有的。
padstart 和 padend es6 的补0方法
第二个参数是字符串,第三个参数是表达式,如果自己定义参数值是动态的会报错,还未找到原因,后期会找时间再看看,目前就是简单的过滤用过滤器,复杂点用方法,能用计算属性用计算属性,有缓存,能提高性能
11.按键修饰符
监听pc键盘上的值
<input @keyup.enter='方法名'></input>
tips: enter 可以换成键盘上的任何一个值,只要去找相关的键盘码,就都可以使用,推荐设置个别名,放在没有按钮操作的模板。
自定义全局按键修饰符:Vue.config.keyCodes.f2=113,就可使用了
tips: f2修饰符是vue里没有定义的自己创建。
12.定义指令
1. 全局
定义的指令都要按规定去创建 在bind 和inserted还有 updated 中去创建Vue.directive('focus'{
//每当指令绑定到元素上的时候,会立即执行bind 函数,只执行一次,
注意:在元素刚绑定元素的时候,还没有插入到dom中去,这时候,调用focus方法没有作用,即放在focus 放在bind中是不起作用 的
bind:function(el,binding){
el.style.color=binding.value
},
//表示元素插入到dom中的时候,只执行一次
inserted:function(){
el.focus() js行为放在这里去创建
},
//当组件更新的时候,可能会触发多次
updated:function(){},
})
tips:
参数1指令名称,在定义的时候,指令名称前面不需要加v-前缀,但是调用的时候,必须在指令名称前加v-前缀;参数2:是一个对象,在这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行
相关的操作。
在每个函数中,的第一个参数,永远是el, el是代表被bind绑定的元素,el是个原生的js对象。
第二个参数可以是用户传进来值 bingding.value
2. 局部directives:{
'指令名':{
bind:function( el,b){
}
}
}3. 简写'指令名':function(el,binding){
} //注意这个function 等同于 把代码写到bind和update中去
tips: 样式相关的指令放在bind中,js行为相关的放在inserted中比较合适,防止指令不生效。使用场景 写组件时可以用这个去改样式
13.生命周期
beforeCreate():这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它… created(): 这是遇到的第二个生命周期函数… beforeMount():这是遇到的第3个生命周期函数,表示 模板已经在内存中编辑完成,但是尚未把模板渲染(挂载)到页面中。在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串。就像{{text}}这样 mounted():这是遇到的第四个生命周期函数,表示内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了。只要执行完这个生命周期,就表示整个vue实例已经初始化完毕了,此时,组件已经脱离了创建阶段,进入到了运行阶段。 beforeUpdate():这时候表示,我们的界面还没有被更新[但数据已经被更新了页面中显示的数据,还是旧的,此时data数据是最新的。页面尚未和最新的数据保持同步 update() : 这一步执行的是 先根据data中最新的数据,在内存中重新渲染出一份最新的内存dom树,当最新的内存dom树被更新后,会把最新的内存DOM树重新渲染到真实的页面中去,这时候,就完成了数据data(model层)->view(视图层)的更新, 页面和data数据已经保持同步了,都是最新的。 beforeDestory :当执行 beforeDestory 钩子函数的时候,Vue实例就已经从运行阶段,进入到销毁阶段, 当执行beforeDestroy的时候,实例身上所有的data和所有的methods以及过滤器、指令...都处于可用状态,此时,还没有真正执行销毁的过程。 destroyed :当执行这个函数的时候,组件已经被完全销毁了,此时,组件中所有的数据,方法,指令,过滤器...都已经不可用了
14.过渡类名实现动画
1. vue的内置动画<style>
.v-enter,
.v-leave-to{
opacity:0;
transform:translateX(150px) --这东西是位移
}
.v-enter-active,
.v-leave-active{
transition:all 0.4s ease;
}
</style> <transition name='my'>
<h3 v-if="flag"></h3>
</transition> <script>
data(){
return {
flag:false
}
}
</script>
2. 使用第三方类实现动画<transition enter-active-
leave-avtive- duration='200'
>
<h3 v-if="flag" ></h3>
</transition>3. 在属性中声明js钩子 实现半场动画(只需要进场,不需要离场)<transition
<div
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
>
</div>
</transition> <transition
<div
v-show="flag"
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
>
</div>
</transition> <script>
methods:{
beforeEnter(el){
//动画入场之前,此时动画尚未开始, 可以在beforeEnter中设置元素开始动画之前的初始位置
el.style.transform=
"translate(0,0)"
},
enter(el,done){
/*这句话,没有实际的作用,但是,如果不写,出不来动画效果,可以认为 这个会强制刷新动画,ofset触发了重绘重排导致动画更新了*/
el.offsetWidth
el.style.transform=
"translate(150px,450px)"
el.style.transition='all 1s ease'
/*这里的done 代表着
afterEnter的引用,
这个会立即执行afterEnter 否则会有延时
*/
done()
},
afterEnter(el){
/*动画完成之后,会调用afterEnter */
this.flag=!this.flag
}
}
</script>4. 在实现列表过渡的时候,如果需要过渡的元素,是通过v-for循环渲染出来的,不能使用transition包裹,需要使用transitionGroup<transition-group appear tag='ul'>
<li v-for >
<li>
</transition-group> .v-enter,
.v-leave-to{
opacity: 0;
transform:translateY(80x);
}
.v-enter-active,
.v-leave-active {
transition: all 0.6s ease;
}
/*离开后下一个东西没有动画使用这个可以使用动画实现下一个东西渐渐地飘上来的效果,要和 v-leave-active的absolute 配合 固定写法*/
.v-move {
transition:all 0.6s ease
}
.v-leave-active{
/* absolute 有个特点元素默认宽度就是最小值,要在元素上添加width:100%*/
position:absolute;
} <transition mode="out-in">
<component :is="comName" >
</component>
</transition>
tips:
v-enter [这是一个时间点] 是进入之前,元素的起始状态,此时还没有开始进入
v-leave-to [这是一个时间点] 是动画离开之后,离开的终止状态,此时,元素动画已经结束了
v-enter-active
[入场动画的时间段]
v-leave-active
[离场动画的时间段]
animated 是个动画库 新版本似乎不需要加入
使用:duration=200 来表示动画的时间 如果只写一个表示统一配置了开场和离场时间 用 对象可传入c入场和离场 duration="{enter:200,leave:400}"
添加appear属性,实现页面刚展示出来,入场时候的效果
通过为transition-group 元素,设置tag属性
指定 transition-group 渲染为指定元素,如果不指定tag属性,默认,渲染为span 标签
mode="out-in" 先过渡再进来,防止有 阴影,通过mode`来设置过渡方式。
注意:最外层一定要用transition包裹着,动画似乎升级了,可以在transition标签中加入name属性,并且在css样式中把v,替换为你的name属性值。
14 组件
1.使用Vue.extend 来创建全局的Vue组件var coml=Vue.extend({
template:'<h3>这是使用Vue.extend 创建的组件</h3>'
}) //第一个参数组件名称,第二个参数创建出来的组件模板对象
Vue.component('myComl',coml) <my-coml><my-coml/>2.使用 vue.component 来创建组件Vue.component('mycom2',{
template:'<div>
<h3>
这是直接使用Vue.component 创建出来的组件
</h3>
</div>'
})
3.使用 template 来创建组件<template id='tmp1'>
<div>
<h1>
这里通过template元素,在外部定义的组件结构,这个方式,有代码的智能提示和高量
</h1>
</div>
</template>
Vue.component('mycom3',{
template:'#tem1'
})4.私有组件 componment<template id='temp2'>
<h1>这是私有login组件</h1>
</template>
componment:{
login:
{
template:'tmpl2'
}
}
如果使用了Vue.component 定义了全局组件的时候,组件名称使用了驼峰命名,在引用的时候大写的驼峰要改为小写,同时两个单词之间 使用-链接 Vue.component第一个参数:组件的名称,将来在引用组件的时候,就是一个标签形式来引入的,第二个参数: Vue.extend 创建的组件,其中 template就是组件将来要展示的内容
16.组件里的data
组件可以有自己的data数据 组件的data和实例中的data有点不一样,实例中的data 可以为一个对象,但是组件中的data必须是一个方法。 组件中的data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行。 组件中的data数据,使用方式,和实例中的data使用方式完全一样! 组件里data为什么必须是个方法返回个对象呢? 因为要确保每个实例里的数据是唯一的,独有的。如果data里的数据是放在实例外部的,会被其他实例共享。
17.组件切换
1.组件里的切换 可以用 v-if 和 v-else 进行切换
即标签页切换 <a href=""
@click.prevent="flag=true"
>
登录
</a> <a href=""
@click.prevent="flag=flase"
>
注册
</a> <login v-if="flag">
</login>
<register v-else="flag">
</register>2.vue 提供了 component,来展示对应名称的组件//component 是一个占位符
:is属性,可以用来指定要展示的组件的名称 写死的时候这个组件名要是个字符串,动态绑定时key普通写法就好,但value必须是字符串。
<component :is="'componentId'">
</component>
<component :is="oneName">
</component>
data(){
return{
oneName:"login",
}
}
18.父子组件通讯
父子组件传值,通过v-bind:(:)来传值,通过props来接收值 父组件用事件绑定机制传递方法给子组件—v-on 简写 @
//父组件中
<component-name
:children='children' //传值
@handle='show' //绑定方法
>
</component-name>
data(){
return(){
children:11
}
}
methods:{
show(data){
}
}
3.emit 英文原意: 是触发,调用,发射的意思。
@handle=show 父组件传show方法给子组件。
子组件接收父组件的方法,并用$emit把子组件的值传给父组件//子组件中
methods:{
handle(){
this.$emit('func',{
age:1,
name:'搞事'
})
}
}4.在父组件中接收子组件所有参数的同时,添加自定义参数1.子组件传出单个参数时:
// 子组件
this.$emit('test',this.param)
// 父组件
@test='test($event,userDefined)'
2.子组件传出多个参数时:
// 子组件
this.$emit('test',this.param1,this.param2, this.param3)
// 父组件 arguments 是以数组的形式传入
@test='test(arguments,userDefined)'
tips:子组件中的data数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如子组件通过ajax,请求回来的数据,都可以放到data身上,data 上的数据都是可读可写的;
19.使用 ref 获取dom元素
<h3 id='myh3' ref='myh3'> </h3>
methods:{
getElement(){
console.log( this.$refs.myh3.innerText)
}
} //组件也可以使用ref,让父组件调用子组件里的方法和属性值
<login ref='mylogin'> </login>
methods:{
getElement(){
//父组件调用子组件里的属性值
console.log(this.$refs.mylogin.msg)
}
}
tips:
refs; s代表多个引用,会有多个dom元素。 ref英文是reference,值类型和引用类型。
20.路由
1.这是vue-router提供的元素,专门用来 当作占位符的,
将来,路由规则,匹配到的组件,就会展示到这个router-view中去,所以:我们可以把router-view认为是一个占位符<router-view></router-view>2.路由切换 模板写法,默认渲染为一个a标签,
使用tag的span可以用来转换模板的标签名<router-link to="/login" tag='span' >
登录
</router-link>3.路由配置new VueRouter({
//路由匹配规则
routes:[
{
path:'/',
redirect:'/login'
},
{
path:'login',
component:login
},
{
path:'/register',
component:register
}
]
//路由高亮的类名
linkActiveClass:'myactive'
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router //将路由规则对象注册到vm实例上,用来监听Url地址的变化,然后展示对应的组件。
})4.路由传参
1.query//获取id
this.$route.query.id 2.在path上设置参数//参数要一一对应不可缺失,不然可能会
造成路由的不匹配
< router-link
to="/login/12/ls"
> {
path:'/login/:id/:name',component:login
}3.params 新的方式可看文档
5.子路由
<router-link
to="/account/login"
>
</router-link>
routes:[
{
path:'/account',
component:account,
children:{
{
path:'login',
component:login
}
}
}
]
tips:
每个路由规则,都是一个对象,这个规则对象,身上,有两个必须的属性。 属性1 是path,表示监听,哪个路由链接地址; 属性2是component,表示,如果路由是前面匹配到的path,则展示component属性对应的那个组件。 子路由不能加/, 加了/ 会以根目录为基准匹配,这样不方便我们用户去理解url地址 超链接的to 一定要加上父路由
注意:componen属性值,必须是一个组件的模板对象,不能是组件的引用名称
21.命名视图实现经典布局
根据name 来找组件<router-view></router-view>
<router-view name="left"></router-view>
<router-view name="main"></router-view> var header={
template:'<h1>header</h1>'
}
var leftBox={
template:'<h1>leftBox</h1>'
}
var mainBox={
template:'<h1>mainBox</h1>'
} {
path:'/',components:{
'default':header,
'left':leftBox,
'main':mainBox
}
}
22.watch
监听非dom元素watch:{
'obj.a'(newValue,oldValue){ },
immediate:false
} watch:{
'obj':{
handler (newValue, oldValue) {
}
},
deep:true //深程度监听 性能消耗大
} watch:{
//监听路由
'$route.path':{
handler (newValue, oldValue) {
}
},
//immediate:true代表如果在 wacth 里声明了之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行
immediate:true
}
tips:
用了obj.a 加上handle +immediate:true ,就可以监听 对象里的值,如果是obj 加上 handle+deep true 也是可以监听对象的属性但是性能消耗大 一般是直接对象> > +属性 用handle 方法可以让watch初始化就执行,如果不用 handle它就先不执行,待数据改变再执行。 不要在watch 和computer 中去修改参与计算或者监听的值 而是要生成新的值。
23.computed 计算属性computed:{
'fullname':(){
return
}
}
24. render 函数注册组件(vm[vue实例]的属性)render:function(createElements){
//createElements是一个方法,调用它,能够把指定的 组件模板 渲染为html结构
return createElements(login)
//注意 这里 return 的结果,会替换页面中el 指定的那个容器
}
tips: render和components区别 render 会把整个app里组件全部覆盖掉一个app中只能放一个render组件components 可以多个,且不会覆盖
25. slot 插槽
1.写插槽<div v-if="layout === 'block'" :>
<slot></slot> //匿名插槽
</div>
<!-- 左右块 -->
<div v-if="layout === 'both'" >
<div :>
<slot name="left"></slot> //有名字的插槽
</div>
<div :>
<slot name="right"></slot>
</div>
</div> 2.使用插槽//有名字的插槽 # v-slot的缩写是#
<template #left></template>
<template v-slot="left" > </template>
tips 区别对待v-slot="" 和v-slot:name; =和:的区别 一个是slot的name 一个是父组件获取子组件的数据,插槽一定要用template包裹着
<template>
插槽的内容
</template>
请先登录后,再回复
行家里手-技能共享平台