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

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

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

    欢迎关注达达的简书!

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

    博客

  • 相关阅读:
    asp.net服务器控件button先执行js再执行后台的方法
    详谈ASP.NET的DataReader对象
    ASP.NET Web API的Controller是如何被创建的?
    富文本编辑器复制粘贴图片上传
    富文本编辑器的使用和图片上传,复制粘贴图片上传
    能够粘贴Word文档公式的编辑器
    可以粘贴Word公式的编辑器
    可以粘贴Word文档公式的编辑器
    可以粘贴Word文档中公式的编辑器
    openstack nova 深入
  • 原文地址:https://www.cnblogs.com/dashucoding/p/11932268.html
Copyright © 2011-2022 走看看