vue 基础知识总结

99 阅读1分钟

computed 和 watch:

    computed 有缓存,data不变则不会重新计算;

    watch 如何深度监听:添加 deep:true;handler;

    watch 监听引用类型,拿不到oldVal;

v-if 和 v-show 的区别:

    v-if: 不符合条件不渲染;更新不频繁或一次性推荐使用;

    v-show:类似于 display:none;不显示,依旧渲染;频繁切换推荐使用;

循环(列表)渲染:

    遍历对象也可以使用 v-for

    key 的重要性。key 不能乱写(如 random 或者 index )

    v-for 和 v-if 不能一起使用;v-for 优先级高于 v-if

event 事件:1. event 是原生的;2. 事件被挂载到当前元素;

6401d1c300010af919201080.jpg

6401d193000112ce19201080.jpg

v-model.trim :截取前后的空格;

v-model.lazy :类似于防抖的效果,输入不会变化,输入结束才会变化;

v-model.number :转换成数字;

props:父组件向子组件传值; $emit:子组件调用父组件的方法;

自定义事件:new Vue()  vue本身就具备自定义事件的能力;绑定自定义事件后一定要在 beforeDestroy 里面及时销毁;

绑定:event.on; 解绑:event.on ;  解绑:event.off;触发:event.$emit;

this.emit:调用父组件的事件;event.emit:调用父组件的事件;event.emit:调用自定义的事件;

生命周期

    挂载阶段:beforeCreate;created;beforeMount;mounted;

    更新阶段:beforeUpdate;updated

    销毁阶段:beforeDestroy;destroyed

created:实例初始化,页面还没有真正的渲染;mounted:渲染完成;

生命周期(父子组件):index(父);list(子)

创建由外至里,渲染由里至外;
index created > list created > list mounted > index mounted

index before update > list before update > list update > index update

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted->父beforeUpdate->子beforeUpdate->子updated->父updated->父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

Vue 高级特性:

自定义 v-model

$nextTick

slot

动态、异步组件

keep-alive

mixin
// 手写 v-model
<template>
    <!-- 例如:vue 颜色选择 -->
    <input type="text"
        :value="text1"
        @input="$emit('change1', $event.target.value)"
    >
    <!--
        1. 上面的 input 使用了 :value 而不是 v-model
        2. 上面的 change1 和 model.event1 要对应起来
        3. text1 属性对应起来
    -->
</template>

<script>
export default {
    model: {
        prop'text1'// 对应 props text1
        event'change1'
    },
    props: {
        text1String,
        default() {
            return ''
        }
    }
}
</script>

$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()}`)

        // 1. 异步渲染,$nextTick 待 DOM 渲染完再回调
        // 3. 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次
        this.$nextTick(() => {
          // 获取 DOM 元素
          const ulElem = this.$refs.ul1
          // eslint-disable-next-line
          console.log( ulElem.childNodes.length )
        })
    }
  }
}
</script>
website: {
    url'http://imooc.com/',
    title'imooc',
    subTitle'程序员的梦工厂'
},
<SlotDemo :url="website.url">
    {{website.title}}
</SlotDemo>

<template>
    <a :href="url">
        <slot>
            默认内容,即父组件没设置内容时,这里显示
        </slot>
    </a>
</template>

<script>
export default {
    props: ['url'],
    data() {
        return {}
    }
}
</script>


// 作用域插槽
<ScopedSlotDemo :url="website.url">
    <template v-slot="slotProps">
        {{slotProps.slotData.title}}
    </template>
</ScopedSlotDemo>
        
<template>
    <a :href="url">
        <slot :slotData="website">
            {{website.subTitle}} <!-- 默认值显示 subTitle ,即父组件不传内容时 -->
        </slot>
    </a>
</template>

<script>
export default {
    props: ['url'],
    data() {
        return {
            website: {
                url'http://wangEditor.com/',
                title'wangEditor',
                subTitle'轻量级富文本编辑器'
            }
        }
    }
}
</script>

640313ae0001145c19201080.jpg

动态组件:

    :is = 'component-name' 用法

    需要根据数据,动态渲染的场景。即组件类型不确定

<component :is="NextTickName"/>

NextTickName"NextTick",

异步组件:

    import()函数

    按需加载,异步加载大组件

components: {
    FormDemo: () => import('../BaseUse/FormDemo'),
}

keep-alive:

    缓存组件

    频繁切换,不需要重复渲染 (如 tab 页)

    Vue 常见性能优化

<keep-alive>需要缓存组件</keep-alive>

mixin:

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

    mixin 并不是完美的解决方案,会有一些问题

    Vue 3 提出的 Composition API 旨在解决这些问题

mixin 问题:

    变量来源不明确,不利于阅读

    多 mixin 可能会造成命名冲突

    mixin 和组件可能出现多对多的关系,复杂度较高

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,解决多组件数据通信。 Vuex 基本概念:

    state:提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data;

    getters:类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据;作用:它是 Vuex 中的计算属性,当 Store 数据源发生变化时,Getter 的返回值会自动更新。

    action:Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action;使用dispatch触发。

    mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数;使用commit触发

用于 Vue 组件:

    dispatch:action时使用。

this.$store.dispatch('actions的名字', 参数)

    commit:mutation时使用。

this.$store.commit('mutation名', 实参)

    mapState:可以方便的把 Store 中指定的数据,映射为当前组件的计算属性。

computed: { 
  ...mapState(['xxx']), 
  ...mapState({'新名字': 'xxx'})
}

    mapGetters:可以把 store 中的 getter 映射为当前组件的计算属性

computed: { 
  ...mapGetters(['xxx']), 
  ...mapGetters({'新名字': 'xxx'})
}

    mapActions:可以方便的把 Store 中指定的 Action,映射为当前组件的 methods。

methods: { 
    ...mapActions(['actions名']),
  ...mapActions({'新名字': 'actions名'}) 
}

    mapMutations:基于 Vuex 提供的 mapMutations 辅助函数,可以方便的把 Store 中指定的方法,映射为当前组件的 methods;

methods: { 
  ...mapMutations(['mutation名']), 
  ...mapMutations({'新名字': 'mutation名'})
}

异步操作必须在 Actions 里面

Vue-router 使用:

    路由模式:hash 、 H5 history;

    路由配置:

        动态路由:动态路径参数 以冒号开头({path: '/user/:id', component: User})。

        懒加载:使用 import ,优化性能 (path: '/user', component: () => {'../user'})。

Vue-router 模式:

    hash 模式(默认),如 abc.com/#/user/10

    H5 history 模式,如 abc.com/user/20 。(mode: 'history')

    后者需要server 端支持,因此无特殊需求可选择前者

Vue 组件如何通讯:

    父子组件:props,$emit;

    兄弟组件:自定义事件;

    Vuex方式通讯;