博客
关于我
vue中的一些高级特性(含vue3新特性)
阅读量:328 次
发布时间:2019-03-04

本文共 7261 字,大约阅读时间需要 24 分钟。

文章目录

vue2.0自定义v-model组件

注意下面是vue2的自定义v-model组件使得子组件和父组件的其他dom实现双向绑定,但是vue2.0的实现方式有诸多缺点
比如:

  • 只能双向绑定一个值,不能双向绑定多个值
  • 实现方式比较繁琐,并且难以理解

子组件CustomVModel.vue

<template>  <!-- 例如:vue 颜色选择 -->  <input type="text"      :value="content"      @input="$emit('changeEvent', $event.target.value)"  >  <!--      1. 上面的 input 使用了 :value 而不是 v-model      2. 上面的 changeEvent 和 changeEvent 要对应起来      --></template><script>export default {     model: {         prop: 'content', // 这个content和下面的props里面的content是自己取的但是两者要对应一样      event: 'changeEvent'  },  props: {         content: String,      default() {    //默认值          return ''      }  }}</script>

父组件index.vue

<template>  <div>      <!-- <p>vue 高级特性</p>      <hr> -->      <!-- 自定义 v-model -->      <p>{   {   name}}</p>      <!--  -->      <CustomVModel v-model="name"/>  </div></template><script>import CustomVModel from './CustomVModel'export default {     components: {         CustomVModel  },  data() {         return {             name: '123',         }  }}</script>

vue3.0实现自定义v-model

在这里插入图片描述
根据上图的比较,我们得知vue3.0实现自定义v-model必须具备以下条件

  • 必须具备modelValue属性
  • 需要在更新的时候必须触发一个onUpdate:modelValue的事件

必须具备modelValue属性
在子组件中ValidateInput:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
vue3.0的context 是 setup() 的第二个形参,它是一个上下文对象,可以通过 context 来访问Vue的实例 this
在这里插入图片描述
在父组件中:
在这里插入图片描述

在这里插入图片描述

$nextTick

  • Vue是异步渲染的框架
  • data改变之后,DOM不会立刻渲染
  • $nextTick会在DOM渲染之后被触发,以获取最新的DOM节点
<template><div id="app">  <ul ref="ul1">       <li v-for="(item, index) in list" :key="index">          {   {   item}}      </li>  </ul>  <button @click="addItem">添加一项</button></div></template><script>export default {   name: 'app',data() {       return {         list: ['a', 'b', 'c']    }},methods: {     addItem() {         this.list.push(`${     Date.now()}`)      this.list.push(`${     Date.now()}`)      this.list.push(`${     Date.now()}`)      const ulElem = this.$refs.ul1  //获取上面的DOM ul元素          console.log('没有用$nextTick '+ulElem.childNodes.length )      // 1. 异步渲染,$nextTick 待 DOM 渲染完再回调      // 3. 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次      this.$nextTick(() => {           // 获取 DOM 元素        const ulElem = this.$refs.ul1  //获取上面的DOM ul元素             console.log(' 用了$nextTick '+ ulElem.childNodes.length )      })  }}}</script>

点第一次

在这里插入图片描述

  • 异步渲染,$nextTick 待 DOM 渲染完再回调
  • 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次

vue的动态组件

一句话来概括就是将组件以变量的形式进行渲染

语法如下

<template><div>	<component :is="HelloWorldName"/></div></template>import HelloWorld from './HelloWorld'export default {       components: {      HelloWorld    },    data() {           return {                  HelloWorldName: "HelloWorld",              }    }}</script>

vue异步加载组件

异步加载组件的简单理解就是什么时候需要用到什么时候就加载

异步组件不需要用import引入了 在下面是这种方式: FormDemo: () => import(’…/…/BaseUse/FormDemo’) 在components里面引入的

点击这个按钮就会出现FormDemo组件(此组件就不贴代码了)

<template>    <div>              <FormDemo v-if="showFormDemo"/>        <button @click="showFormDemo = true">show form demo</button>           </div></template><script>export default {       components: {              FormDemo: () => import('../../BaseUse/FormDemo'),// 异步加载组件      },    data() {           return {                     showFormDemo: false        }    }}</script>

keep-alive

先从字面意思 上理解,坚持活着,这里的主语是组件,其实本质上就是缓存组件的意思,缓存频繁切换的组件,使其不重复渲染。可以优化vue项目的性能

下面的实例营造了这样一个场景:有三个按钮A,B,C,分别点击不同的按钮,下面会出现不同的 组件,其实本质上就是一个简单的tabBar

将要渲染的三个组件 KeepAliveStageA,
KeepAliveStageB, KeepAliveStageC 用 keep-alive 组件包裹,他们就不会被销毁 了,除非页面被关闭

KeepAlive.vue

<template>    <div>        <button @click="changeState('A')">A</button>        <button @click="changeState('B')">B</button>        <button @click="changeState('C')">C</button>        <keep-alive> <!-- tab 切换 -->            <KeepAliveStageA v-if="state === 'A'"/>             <KeepAliveStageB v-if="state === 'B'"/>            <KeepAliveStageC v-if="state === 'C'"/>        </keep-alive>    </div></template><script>import KeepAliveStageA from './KeepAliveStateA'import KeepAliveStageB from './KeepAliveStateB'import KeepAliveStageC from './KeepAliveStateC'export default {       components: {           KeepAliveStageA,        KeepAliveStageB,        KeepAliveStageC    },    data() {           return {               state: 'A'        }    },    methods: {           changeState(state) {               this.state = state        }    }}</script>

KeepAliveStateA.vue

<template>    <p>state A</p></template><script>export default {       mounted() {           // eslint-disable-next-line        console.log('A mounted')    },    destroyed() {           // eslint-disable-next-line        console.log('A destroyed')    }}</script>

KeepAliveStageB.vue

<template>    <p>state B</p></template><script>export default {       mounted() {           // eslint-disable-next-line        console.log('B mounted')    },    destroyed() {           // eslint-disable-next-line        console.log('B destroyed')    }}</script>

KeepAliveStageC.vue

<template>    <p>state C</p></template><script>export default {       mounted() {           // eslint-disable-next-line        console.log('C mounted')    },    destroyed() {           // eslint-disable-next-line        console.log('C destroyed')    }}</script>

mixin

多个组件之间有相同的逻辑,抽离出来。

这里其实思想和react的自定义hook一模一样
vue3中也有自定义hook的功能了

mixin语法有如下缺点:

  1. 变量来源不明确,不利于阅读
  2. 多个mixin可能会造成命名冲突
  3. mixin和组件可能出现多对多的关系,复杂度较高

朋友们不需要担心,现在vue3出来了,里面也有自定义hook了,完全可以代替mixin

下面一个场景就是,如果多个组件都需要使用到showName方法,就可以showName方法写到一个单独的js文件中,但是此js文件用的是vue的script相同的模板

mixin.js

export default {       data() {           return {               city: '北京'        }    },    methods: {           showName() {               // eslint-disable-next-line            console.log(this.name)        }    },    mounted() {           // eslint-disable-next-line        console.log('mixin mounted', this.name)    }}

将mixin.js引入到要渲染的组件,这个组件用到minxin的showName方法和city属性

<template>    <div>        <p>{   {   name}} {   {   major}} {   {   city}}</p>        <button @click="showName">显示姓名</button>    </div></template><script>import myMixin from './mixin'export default {       mixins: [myMixin], // 可以添加多个,会自动合并起来    data() {           return {               name: 'lisi',            major: 'English'        }    },    methods: {       },    mounted() {           // eslint-disable-next-line        console.log('component mounted', this.name)    }}</script>

vue3中的自定义hook函数

下面的自定义hook函数传入参数是一个dom节点,监听document中的点击事件,看点击的区域是否在这个节点内部

import {    ref, onMounted, onUnmounted,Ref } from "vue";const useClickOutside = (elementRef: Ref<null | HTMLElement>) => {       const isClickOutside = ref(false)    const handler = (e: MouseEvent) => {           if (elementRef.value) {               if (!elementRef.value.contains(e.target as HTMLElement)) {                   isClickOutside.value = false            }else{                   isClickOutside.value = true            }        }    }    onMounted(() => {           // console.log(123132132);                document.addEventListener('click', handler)        // console.log(isClickOutside.value);            })    onUnmounted(() => {           document.removeEventListener('click', handler)    })    return isClickOutside}export default useClickOutside
    const isClickOutside = useClickOutside(dropRef);    watch(isClickOutside, () => {         // console.log(isClickOutside.value);      if (isOpen.value && !isClickOutside.value) {           console.log("watch");        isOpen.value = false;      }    });

转载地址:http://jyue.baihongyu.com/

你可能感兴趣的文章
全球首个!阿里云开源批流一体机器学习平台Alink……
查看>>
必须要看的网上冲浪安全攻略!
查看>>
清华硕士爆料:这些才是机器学习必备的数学基础
查看>>
红点中国、红杉中国联合领投,WakeData惟客数据完成1000万美元B轮融资
查看>>
看完这篇操作系统,和面试官扯皮就没问题了!
查看>>
OpenStack发布Ussuri版本 实现智能开源基础设施的自动化
查看>>
整理了一份 Docker系统知识,从安装到熟练操作看这篇就够了 | 原力计划
查看>>
2020 AI 产业图谱启动,勾勒中国 AI 技术与行业生态
查看>>
“编程能力差,90%输在了数学上!”CTO:多数程序员都是瞎努力!
查看>>
霍因科技获首届全国信创产业生态创新奖
查看>>
我是程序员,我用这种方式铭记历史
查看>>
F5打造“感知可控,随需而变的应用” 助力企业实现非凡数字体验
查看>>
CSDN湘苗培优|保持热情,告别平庸
查看>>
Serverless 在大规模数据处理中的实践
查看>>
高可用Redis服务架构分析与搭建
查看>>
运营商的互联网蜕变,从沃云平台开始
查看>>
下一次 IT 变革:边缘计算(Edge computing)
查看>>
Gartner的预言:通向混合IT之旅
查看>>
Docker精华问答 | task与executor有什么关系?
查看>>
英特尔强势上新一大波数据产品,小伙伴们“奔走相告”…… | 极客头条
查看>>