1. 动静组件 <component :is='组件名'></component>
联合 v -for 循环应用
-
应用环境
如图,这是一个 v -for 渲染的列表(只是目前这个版块才刚开始做,目前只有一个),圆圈内的就是一个组件,也就是要 v -for 动静组件 [外链图片转存失败, 源站可能有防盗链机制, 倡议将图片保留下来间接上传(img-CgstVJ6d-1665390342414)(https://p3-juejin.byteimg.com…)]
- 理论应用
一开始就是根本的组件引入了
import ColorIn from '@/components/Magic/ColorIn.vue'
import LineIn from "@/components/Magic/LineIn.vue";
import LineIn from "@/components/Magic/Header.vue";
import LineIn from "@/components/Magic/Footer.vue";
export default{
components:{
ColorIn,
LineIn,
Header,
Footer
}
}
接下来就是动静 v -for 动静组件的应用,componentList:['ColorIn','LineIn','Header','Footer']
应用上面的代码即可将代码顺次循环
<component v-for="(item,index) in componentList" :key="index" :is="item"></component>
编译当前的成果就是
<ColorIn></ColorIn>
<LineIn></LineIn>
<Header></Header>
<Footer></Footer>
2.watch 进阶应用
立刻执行
- 应用环境
例如场景为页面一进来就调用拉取列表数据 getList()
,而后监听路由的$route.query.id
而后触发列表数据的更新
- 理论应用
为了让它一开始就执行,咱们须要在 created()
生命周期中执行一次拉取数据的办法
watch:{
'$route.query.id':{handle(){this.getList();
},
}
},
created(){this.getList();
},
然而应用 immediate
即可立刻执行, 改写当前的代码如下
watch:{
'$route.query.id':{handle(){this.getList();
},
immediate:true
}
},
深度监听
- 应用环境
在监听对象的时候,对象的外部属性发生变化 watch 无奈监听到,这种时候就须要应用深度监听
- 理论应用
只须要设置 deep:true
即可开启深度监听
data(){
return{
queryList:{
count:0,
name:'',
}
}
},
watch:{
queryList:{handle(newValue,oldValue){//do something},
deep:true
}
},
计算属性之 setter
- 理论应用
咱们个别平时应用的都是getter
,但其实它还有个setter
, 当计算属性的fullName
触发更新的时候,就会触发setter
回调
data(){
return{
firstName:'',
lastName:'',
}
},
computed:{
fullName:{get(){return `${this.firstName} ${this.lastName}`;
},
set(newValue){let names=newValue.split(' ');
this.firstName=names[0];
this.lastName=names[1];
}
}
},
$on(‘hook: 生命周期 ’)来简化 window 监听
- 理论应用
先来看一下平时的应用办法, 参考 vue 实战视频解说:进入学习
mounted () {window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy () {window.removeEventListener('resize', this.resizeHandler);
}
改写当前的代码为, 相比于下面的写法,这个写法的益处在于能够开启一个事件监听器的同时,就在 beforeDestroy
生命周期中挂载一个删除事件监听器的事件。比下面的写法会更加平安,更加有助于防止内存泄露并避免事件抵触
mounted () {window.addEventListener('resize', this.resizeHandler);
this.$on("hook:beforeDestroy", () => {window.removeEventListener('resize', this.resizeHandler);
})
}
子组件 @hook: 生命周期
监听子组件的生命周期回调
- 理论应用
<child @hook:mounted="listenChildMounted" />
v-pre
- 应用环境
不须要编译的 html 代码能够应用 v -pre,能够进步性能
- 理论应用
<span v-pre>{{message}}</span> // 就算 data 外面定义了 message,渲染完也是{{message}}
v-once
- 应用环境
只须要渲染一次,实用于渲染完当前就不会更新的内容,升高性能开销
- 理论应用
<span v-once>{{message}}</span> //message 的值会编译后渲染,然而编译当前再次批改 message 的值不会触发更新
- v-pre 与 v -once 的区别
v-pre 相当于不编译,间接显示,v-once 相当于只编译一次,前面的更新不编译了
Vue.set()
- 应用环境
① 当你利用索引间接设置一个数组项时
② 当你批改数组的长度时
③ 对象属性的增加或删除时
因为 Object.defineprototype()
办法限度, 数据不响应式更新
- 理论应用
this.$set(arr,index,item);
$forceUpdate()
- 应用环境
$set()
也有肯定的应用限度,当对象没有这个属性的时候,$set()
就会报错,这种时候,间接批改数据,再应用 $forceUpdate()
强制视图刷新即可
- 理论应用
this.$forceUpdate();
keep-alive
- 应用环境
当这个页面没有数据更新,或者是想保留状态,下次进来还是这样子的时候,例如淘宝查看列表页,点进去查看详情之后,返回列表页仍旧到上次浏览到的中央,都能够应用keep-alive
- 理论应用
分为配合路由应用,应用max,include,exclude
,以及非凡的生命周期activated
和deactivated
$route 路由信息
- $route.query.id
用来拿取路由传值的信息,比方路由的后缀?id=1,$route.query.id 拿到的值为 1
- $route.meta.flag
用来拿取路由 meta 中的信息,路由信息里的 meta 是能够自定义属性的,我个别导航栏以后选中的 nav 用来和 $route.meta.flag 进行匹配,来拿到以后页面应该激活哪一个选项卡
- base 路由
比方说百度的所有路由前缀要加/baidu
,那么能够设置路由的 base 为/baidu
export const router = new Router({base:'/baidu/',}
此外,打包的时候,请批改 config/index.js
的build
块中的 assetsPublicPath
为 ‘/baidu/’, 不然打包当前是找不到资源文件门路的
module.exports = {
build:{assetsPublicPath: '/baidu/',}
}
- 全局路由钩子
应用场景个别为用户的登录鉴权
router.beforeEach((to, from, next) => {// 肯定要调用 next()能力到下一个页面
if (path === '/login') {next()
}else{if(token){next();
}else{next('/login');
}
}
})
- 组件路由钩子中拜访 this
组件路由的钩子一开始还未初始化,不能拜访到 vue 实例
beforeRouteEnter (to, from, next) {
// 这里还无法访问到组件实例,this === undefined
next(vm => {
// 通过 vm
拜访组件实例
})
}
$route 路由信息不刷新问题
- 应用场景
有的时候,你从 /user?id=1
跳转到 /user?id=2
的时候,因为渲染同样的 User
组件,导致路由会复用,此时,页面就会依然是用户 1 的信息。
解决方案
- 组件内的路由守卫
beforeRouteUpdate(to, from, next) {
// 在以后路由扭转,然而该组件被复用时调用
// 举例来说,对于一个带有动静参数的门路 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 因为会渲染同样的 Foo 组件,因而组件实例会被复用。而这个钩子就会在这个状况下被调用。// 能够拜访组件实例 `this`
},
- 给
<router-view>
绑定key
<router-view :key="$route.fullpath"></router-view>
- 应用 watch 监听路由
watch:{
'$route':{hander(){// do something...},
immediate:true // 如果要首次加载就触发
}
}
$emit 传参同时拿到父子组件两者入参的值
在理论我的项目开发中,可能会遇到 $emit
的值和父组件的 index 都要拿的状况,然而依照之前的写法,只能拿到其中一个的值,要么子组件,要么父组件,鱼和熊掌不可兼得
- 子组件入参
this.$emit('uploadSuccess',res);
- 父组件入参
<Up @uploadSuccess="uploadLogoImage(index,arguments)" />
- 办法取参
uploadLogoImage(){console.log(arguments[0]); //index
console.log(arguments[1][0]); //res
},
款式穿透
- 应用环境
个别在批改插件款式的时候应用的比拟多
- 理论应用
分为两种, 个别 stylus
中应用 >>>
,less
中应用 /deep/
,sass
没有应用教训,不予阐明
>>>.el-dialog .el-dialog__body{
padding 0
text-align center
border-radius 0 0 4px 4px
}
/deep/.el-dialog .el-dialog__body{
padding 0
text-align center
border-radius 0 0 4px 4px
}
Object.freeze()
- 应用环境
咱们都晓得 vue
是应用 Object.defineProperty
对数据进行双向绑定,而对于只做展现应用的长列表,能够应用 Object.freeze()进行解冻,使它无奈被批改,从而进步性能
- 理论应用
getList().then(res=>{this.list=Object.freeze(res.data.result);
})
值得注意的是,扭转 list 的值不会更新,但扭转援用会触发更新
组件通信技巧
props
$emit
$attrs
&$listeners
provide
&inject
vuex
Observable
eventBus
$refs
slot-scope
&v-slot
scopedSlots
$parent
&$children
&$root
父子组件参数同时获取
- 应用环境,有的时候父组件中,要拿取子组件中
$emit
传递的值,并且,要拿到父组件v-for
以后的index
值
子组件入参
this.$emit('uploadSuccess',res);
父组件入参
<Up @uploadSuccess="uploadLogoImage(index,arguments)" />
- 理论应用
uploadLogoImage(){console.log(arguments[0]); //index
console.log(arguments[1][0]); //res
},
mixins 混入的应用
- 应用环境
个别获取验证码,珍藏,点赞等专用且逻辑一样 (有些逻辑是依据页面的不同而不同的不倡议应用混入) 等场景都能够应用混入
- 理论应用
这里我间接封装了一个 vue 新开窗口的混入办法,引入了当前,混入中的所有data,methods
,以及生命周期都会共享
//openWindow.js
export default {
methods:{openUrl(url){const link= this.$router.resolve({path: url});
window.open(link.href,'_blank');
},
}
}
// 其余页面应用
import openWindow from "../../mixins/openWindow";
export default{mixins:[openWindow],
}
- 留神点(应用的页面统称为组件)
① 混入比组件优先执行
② 当混入中的属性或者办法与组件中的属性或者办法名称雷同时,以组件中的值为准(联合上一条规定,因为混入先执行,所以组件会将混入笼罩)
③ 比方说 A 页面和 B 页面都应用了同一个混入,A 页面与 B 页面的状态同样是独立的
qs
- 应用场景,
get
传输的时候都是路由拼接形式 (?a=1&b=2),而不是json
形式 - 理论应用
// 装置依赖
npm install qs --save
// 页面中或者间接 api.js 中间接序列化应用
import qs from 'qs'
qs.stringify(params)
//axios 拦截器中间接应用
import qs from 'qs'
axios.interceptors.request.use(
config => {if (config.method === 'get') {config.data = qs.stringify(config.data)
}
)
v-for 绑定 key 不倡议应用 index
- 次要起因
有的时候 v -for 列表可能存有 删除,替换地位 等操作,这种时候index 的程序变换会导致同一条数据,在此刻的 index 置换,所以,不倡议 v -for 的 key 绑定 index
- 解决方案
倡议应用另外的并且值惟一的变量,例如后盾给你的 id,反正只有是惟一,不会反复即可
v-for 不倡议配合 v -if
- 次要起因
v-for 的优先级比 v -if 高,也就是说,假如总计 50 条数据,即便通过 v -if 当前,只剩下 25 条显示,然而 v -for 早就循环了一遍 50 条数据,解决办法就是用一个计算属性先将数据过滤了当前,v-for 循环过滤了之后的数据
- 解决方案
应用 computed
计算属性,对列表进行过滤,只剩下过滤之后须要的数据
document.body.contentEditable
- 操作方法
关上控制台,输出document.body.contentEditable=true
, 而后敲回车,网页能够像 word 一样编辑,很不便对于页面的布局抗压能力做测试