zoukankan      html  css  js  c++  java
  • 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

    创建阶段:beforeCreatecreatedbeforeMountrendermounted

    更新阶段beforeUpdaterenderupdated

    销毁阶段beforeDestorydestoryed

    file

    创建阶段:beforeCreatecreatedbeforeMountrendermounted

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

    file

    更新阶段多次更新的阶段

    更新阶段

    beforeUpdaterenderupdated

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

    file

    销毁阶段:beforedestorydestoryed

    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

    自定义指令:bindinsertedupdatecomponentUpdatedunbind

    生命周期钩子

    常用的高级特性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

    filevue 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 DevToolsfile

    file

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

    file

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

    计算属性computed实现getters缓存

    beforeCreate中混入$store的获取方式

    file

    file

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

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

    欢迎关注达达的简书!

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

    博客

  • 相关阅读:
    【Educational Codeforces Round 101 (Rated for Div. 2) C】Building a Fence
    【Codeforces Round #698 (Div. 2) C】Nezzar and Symmetric Array
    【Codeforces Round #696 (Div. 2) D】Cleaning
    【Codeforces Round #696 (Div. 2) C】Array Destruction
    【Educational Codeforces Round 102 D】Program
    【Educational Codeforces Round 102 C】No More Inversions
    【Good Bye 2020 G】Song of the Sirens
    【Good Bye 2020 F】Euclid's nightmare
    使用mobx入门
    requestAnimationFrame 控制速度模拟setinterval
  • 原文地址:https://www.cnblogs.com/dashucoding/p/11932268.html
Copyright © 2011-2022 走看看