作者:小城听风雨
https://blog.csdn.net/a5252145/article/details/107316953
v-cloak
使用 v-cloak 指令可以有效解决屏幕闪动。
有时候,页面没渲染之前就会出现vue代码块,例如下图。使用v-cloak可以很好解决这种问题。
![077b351746c0f5967ea06ece55da2314.png](https://i-blog.csdnimg.cn/blog_migrate/1f4445f1464a119b2321da65331dd35e.png)
<template> <div class="hello"> <span v-cloak>{{ content }}span> div>template><script>export default { name: "hello", data() { return { content: "测试" }; }};script><style scoped>/* v-cloak这个属性会在页面渲染前作用于对应dom 在渲染完毕这个里面的样式将被移除 */[v-cloak] { display: none;}style>
keep-alive
官网是这么解释的:
![c7909e6b1cd8b22da9fd5141499fe4fa.png](https://i-blog.csdnimg.cn/blog_migrate/f2a85ab46440563be24b257d0fa7f661.png)
例如:可以实现页面缓存,比如从编辑页切出去再切进来,页面还是处于编辑状态。
需要在router.js中设置meta属性,meta下的keepAlive属性设置为true,代表这个页面需要进行缓存。
import Vue from 'vue'import Router from 'vue-router'import HelloWorld from '@/components/HelloWorld'import is from '@/view/is'import list from '@/view/list'import detail from '@/view/detail'Vue.use(Router)export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld, meta: { keepAlive: false, title: 'HelloWorld' } }, { path: '/is', name: 'is', component: is, meta: { keepAlive: false, title: 'is' } }, { path: '/list', name: 'list', component: list, meta: { keepAlive: true, title: 'list' } }, { path: '/detail', name: 'detail', component: detail, meta: { keepAlive: true, title: 'detail' } } ]})
在app.vue中修改一下代码
<template> <div id="app"> <keep-alive> <router-view v-if="$route.meta.keepAlive" /> keep-alive> <router-view v-if="!$route.meta.keepAlive" /> div>template><script>export default { name: "App"};script><style>#app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;}style>
在详情页detail.vue中,注意beforeRouteEnter和beforeRouteLeave两个方法。
<template> <div> <Form ref="formCustom" :model="formItem" :label-width="80"> <FormItem label="Input"> <Input v-model="formItem.input" placeholder="Enter something...">Input> FormItem> <FormItem label="Select"> <Select v-model="formItem.select"> <Option value="beijing">New YorkOption> <Option value="shanghai">LondonOption> <Option value="shenzhen">SydneyOption> Select> FormItem> <FormItem label="DatePicker"> <Row> <Col span="11"> <DatePicker type="date" placeholder="Select date" v-model="formItem.date">DatePicker> Col> <Col span="2" style="text-align: center">-Col> <Col span="11"> <TimePicker type="time" placeholder="Select time" v-model="formItem.time">TimePicker> Col> Row> FormItem> <FormItem label="Radio"> <RadioGroup v-model="formItem.radio"> <Radio label="male">MaleRadio> <Radio label="female">FemaleRadio> RadioGroup> FormItem> <FormItem label="Checkbox"> <CheckboxGroup v-model="formItem.checkbox"> <Checkbox label="Eat">Checkbox> <Checkbox label="Sleep">Checkbox> <Checkbox label="Run">Checkbox> <Checkbox label="Movie">Checkbox> CheckboxGroup> FormItem> <FormItem label="Switch"> <i-switch v-model="formItem.switch" size="large"> <span slot="open">Onspan> <span slot="close">Offspan> i-switch> FormItem> <FormItem label="Slider"> <Slider v-model="formItem.slider" range>Slider> FormItem> <FormItem label="Text"> <Input v-model="formItem.textarea" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="Enter something...">Input> FormItem> <FormItem> <Button type="primary">SubmitButton> <Button style="margin-left: 8px">CancelButton> FormItem> <FormItem> <router-link :to="{name:'list'}"> <Button size="small" type="primary">跳转到列表页Button> router-link> <router-link :to="{name:'is'}"> <Button size="small" type="primary">跳转到is页Button> router-link> FormItem> Form> div>template><script>export default { name: "detail", mixins: [], components: {}, filters: {}, props: [], computed: {}, data() { return { formItem: { input: "", select: "", radio: "male", checkbox: [], switch: true, date: "", time: "", slider: [20, 50], textarea: "" } }; }, watch: {}, created() { }, mounted() { }, methods: { // 重置表单 init() { this.$refs[formCustom].resetFields(); } }, // 路由进来之前,判断是从哪个页面过来的,设置不同的keepAlive属性 beforeRouteEnter(to, from, next) { if (from.name === "list") { to.meta.keepAlive = true; } else { to.meta.keepAlive = false; } next(); // beforeRouteEnter不能通过this访问组件实例,但是可以通过 vm 访问组件实例(刚开始错误写法) // next(vm => { // if (from.name === "list") { // // 在这里修改keepAlive值,是不能缓存数据的,因为在next()里面的代码,是在vue挂载之后执行,处于activated之后,此时activated中keepAlive还是false // vm.$route.meta.keepAlive = true; // } else { // vm.$route.meta.keepAlive = false; // } // }); }, // 路由离开之前,判断去往哪个页面,设置不同的keepAlive属性 beforeRouteLeave(to, from, next) { if (to.name === "list") { this.$route.meta.keepAlive = true; } else { this.$route.meta.keepAlive = false; } next(); }, activated() { // 此方法在页面缓存时会被调用(this.$route.meta.keepAlive为true时),根据路由元信息决定是否重新加载数据。不加载则是上次填写完的数据 // console.log(this.$route.meta.keepAlive); }};script><style scoped>.detail { position: relative; height: 100%; width: 100%;}style>
插槽slot
解构插槽 Prop:可以传递子组件的变量
// 子组件<template> <div class="isComponent"> <slot name='one' :childStr='childStr'>slot> <slot name='two'>slot> <slot>slot> div>template><script>export default { name: "isComponent", data() { return { childStr: 'i am a child', }; }};script><style scoped>style>
// 父组件<is-component> <template #one="{childStr}">{{childStr}}template> <template v-slot:two> two template> <template> default template>is-component>
效果:// i am a child two default
强制刷新某个div
通过this.$router.go(0)刷新页面,和F5一样,会有空白页时间,体验不好。通过provide/inject即可改变这种效果。
修饰符
事件修饰符:
.stop:相当于原生JS中event.stopPropagation(),阻止事件冒泡。
.prevent:相当于原生JS中event.preventDefault(),阻止默认事件的发生。
.capture:事件冒泡的方向相反,事件捕获由外到内。即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依次执行。
.self:只会触发自己范围内的事件,不包含子元素。
![08dff925429476663f224c47b402461e.gif](https://i-blog.csdnimg.cn/blog_migrate/83705299a5244dc84ee7af6f100e01f8.gif)
.once:事件只能触发一次。
.passive:事件会执行默认方法。
注:
每次事件产生,浏览器都会去查询一下是否有preventDefault阻止该次事件的默认动作。
我们加上passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作。
passive和prevent冲突,不能同时绑定在一个监听器上
:is: 动态组件
优点:使代码更符合HTML语法验证
官网是这么解释的:
![a71bcb8fc304a5623b78b1b4c4ecf3d5.png](https://i-blog.csdnimg.cn/blog_migrate/01dbe3cba49b09dd7b2f055ce02d527a.png)
// 父组件:<template> <div class="is"> <table> <tr :is='is'>tr> table> div>template><script>import isComponent from '../components/isComponent'export default { name: "is", components: { isComponent }, data() { return { is: 'isComponent' }; }};script><style scoped>style>
// 子组件:<template> <div class="isComponent"> <span>我是trspan> div>template><script>export default { name: "isComponent", data() { return {}; }};script><style scoped>style>
@click.native
在封装好的组件上使用,要加上.native才能click。
router-link 加上@click事件,绑定的事件会无效因为:
router-link的作用是单纯的路由跳转,会阻止click事件,你可以试试只用click不用native,事件是不会触发的。
此时加上.native,才会触发事件.
根据Vue2.0官方文档关于父子组件通讯的原则,父组件通过prop传递数据给子组件,子组件触发事件给父组件。但父组件想在子组件上监听自己的click的话,需要加上native修饰符
// router-link "{name:'detail'}" "small" type=// 自己封装的组件<is-component @click.native="handleNative">is-component>
![c658a3eb61869667cf87d59e84706b48.png](https://i-blog.csdnimg.cn/blog_migrate/cba7e4f59a53872cea74dbdee21d81ea.jpeg)
更多前端分享,请关注:
前端路人甲