• Vue的Key属性,v-for和v-if,v-if/v-show,v-pre不渲染,v-once只渲染一次


    key属性
    为什么要加

    key -- api 解释

    key的特殊属性主要用在vue的虚拟dom算法,如果不适用key,vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用Key,它会基于Key的变化重新排列元素顺序,并且会移除Key不存在的元素。

    v-for为什么要加Key

    <div id="app">
     <div>
      <input type="text" v-model="name">
    	<button @click="add">添加</button>
    </div>
    
    <ul>
    <li v-for="(item, i) in list">
    <input type="checkbox">
    {{item.name}}
    </li>
    </ul>
    
    <script>
    // 创建vue实例,得到viewmodel
    var vm = new Vue({
    el: '#app',
    data: {
     name: '',
     newId: 3,
     list: [
     {id:1,name''}
     ]
     },
     methods: {
      add() {
    	 this.list.unshift({ 
    	 id: ++this.newId,  
    	 name: this.name })
    	 this.name=""
    	 }
    	 }
    	});
    </script>
    </div>
    

    有key

      <div id="app">
        <div>
          <input type="text" v-model="name">
          <button @click="add">添加</button>
        </div>
        <ul>
          <li v-for="(item, i) in list" :key="item.id">
            <input type="checkbox"> {{item.name}}
          </li>
        </ul>
    <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            name: '',
            newId: 3,
            list: [
              { id: 1, name: '' },
              { id: 2, name: '' },
              { id: 3, name: '' }
            ]
          },
          methods: {
            add() {
             //注意这里是unshift
              this.list.unshift({ id: ++this.newId, name: this.name })
              this.name = ''
            }
          }
        });
      </script>
      </div>
    

    file

    file

    file

    file

    file

    为什么使用v-for时必须添加唯一的key?

    const list = [
        {
            id: 1,
            name: 'test1',
        },
        {
            id: 2,
            name: 'test2',
        },
        {
            id: 3,
            name: 'test3',
        },
    ]
    
    <div v-for="(item, index) in list" :key="index" >{{item.name}}</div>
    
    const list = [
        {
            id: 1,
            name: 'test1',
        },
        {
            id: 2,
            name: 'test2',
        },
        {
            id: 3,
            name: 'test3',
        },
        {
            id: 4,
            name: '我是在最后添加的一条数据',
        },
    ]
    
    const list = [
        {
            id: 1,
            name: 'test1',
        },
        {
            id: 4,
            name: '我是插队的那条数据',
        }
        {
            id: 2,
            name: 'test2',
        },
        {
            id: 3,
            name: 'test3',
        },
    ]
    

    两个相同的组件产生类似的dom结构,不同的组件产生不同的dom结构。

    同一层级的一组节点

    特殊特性
    key

    预期:number | string

    key的特殊属性主要用在vue的虚拟dom算法,在新旧nodes对比时辨识vnodes。

    <ul>
    <li v-for="item in items" :key="item.id"></li>
    </ul>
    

    它可以用于强制替换元素,组件而不是重复使用它。

    完整地触发组件的生命周期钩子
    触发过渡

    <transition>
    <span :key="text">{{text}}</span>
    </transition>
    

    ref被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的$refs对象上。如果在普通的dom元素上使用,引用指向就是dom元素,如果用在子组件上,引用就指向组件实例:

    <p ref="p"> hello </p>
    
    <child-component ref="child"></child-component>
    

    v-for用于元素或组件的时候,引用信息将包含dom节点或组件实例的数组

    is
    用于动态组件且基于dom内模板的限制来工作

    <component v-bind:is="currentView"></compoent>
    
    <table>
    <tr is="my-row"></tr>
    </table>
    
    data: function () {
      return {
        todos: [
          {
            id: 1,
            text: '学习使用 v-for'
          },
          {
            id: 2,
            text: '学习使用 key'
          }
        ]
      }
    }
    
    <ul>
      <li v-for="todo in todos">
        {{ todo.text }}
      </li>
    </ul>
    
    <ul>
      <li
        v-for="todo in todos"
        :key="todo.id"
      >
        {{ todo.text }}
      </li>
    </ul>
    

    永远不要把 v-if 和 v-for 同时用在同一个元素上。

    为了过滤一个列表中的项目

    v-for="user in users" v-if="user.isActive"
    
    v-for="user in users"
    v-if="shouldShowUsers"
    
    <ul>
     <li v-for="user in users"
     v-if="user.isActive"
     :key="user.id">
     {{ user.name }}
     </li>
    </ul>
    
    this.users.map(function (user) {
     if (user.isActive) {
      return user.name
    	}
    })
    
    computed: {
     activeUsers: function() {
      return this.user.filter(function (user) {
    	 return user.isActive
    	})
    }
    }
    
    <ul>
    <li v-for="user in activeUsers"
     :key="user.id">
     {{user.name}}
     </li>
     </ul>
    
    <ul>
    <li v-for="user in users" v-if="shouldShowUsers" :key="use.id">
    {{user.name}}
    </li>
    </ul>
    
    <ul>
    <li v-for = "user in users"
    v-if="user.isActive"
    :key="user.id">
    {{user.name}}
    </li>
    </ul>
    
    <ul>
    <li v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id">
    {{user.name}}
    </li>
    </ul>
    
    <ul>
      <li
        v-for="user in activeUsers"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    <ul v-if="shouldShowUsers">
      <li
        v-for="user in users"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    
    <ul>
      <li
        v-for="user in activeUsers"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    <ul v-if="shouldShowUsers">
      <li
        v-for="user in users"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    
    <template>
      <button class="btn btn-close">X</button>
    </template>
    
    <style>
    .btn-close {
      background-color: red;
    }
    </style>
    
    <template>
      <button class="button button-close">X</button>
    </template>
    
    <!-- 使用 `scoped` 特性 -->
    <style scoped>
    .button {
      border: none;
      border-radius: 2px;
    }
    
    .button-close {
      background-color: red;
    }
    </style>
    <template>
      <button :class="[$style.button, $style.buttonClose]">X</button>
    </template>
    
    <!-- 使用 CSS Modules -->
    <style module>
    .button {
      border: none;
      border-radius: 2px;
    }
    
    .buttonClose {
      background-color: red;
    }
    </style>
    
    <template>
      <button :class="[$style.button, $style.buttonClose]">X</button>
    </template>
    
    <!-- 使用 CSS Modules -->
    <style module>
    .button {
      border: none;
      border-radius: 2px;
    }
    
    .buttonClose {
      background-color: red;
    }
    </style>
    
    <template>
      <button class="c-Button c-Button--close">X</button>
    </template>
    
    <!-- 使用 BEM 约定 -->
    <style>
    .c-Button {
      border: none;
      border-radius: 2px;
    }
    
    .c-Button--close {
      background-color: red;
    }
    </style>
    

    虚拟Dom以及Key属性的作用

    file

    file

    file

    file

    file

    <template>
    <div id="app">
    <input v-model="message" >
    <input :value="message" @input="handleChange">
    {{message}} {{message * message}}
    <div :id="message"></div>
    <todo-list>
     <todo-item @delete="handleDelete" v-for="(item, index) in list" :key="index" :title="item.title" :del="">
      <template v-slot:pre-icon="{value}">
    	 <span>{{value}}</span>
    	</template>
     </todo-item>
    </todo-list>
    

    vue是如果触发组件更新的

    file

    file

    file

    <script>
    export default{
     name: " ",
     props: {
     info: Object,
     name: String,
     list: Array
     },
     data(){
      return {
    	 a: ' ',
    	 b: ' '
    	};
    },
    updated() {
    console.log(' ');
    },
    methods: {
    handleBChange() {
     this.b = "vue" +Date.now();
     }
    }
    };
    

    file

    合理应用计算属性和侦听器

    减少模板中计算逻辑
    数据缓存
    依赖固定的数据类型(响应式数据)

    计算属性:computed

    <p>{{ reversedMessage1 }}</p>
    <p>{{ reversedMessage2() }}</p>
    <p> {{ now }} </p>
    <button @click="() => $forceUpdate()">forceUpdate</button>
    <br/>
    <input v-model="message"/>
    
    export default {
    data() {
    return {
    message: 'hello'
    };
    },
    
    computed: {
    // 计算属性的getter
    reversedMessage1: function() {
     return this.message
      .split("")
    	.reverse()
    	.join("");
    	},
    	now: function() {
    	 return Date.now();
    	 }
    	},
     methods: {
     reversedMessage2: function() {
     return this.message
     .split("")
     .reverse()
     .join("");
    }
    

    侦听器watch
    更加灵活,通用
    watch中可以执行任何逻辑,如函数节流,ajax异步获取数据

    <div>
    {{$data}}
    <br/>
    <button @click="() => (a += 1)"><button>
    </div>
    
    wxport default {
     data: function() {
     return {
      a: 1,
    	b: {c:2,d:3},
    	e: {
    	 f: {
    	  g: 4
    		}
    	},
    	h: []
     };
    },
    watch: {
     a: function(val, oldVal) {
      this.b.c += 1;
     },
     "b.c": function(val, oldVal) {
     this.b.d += 1;
     },
     "b.d": function(val, oldVal) {
      this.e.f.g += 1;
     }
    

    computed vs watch

    computed能做的,watch都能做,反之不行
    能computed的尽量用computed

    <div>
    {{ fullName }}
    <div> firstName: <input v-model="firstName"/></div>
    <div> lastName: <input v-model="lastName"/></div>
    </div>
    
    export default {
    data: function() {
     return {
      firstName: 'foo',
    	lastName: 'bar'
    	};
    },
    computed: {
     fullName: function() {
      return this.firstName + " " + this.lastName;
    	}
    },
    watch: {
     fullName: function(val, oldVal) {
      console.log("new",val,oldVal);
     }
    }
    

    vue的生命周期的应用场景和函数式组件

    生命周期:

    创建阶段,更新阶段,销毁阶段

    file

    创建阶段:
    beforeCreate
    created
    beforeMount
    render
    mounted

    更新阶段
    beforeUpdate
    render
    updated

    销毁阶段
    beforeDestory
    destoryed

    file

    创建阶段:
    beforeCreate
    created
    beforeMount
    render
    mounted

    初始化事件和生命周期
    beforeCreate
    数据观测,属性,侦听器配置
    created
    模板编译到render
    beforeMount
    render
    mounted
    异步请求,操作dom,定时器等

    file

    更新阶段多次更新的阶段

    更新阶段

    beforeUpdate
    render
    updated

    依赖数据改变或$forceUpdate强制刷新
    beforeUpdate
    移除已经添加的事件监听器等万万不可更改
    render
    updated
    操作dom添加事件监听器等万万不更改依赖数据

    file

    销毁阶段:
    beforedestory
    destoryed

    file

    watch: {
    start() {
     this.startClock();
     }
    },
    

    file

    函数式组件:
    functional:true
    无状态,无实例,没有this上下文,无生命周期

    函数式组件:
    file

    vue指令的本质

    v-text
    
    v-html
    
    v-show
    
    v-if
    
    v-else
    
    v-else-if
    
    v-for
    
    v-on
    
    v-bind
    
    v-model
    
    v-slot
    
    v-pre
    
    v-cloak
    
    v-once
    

    自定义指令:
    bind
    inserted
    update
    componentUpdated
    unbind

    生命周期钩子

    常用的高级特性provide/inject

    解决的问题为组件的通信问题
    file

    属性,通信
    事件,通信

    如何优雅地获取跨层级组件实例:
    拒绝递归

    引用信息

    <p ref="p">hello</p>
    
    <child-component ref="child"></child-component>
    

    file

    file

    自动通知setXXXref
    主动获取getxxxref

    <button @click="getEH3Ref"></button
    
    export default {
     components: {
      ChildrenB,
    	ChildrenC,
    	ChildrenD
    	},
    	provide() {
    	return {
    	setChildrenRef: (name, ref) => {
    	this[name] = ref;
    	},
    	getChildrenRef: name => {
    	 return this[name];
    	},
    	getRef: () => {
    	 return this;
    	}
    };
    },
    
    <ChildrenH v-ant-ref="c => setChildrenRef("childrenH", c)"/>
    
    export default {
    components: {
    ChildrenG,
    ChildrenH,
    ChildrenI
    },
    inject: {
    setChildRef: {
    default: () = {}
    }
    }
    };
    

    template和jsx之间的区别

    file

    file

    file

    如何在vue中使用vuex

    file

    file

    import Vue from 'vue'
    import Vuex from 'vuex'
    import App from './App.vue'
    
    Vue.use(Vuex)
    Vue.config.productionTip = false
    
    const store = Vue.Store({
     state: {
      count: 0,
    }
    })
    
    new Vue({
    store,
    render: h => h(App),
    }).$mount('#app')
    
    increment({commit}) {
      setTimeout(()=>{
        commit('increment')
      }, 3000)
    }
    
    <template>
    <div id="app">
    {{count}}
    </div>
    </template>
    
    <script>
    export default {
     name: 'app',
     computed: {
      count() {
    	 return this.$store.state.count
    	 }
    	}
    }
    </script>
    
    <button @click="$store.commit('increment', 2)">count++</button>
    
    mutations: {
    increment(state, n) {
     state.count += n
     }
    }
    

    file

    vuex核心概念以及底层原理

    核心概念
    state->this.$store.state.xxx取值
    getter->this.$store.getters.xxx取值

    mutation->this.$store.commit("xxx")赋值
    action->this.$store.dispatch("xxx")赋值

    module

    底层原理:
    State:提供一个响应式数据
    Getter:借助Vue的计算属性computed来实现缓存

    mutation:更改state方法
    action:触发mutaion方法
    module:Vue.set动态添加state到响应式数据中

    file

    file

    vuex最佳实战

    file

    使用常量替代mutation事件类型

    // mutation-type.js
    export const SOME_MUTATION="SOME_MUTATION“
    
    // store.js
    import Vuex from 'vues'
    import { SOME_MUTATION } from ''
    
    const store = new Vuex.Store({
    state: { ... },
    mutations {
    [SOME_MUTATION] (state) {
    }
    }
    })
    

    传统开发模式

    www.xxx.com - index.html
    www.xxx.com/about -about.html
    

    file
    vue touter的使用场景

    监听url的变化,并在变化前后执行相应的逻辑

    不同的url对应不同的不同的组件

    提供多种方式改变Url的api

    使用方式:
    提供一个路由配置表,不同url对应不同组件的配置
    初始化路由实例new VueRouter()

    挂载到vue实例上
    提供一个路由占位,用来挂载Url匹配到的组件
    file

    选择何种模式的路由以及底层原理

    hash模式:丑,无法使用锚点定位

    file

    Nuxt解决了哪些问题?

    file

    file

    Nuxt核心原理,SSR的核心原理

    file

    file

    Ui组件对比
    Element UI,ANT design vue,iview

    file

    提升开发效率

    Vetur,ESLint,Prettier,Vue DevTools
    file

    file

    Vuex是通过什么方式提供响应式数据的?

    file

    扩展简化版的min-vuex,实现getters,并实现Vuex的方式注入$store

    计算属性computed实现getters缓存

    beforeCreate中混入$store的获取方式

    file

    file


    若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。


    请点赞!因为你们的赞同/鼓励是我写作的最大动力!

    欢迎关注达达的简书!

    这是一个有质量,有态度的博客

    博客

  • 相关阅读:
    十张伟大的科学瞬间
    机器学习如何破译早已消亡的古老语言?
    如何阻止「数码黑帮」偷走你的时间
    社会地位即服务, Status as a Service (二): 社交网络的投资回报率 (ROI)
    谁是你的创业竞争对手?
    酷!美国国家安全局(NSA)开源了逆向工程工具 Ghidra
    Linux终端下Ctrl+S卡死
    操作系统损坏重装是否能恢复lvm硬盘数据的相关实验
    How to write an iso file to usb driver
    linux screen的用法
  • 原文地址:https://www.cnblogs.com/dashucoding/p/11789144.html
Copyright © 2020-2023  润新知