本文共 8114 字,大约阅读时间需要 27 分钟。
## Vue的数据驱动原理?数据更新原理?响应式原理?
因为每个实例可以维护一份被返回对象的独立拷贝
vue提供了一种将父组件内容和子组件的模板整合的方法,内容分发,通过slot插槽实现.
分为具名插槽和匿名插槽在关系链中可以用this.$children[X].xxx=" ” 改变子组件的xxx数据
用ref链实现修改// 在父组件的触发方法中写this.$refs.a.msg= " "
1.需要创建一个公共的vue实例对象 let bus = new Vue()
2.弟弟组件准备一个方法,如hit(){ this.isShow=true;//用于一个标签显示隐藏}
3.弟组件
mounted(){ bus.$on("hit",this.hit)//绑定一个事件,等待一个机会执行}
4.哥组件触发的方法
bus.$emit("hit")
只渲染元素和组件一次,随后的重新渲染,元素/组件及其子节点将被视为静态资源跳过,这属于优化更新性能。
//name属性写后改为abc-的样式名,默认v-
.abc-enter-alive
.abc-leave-active
多元素同时增加动画
//子元素要加key属性
多元素的过渡模式
多个元素过渡
transition里只能是一个元素,但增加v-if/v-else 当相同标签名切换时,由于虚拟DOM机制,会直接让动画消失,所以给transition组件中多个设置key是一个更好地实践vue生命周期分三个阶段
初始化:beforeCreate/created/beforeMount/mounted 运行中:beforeUpdate updated 销毁:beforeDestroy destroyedbeforeCreate(){ //不能拿到this}
created(){ //此钩子函数数据已加载完毕,但DOM未生成。 // 通常在这里面初始化一些事件与ajax请求}
当动态组件被keep-alive包裹时,created只会执行一次,并且组件一直缓存在内存中,没有销毁,
问题: 例如我们在created中绑定一个定时器时,会造成定时器无法关闭。 解决: 动态组件给我们提供了activated和deactivated钩子函数 默认缓存所有组件 可以用include="组件名,组件名"指明有条件缓存 可以使用正则 :include=“/a|b/” 可以使用数组 :include=“[‘a’,‘b’]” exclude是除了谁都缓存目的:操作底层DOM元素,例如让初始化时输入框获取焦点
//全局的Vue.directive("focus",{ //当被绑定的元素插入父节点时,会触发inserted inserted(el){ el.focus() }})//局部的new Vue({ el:"#box", directives:{ focus:{ inserted(el){ el.focus() } } }})
页面加载时:bind inserted
更新组件: update componentUpdate 卸载组件: unbind 重新加载组件: bind inserted bind:指令第一次绑定到元素时调用; inserted:被绑定元素插入父节点时调用 update:所在组件的vnode更新时调用,但可能发生在其子vnode更新之前 componentUpdated:指令所在组件的vnode及其子vnode全部更新后调用 unbind: 指令与元素解绑是调用el:指令绑定的元素,可以用来直接操作DOM
binding:一个对象,包含以下property。//必须加' ' 否则变量应放在data里声明Vue.directive("color",{ bind(el,binding){ el.style.background=binding.value }})//有时候,可能在bind和update里触发相同行为可简写Vue.directive("color",function(el,binding){ el.style.background=binding.value})
用JavaScript驱动时,有以下缺点:
以vue-loader的装载器解析以.vue后缀名的文件
以 vue create . 安装vue全部脚手架//创建vue.config.js文件module . exports={ devserve:{ overlay:{ warnings:false, errors:false } }, lintOnSave:false //关闭eslint检查}//关闭某个eslint找到.eslintrc.js文件中rules error的最后一个单词 ' ' 引起来放到rules里, 然后 :'off'
在style中scoped属性指明仅当前组件可用
原理:会给标签添加额外的属性,内部会根据属性选择器来添加样式。 另:style中lang属性可以具体的CSS预处理语言(sass/less) scoped的穿透问题 设置scoped的目的是为了限制样式只能影响当前的组件 若希望也可以影响到子组件或第三方组件时,需要使用scoped穿透。div /deep/ p{ }
应用:组件里引用第三方插件时,后续想要在这个组件中修改第三方插件的样式,只能通过/deep/.abc实现scoped穿透修改。
//父组件import Son from "子组件路径"//或 const Son = require("子组件路径")1.引入Son组件2.声明组件并注册export default{ components:{ One }}3.传数据 :msg="父组件data的要穿的数据"//子组件export default{ props:["msg"]}
//父组件1.定义空数据2.定义改变数据的方法methods:{ changeData(data){ this.adata= data }}//子组件created(){ this.$emit("change",参数)}//初始化时触发父组件方法
//通过axios请求本地资源1.引入axios import axios from "axios"2.export default{ axios.get("/data.json").then(res=>{ console.log(res) })}//注:data.json必须放在public文件里//访问时须 / 根目录获取
请求在线资源
//请求在线资源要考虑跨域问题//在控制台response Headers下Access-Control-Allow-Origin代表后台是否写跨域。//卖座后台解决了跨域问题但在requl.Header下有个请求头 X-Client-Info和X-Host//请求时需携带请求头//get(" ",{ // headers:{ // ' ':' ',// ' ':' '//}//})前端写跨域时用proxy 代理服务器在vue.config.js下的devserveproxy:{ '/api':{ target:'http://m.maizuo.com', changeOrigin:true, pathRewrite:{ '^/api':'' } }}
网页不是直接放入浏览器中的,而是先放在viewport中,然后viewport再等比例缩放到浏览器宽度,放入浏览器,viewport在缩放过程中,内容也缩小了。
< meta name="viewport" content="width=device-width ,initial-scale=1.0,maximum-scale=1.0, user-scalable=no">//width=device-width宽度等于当前设备宽度//initial-scale=1.0初始的缩放比//maximum-scale=1.0允许用户缩放的最大比例//minimum-scale=1.0允许用户缩放的最小比例//user-scalable用户是否可以手动缩放
rem 指相对于根元素的字体大小的单位
VW 设备宽度的1% 布局 xs 超小屏幕 sm 小屏幕 md中等屏幕lg大屏幕dpr = 设备像素比 / CSS像素比
iPhone6 750px dpr=2 css=750 / 2 =375 100vw=375px 100px=26.67vw iphone5 640px dpr = 2 100px = 31.25vw 1080px dpr=3 100px = 27.78vm传统多页MPA应用,底部通过a标签实现页面的跳转,但网速卡顿时会产生打开速度慢,并且伴随留白问题,用户体验较差。
引入spa single page application 单页面应用 原理:根据rul地址栏变化,来实现对应路由的组件的切换,整个网页没有刷新。只是组件间的卸载与装载,只有一个页面。 安装插件 yarn add vue-router 通过全局方法 Vue.use()使用插件,他需要在new Vue()启动前应用。 Vue.use()背后原理 通过调用插件里的install vue-router提供了router-view,用来显示路由视图组件import Films from '@/views/Films'//@指向SRC目录routes =[ { path:'/film', component:Films }]
import Films from '@/views/Films'//@指向SRC目录//引入二级路由import ComingSoon ....,,routes =[ { path:'/film', component:Films, children:[ { path:'/film/comingsoon' component:ComingSoon } ] }]
//在上面路由配置中加name : 'cn',
router-link标签tag = “li” 指明渲染转化的页面标签
to = "/films"跳转地址 active-class="active"带的class名 replace 阻止浏览器返回按键(不留下浏览记录)点击进入我的页面
export default{ methods:{ toMine(){ this.$router.push("/film") } }}或进入我的
//有时需要我们在路由跳转时带上参数:to="{path:'/film/100'}"在配置路由时{ path:"/person/:id" props:true}接收:props:["id"]或this.$route.params.id:to = "{path:'/film/100?title=我是二号'}"this.$route.query.title接收
即需要的时候加载,随用随载
为什么需要懒加载? 向vue等这种单页面应用,若未用懒加载,运用webpack打包后的文件会异常大,造成进入首页时,需要加载的内容过多,时间过长,会出现长时间白屏,应用懒加载会分担首页所承担的加载压力,减少首页加载用时。Es6写法component:() => import('路径')ES5写法component:resolve => require(['路径'],resolve)//命名webpack包的方法component:()=>import(/*webpack(hunkName:'film')*/'路径')
vue中model模式
hash模式原理:调用window.onhashchange方法hash值切换 history模式原理:本质使用H5的history.pushstate方法更改URL当路由跳转前或跳转后,进入,离开某个路由,需要做某些操作,就可以使用某些钩子来监听。
全局路由守卫
beforeEach | afterEach 前置路由beforeEach()路由跳转前执行router.beforeEach((to,from,next)=>{ if(from.path === '/person'){ console.log("从哪里来") } next(); //代表放行 (必须写)})//to: 将要进入的路由对象,// from:当前导航即将离开的路由
后置路由 跳转之后
router.after((to,from)=>{ if(to.path==='/person'){ console.log("进入person") } })
局部路由 写在路由配置里,放在person路由路径下
beforeEnter(to,from,next){ console.log("进入用户前打印") next()}
路由组件钩子
写在person.vue的export default里 beforeRouteEnter(to,from,next){}
渲染组件的对应路由被confirm前调用,不能获取组件实例this,因为在路由守卫前执行组件未被创建未完待续,将在本篇文章末尾处持续更新
转载地址:http://dzwwz.baihongyu.com/