• vue-学习笔记


    一、vue组件

    父组件向子组件传值(通过prop属性绑定),

    注意:

    1.v-bind数据绑定时,可能由于某种命名的规范方法或者属性名字不能是带有驼峰或者连字符的。并且绑定之后,还要放到子组件的props数据后,方可调用。  

    <v-infoList v-bind:listdata="listdata"></v-infoList>

    2.子组件调用的父组件的属性,只能读不能写。同时,子组件的属性是其私有的,Ajax请求返回data属性变化也只是子组件私有的

    3.如果要传递方法时,用v-on绑定方法,通过this.$emit()完成template对于data的作用

    二、Vue Router

    用 Vue.js + Vue Router 创建单页应用。

    使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。

    1、通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由:

     三、为什么 Vue 中不要用 index 作为 key?(diff 算法详解)--【转https://juejin.im/post/5e8694b75188257372503722

    • 用组件唯一的 id(一般由后端返回)作为它的 key,实在没有的情况下,可以在获取到列表的时候通过某种规则为它们创建一个 key,并保证这个 key 在组件整个生命周期中都保持稳定。

    • 如果你的列表顺序会改变,别用 index 作为 key,和没写基本上没区别,因为不管你数组的顺序怎么颠倒,index 都是 0, 1, 2 这样排列,导致 Vue 会复用错误的旧子节点,做很多额外的工作。列表顺序不变也尽量别用,可能会误导新人。

    • 千万别用随机数作为 key,不然旧节点会被全部删掉,新节点重新创建,你的老板会被你气死。

     

     四、Virtual DOM

    Virtual DOM 这个概念相信⼤部分⼈都不会陌⽣,它产⽣的前提是浏览器中的 DOM 是很“昂贵"的。可以看到,真正的 DOM 元素是⾮常庞⼤的,因为浏览器的标准就把 DOM 设计的⾮常复杂。当我们频繁的去做 DOM 更新,会产⽣⼀定的性能问题。
     
    ⽽ Virtual DOM 就是⽤⼀个原⽣的 JS 对象去描述⼀个 DOM 节点,所以它⽐创建⼀个 DOM 的代价要⼩很多。在 Vue.js 中,Virtual DOM 是⽤ VNode 这么⼀个 Class 去描述,它是定义在src/core/vdom/vnode.js 中的。

    可以看到 Vue.js 中的 Virtual DOM 的定义还是略微复杂⼀些的,因为它这⾥包含了很多 Vue.js 的特性。这⾥千万不要被这些茫茫多的属性吓到,实际上 Vue.js 中 Virtual DOM 是借鉴了⼀个开源库
    snabbdom 的实现,然后加⼊了⼀些 Vue.js 特⾊的东⻄。我建议⼤家如果想深⼊了解 Vue.js 的 VirtualDOM 前不妨先阅读这个库的源码,因为它更加简单和纯粹。
     
    其实 VNode 是对真实 DOM 的⼀种抽象描述,它的核⼼定义⽆⾮就⼏个关键属性,标签名、数据、⼦节点、键值等,其它属性都是都是⽤来扩展 VNode 的灵活性以及实现⼀些特殊 feature 的。由于 VNode只是⽤来映射到真实 DOM 的渲染,不需要包含操作 DOM 的⽅法,因此它是⾮常轻量和简单的。Virtual DOM 除了它的数据结构的定义,映射到真实的 DOM 实际上要经历 VNode 的 create、diff、patch 等过程。那么在 Vue.js 中,VNode 的 create 是通过之前提到的 createElement ⽅法创建的。

    五、vue-cli

    5.1 部署

    如果你用 Vue CLI 处理静态资源并和后端框架一起作为部署的一部分,那么你需要的仅仅是确保 Vue CLI 生成的构建文件在正确的位置,并遵循后端框架的发布方式即可。

    如果你独立于后端部署前端应用——也就是说后端暴露一个前端可访问的 API,然后前端实际上是纯静态应用。那么你可以将 dist 目录里构建的内容部署到任何静态文件服务器中,但要确保正确的 publicPath

    本地预览

    dist 目录需要启动一个 HTTP 服务器来访问 (除非你已经将 publicPath 配置为了一个相对的值),所以以 file:// 协议直接打开 dist/index.html 是不会工作的。在本地预览生产环境构建最简单的方式就是使用一个 Node.js 静态文件服务器,例如 serve

    npm install -g serve
    # -s 参数的意思是将其架设在 Single-Page Application 模式下
    # 这个模式会处理即将提到的路由问题
    serve -s dist

    使用 history.pushState 的路由

    如果你在 history 模式下使用 Vue Router,是无法搭配简单的静态文件服务器的。例如,如果你使用 Vue Router 为 /todos/42/ 定义了一个路由,开发服务器已经配置了相应的 localhost:3000/todos/42 响应,但是一个为生产环境构建架设的简单的静态服务器会却会返回 404。

    为了解决这个问题,你需要配置生产环境服务器,将任何没有匹配到静态文件的请求回退到 index.html。Vue Router 的文档提供了常用服务器配置指引

    CORS

    如果前端静态内容是部署在与后端 API 不同的域名上,你需要适当地配置 CORS

    六、Vue 不能检测数组和对象的变化

    对于对象】

    Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。

    对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。例如,对于:

    Vue.set(vm.someObject, 'b', 2)

    您还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:

    this.$set(this.someObject,'b',2)

    有时你可能需要为已有对象赋值多个新属性,比如使用 Object.assign()_.extend()。但是,这样添加到对象上的新属性不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的属性一起创建一个新的对象。

    // 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
    this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

    对于数组】

    Vue 不能检测以下数组的变动:

    1、当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue

    解决:

    (1)vm.items.splice(indexOfItem, 1, newValue)    // Array.prototype.splice

    (2)Vue.set(vm.items, indexOfItem, newValue)    // Vue.set

    (3)vm.$set(vm.items, indexOfItem, newValue)             //vm.$set实例方法,该方法是全局方法 Vue.set 的一个别名

    2、当你修改数组的长度时,例如:vm.items.length = newLength

    (1)使用 splicevm.items.splice(newLength)

     

    七、Vue基础-查缺补漏
    1、数据与方法
    1.1 当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
    注意: 只有当实例被创建时就已经存在于 data 中的 property 才是响应式的。
    如果你知道你会在晚些时候需要一个 property,但是一开始它为空或不存在,那么你仅需要设置一些初始值。

    1.2 使用Object.freeze(),这会阻止修改现有的 property,也意味着响应系统无法再追踪变化。

    1.3 vue实例 property 与方法(都有前缀 $) 【API参考
    vm.$data === data // => true
    vm.$el === document.getElementById('example') // => true
    
    // $watch 是一个实例方法
    vm.$watch('a', function (newValue, oldValue) {
      // 这个回调将在 `vm.a` 改变后调用
    })


    2、模板语法
    2.1 v-bind指令
    对于布尔 attribute (它们只要存在就意味着值为 true),v-bind 工作起来略有不同,
    <button v-bind:disabled="isButtonDisabled">Button</button>
    如果 isButtonDisabled 的值是 nullundefinedfalsedisabled attribute 甚至不会被包含在渲染出来的 <button> 元素中。


    2.2 动态参数(2.6.0新增)
    <a v-bind:[attributeName]="url"> ... </a>
    <a v-on:[eventName]="doSomething"> ... </a>
    注意: (1)对动态参数的值的约束:  
    动态参数预期会求出一个字符串,异常情况下值为 null
    这个特殊的 null 值可以被显性地用于移除绑定。
    任何其它非字符串类型的值都将会触发一个警告。
    (2)对动态参数表达式的约束:
    使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。
    避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:


    3、计算属性 & 侦听器
    3.1 如何使用计算属性computed
    例子:
    <div id="example">
      <p>Original message: "{{ message }}"</p>
      <p>Computed reversed message: "{{ reversedMessage }}"</p>
    </div>
    var vm = new Vue({
      el: '#example',
      data: {
        message: 'Hello'
      },
      computed: {
        // 计算属性的 getter
        reversedMessage: function () {
          // `this` 指向 vm 实例
          return this.message.split('').reverse().join('')
        }
      }
    })
    说明:(1)reversedMessage:是申明的计算属性,提供的函数将用作 property vm.reversedMessage 的 getter 函数: ;
    (2)“你可以像绑定普通 property 一样在模板中绑定计算属性。
    Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。
    而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。”

    3.2 计算属性 VS 方法
    (1)不同的是计算属性是基于它们的响应式依赖进行缓存的
    只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
    相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

    3.3 计算属性 VS 侦听属性
    当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。


    3.4 watch
    当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
    使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。

    4、v-show & v-if
    v-show 不支持 <template> 元素,也不支持 v-else

    v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。

    如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

    5、key 管理可复用的元素

      key 预期number | string

      key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

      有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。


    6、列表渲染
    6.1 v-for 指令
    6.1.1 基于一个数组来渲染一个列表。
    v-for 指令需要使用 item (in|of) items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。可选的第二个参数,即当前项的索引。
    v-for="(item, index) in items"
    v-for="item of items"
    6.1.2  遍历一个对象的 property
    <div v-for="(value, name, index) in object">
      {{ index }}. {{ name }}: {{ value }}
    </div>

    6.1.3 v-for接受整数 ,把模板重复对应次数
    <div>
      <span v-for="n in 5">{{ n }} </span>
    </div>
    // 1 2 3 4 5


    6.1.4  key
    当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。
    如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。

       为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:

    <div v-for="item in items" v-bind:key="item.id">
      <!-- 内容 -->
    </div>

      建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

      注意:不要使用对象或数组之类的非基本类型值作为 v-forkey。请用字符串或数值类型的值。

    6.2 数组更新检测
    6.2.1 变更方法
    push() 、pop()、shift()、unshift()、splice()、sort()、reverse()

    以上,Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。

    6.2.2 替换数组
    例如:filter()、concat()、slice(),它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
    example1.items = example1.items.filter(function (item) {
      return item.message.match(/Foo/)
    })
    备注: “不是Vue 丢弃现有 DOM 并重新渲染整个列表”
    Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

    6.3 显示过滤 | 排序后的结果

    (1)我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。
    在这种情况下,可以创建一个计算属性 computed ,来返回过滤或排序后的数组。
    <li v-for="n in evenNumbers">{{ n }}</li>
    data: {
      numbers: [ 1, 2, 3, 4, 5 ]
    },
    computed: {
      evenNumbers: function () {
        return this.numbers.filter(function (number) {
          return number % 2 === 0
        })
      }
    }

    (2)在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用方法: methods
    <ul v-for="set in sets">
      <li v-for="n in even(set)">{{ n }}</li>
    </ul>
    data: {
      sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
    },
    methods: {
      even: function (numbers) {
        return numbers.filter(function (number) {
          return number % 2 === 0
        })
      }
    }

    6.4 v-for & v-if
    当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
    当你只想为部分项渲染节点时,这种优先级的机制会十分有用。

    备注:而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 <template>) 上。


    7、事件处理
    7.1 事件处理方法
    需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
    <button v-on:click="warn('Form cannot be submitted yet.', $event)">
      Submit
    </button>

    // ...
    methods: {
      warn: function (message, event) {
        // 现在我们可以访问原生事件对象
        if (event) {
          event.preventDefault()
        }
        alert(message)
      }
    }
    7.2 事件修饰符
    <!-- 阻止单击事件继续传播 -->
    <a v-on:click.stop="doThis"></a>
    
    <!-- 提交事件不再重载页面 -->
    <form v-on:submit.prevent="onSubmit"></form>
    
    <!-- 修饰符可以串联 -->
    <a v-on:click.stop.prevent="doThat"></a>
    
    <!-- 只有修饰符 -->
    <form v-on:submit.prevent></form>
    
    <!-- 添加事件监听器时使用事件捕获模式 -->
    <!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
    <div v-on:click.capture="doThis">...</div>
    
    <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
    <!-- 即事件不是从内部元素触发的 -->
    <div v-on:click.self="doThat">...</div>
    注意:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。
    因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

    <!-- 点击事件将只会触发一次 -->
    <a v-on:click.once="doThis"></a>
    <!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
    <!-- 而不会等待 `onScroll` 完成  -->
    <!-- 这其中包含 `event.preventDefault()` 的情况 -->
    <div v-on:scroll.passive="onScroll">...</div>
    注意:不要把 .passive.prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你想阻止事件的默认行为。

    其他: 按键修饰符、系统修饰符、鼠标按钮修饰符

    8、表单输入绑定

      v-model指令 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

    • text 和 textarea 元素使用 value property 和 input 事件;
    • checkbox 和 radio 使用 checked property 和 change 事件;
    • select 字段将 value 作为 prop 并将 change 作为事件。
    8.1 select
    8.1.1 注意:
    <div id="example-5">
      <select v-model="selected">
        <option disabled value="">请选择</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
      </select>
      <span>Selected: {{ selected }}</span>
    </div>

    如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

    8.1.2
    v-for 渲染的动态选项:
    
    
    <select v-model="selected">
      <option v-for="option in options" v-bind:value="option.value">
        {{ option.text }}
      </option>
    </select>
    <span>Selected: {{ selected }}</span>
    
    
    new Vue({
      el: '...',
      data: {
        selected: 'A',
        options: [
          { text: 'One', value: 'A' },
          { text: 'Two', value: 'B' },
          { text: 'Three', value: 'C' }
        ]
      }
    })
    8.2 修饰符
    <!-- 自动过滤用户输入的首尾空白字符 -->
    <input v-model.trim="msg">
     
    <!-- 在“change”时而非“input”时更新 -->
    <input v-model.lazy="msg">

    <!-- 自动将用户的输入值转为数值类型 -->
    <input v-model.number="age" type="number">

    9、组件
    9.1 prop
    就是你可以在组件上注册的一些自定义attribute。

    9.2 子组件的$emit事件
    父级组件可以像处理 native DOM 事件一样通过 v-on 监听子组件实例的任意事件:
     <blog-post ... v-on:enlarge-text="onEnlargeText" ></blog-post>
    methods: {
      onEnlargeText: function (enlargeAmount) {
        this.postFontSize += enlargeAmount
      }
    }

    子组件可以通过调用内建的 $emit 方法并传入事件名称来触发一个事件:
    <button v-on:click="$emit('enlarge-text', 0.1)">
      Enlarge text
    </button>



  • 相关阅读:
    SharePoint部署webpart时候,报错:部署步骤“回收 IIS 应用程序池”中出现错误: 无效命名空间 解决方案
    免费的分布式的自动化测试工具
    https://github.com/dotnetcore
    SharePoint2013与SharePoint2016语言切换原理以及如何使用代码进行语言切换
    微软开源最强Python自动化神器Playwright!不用写一行代码!
    B站播单按时间统计进度
    AF_INET与PF_INET的区别
    git显示:fatal: index file smaller than expected
    Unix系统中信号SIGKILL和SIGSTOP
    GTM、UTC和C/C++中的时间处理
  • 原文地址:https://www.cnblogs.com/sylvia-Camellia/p/11679186.html
Copyright © 2020-2023  润新知