vue 学习笔记

VUE 学习笔记

1 简介

1.1 简介

中文网 https://cn.vuejs.org/v2/guide/

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。是一个用于创建用户界面的开源JavaScript框架,也是一个创建单页应用的Web应用框架。

与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

MVVM模型:

M: 模型,对应data中的数据

V: 视图,模板

VM:视图模型,vue实例对象
vue 学习笔记_第1张图片

1.2 Vue核心

1.2.1 数据驱动——双向绑定

Vue是一种MVVM框架。而DOM是数据的一个种自然映射。传统的模式是通过Ajax请求从model请求数据,然后手动的触发DOM传入数据修改页面。Vue中,Directives对view进行了封装,当model里的数据发生变化是,Vue就会通过Directives指令去修改DOM。同时也通过DOM Listener实现对视图view的监听,当DOM改变时,就会被监听到,实现model的改变,实现数据的双向绑定。
vue 学习笔记_第2张图片

Vue.js数据观测原理在技术实现上,利用的是ES5Object.defineProperty和存储器属性: getter和setter(所以只兼容IE9及以上版本),可称为基于依赖收集的观测机制。核心是VM,即ViewModel,保证数据和视图的一致性。

watcher:每一个指令都会有一个对应的用来观测数据的对象,叫做watcher,比如v-text=“msg”, {{ msg }},即为两个watcher,watcher对象中包含了待渲染的关联DOM元素。

基于依赖收集的观测机制原理:

1 将原生的数据改造成 “可观察对象”,通常为,调用defineProperty改变data对象中数据为存储器属性。一个可观察对象可以被取值getter,也可以被赋值setter。

2 在解析模板,也就是在watcher的求值过程中,每一个被取值的可观察对象都会将当前的watcher注册为自己的一个订阅者,并成为当前watcher的一个依赖。

3 当一个被依赖的可观察对象被赋值时,它会通知notify所有订阅自己的watcher重新求值,并触发相应的更新,即watcher对象中关联的DOM改变渲染。

依赖收集的优点在于可以精确、主动地追踪数据的变化,不需要手动触发或对作用域中所有watcher都求值(angular脏检查实现方式的缺点)。特殊的是,对于数组,需要通过包裹数组的可变方法(比如push)来监听数组的变化。在添加/删除属性,或是修改数组特定位置元素时,也需要调用特定的函数,如obj.$add(key, value)才能触发更新。这是受ES5的语言特性所限。

1.2.2 组件系统

组件化实现了扩展HTML元素,封装可用的代码。页面上每个独立的可视/可交互区域视为一个组件;每个组件对应一个工程目录,组件所需要的各种资源在这个目录下就近维护;页面不过是组件的容器,组件可以嵌套自由组合形成完整的页面。

vue 学习笔记_第3张图片

应用类UI可以看作全部是由组件树构成的。

组件的核心选项

1 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。

2 初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。

3 接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。

4 方法(methods):对数据的改动操作一般都在组件的方法内进行。

5 生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。

6 私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。

Webpack是一个开源的前端模块构建工具,它提供了强大的loader API来定义对不同文件格式的预处理逻辑,这是.vue后缀单文件组件形式的基础。所以在此基础上,尤大开发的vue-loader允许将模板、样式、逻辑三要素整合在同一个文件中,以.vue文件后缀形成单文件组件格式,方便项目架构和开发引用。

1.3 兼容性

vue2不支持IE8及以下的版本。vue3不支持IE10及以下的版本。

支持兼容ECMAScript 5特性的浏览器。

2 示例

https://cn.vuejs.org/v2/guide/installation.html#直接用-lt-script-gt-引入

2.1 引入vue

vue 学习笔记_第4张图片

直接点击开发版本会下载vue.js。开发版本和生产版本区别官网有解释。

2.2 小demo

创建一个html, 并引入vue.js文件





    
    
    Document
    




在谷歌浏览器打开调试,输入Vue,说明成功
vue 学习笔记_第5张图片

2.3 安装devtools

vue 学习笔记_第6张图片

添加后,需设置允许访问文件,
vue 学习笔记_第7张图片

重启浏览器

vue 学习笔记_第8张图片

2.4 VUE实例

vue 学习笔记_第9张图片

3 VUE指令

3.1 事件处理

3.1.1 监听事件 v-on

v-on

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

var example2 = new Vue({ el: '#example-2', data: { name: 'Vue.js' }, // 在 `methods` 对象中定义方法 methods: { greet: function (event) { // `this` 在方法里指向当前 Vue 实例 alert('Hello ' + this.name + '!') // `event` 是原生 DOM 事件 if (event) { alert(event.target.tagName) } } } }) // 也可以用 JavaScript 直接调用方法 example2.greet() // => 'Hello Vue.js!'

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:



...
methods: {
  warn: function (message, event) {
    // 现在我们可以访问原生事件对象
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

事件修饰符

在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop

  • .prevent

  • .capture

  • .self

  • .once

  • .passive

按键修饰符

在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:



按键码

keyCode 的事件用法已经被废弃了并可能不会被最新的浏览器支持。

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,这些内置的别名应该是首选。

你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:

// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

常用的按键 keyCode ,也可用 key



 show(e) {
     console.log(e.key)
 }

3.1.2 计算属性

{{ message.split('').reverse().join('') }}

你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中的多处包含此翻转字符串时,就会更加难以处理。

对于任何复杂逻辑,你都应当使用计算属性。

Original message: "{{ message }}"

Computed reversed message: "{{ reversedMessage }}"

var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })

当然,也可以 写一个方法如: {{ reversedMessage() }}

两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

3.1.3 监听器

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

语法

简写:

语法:
watch: {
    侦听数据: function ( 新数据, 旧数据 ) {
    -----  可以在此处进行操作  ------
    }
}

完整版:

watch: {
    侦听数据 : {
        handler: function( 旧数据, 新数据 ){
                 -----  可以在此处进行操作  ------
        },
        deep: true,  // 深度侦听
        immediate: true  //  执行触发一次
    }
}

实例demo

Ask a yes/no question:

{{ answer }}

var watchExampleVM = new Vue({ el: '#watch-example', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { // 如果 `question` 发生改变,这个函数就会运行 question: function (newQuestion, oldQuestion) { this.answer = 'Waiting for you to stop typing...' this.debouncedGetAnswer() } }, created: function () { // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。 // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率 // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于 // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识, // 请参考:https://lodash.com/docs#debounce this.debouncedGetAnswer = _.debounce(this.getAnswer, 500) }, methods: { getAnswer: function () { if (this.question.indexOf('?') === -1) { this.answer = 'Questions usually contain a question mark. ;-)' return } this.answer = 'Thinking...' var vm = this axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = _.capitalize(response.data.answer) }) .catch(function (error) { vm.answer = 'Error! Could not reach the API. ' + error }) } } })

在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。比如,开启异步任务时候,更适合用监听器,监听新值和旧值之间相差多少后,在发送一个请求到后端

除了 watch 选项之外,您还可以使用命令式的 vm.$watch API。

计算属性和监听器

  1. computed 能完成的 watch 都能完成
  2. watch 能进行异步操作,computed 不可以
  3. 被vue管理的函数,最好写成普通函数,这样this指向才是vm
  4. 不被vue管理的函数(定时器的回到,ajax的回调等)最好写成箭头函数,这样this执行才是vm或组件实例对象

3.2 Class 与 Style 绑定 v-bind

3.2.1 绑定class

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

对象语法

我们可以传给 v-bind:class 一个对象,以动态地切换 class:

上面的语法表示 active 这个 class 存在与否将取决于数据 property isActive 的 truthiness。

你可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class attribute 共存。当有如下模板:

和如下 data:

data: {
  isActive: true,
  hasError: false
}

结果渲染为:

当 isActive 或者 hasError 变化时,class 列表将相应地更新。例如,如果 hasError 的值为 true,class 列表将变为 “static active text-danger”。

绑定的数据对象不必内联定义在模板里:

data: { classObject: { active: true, 'text-danger': false } }

数组语法

我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:

data: { activeClass: 'active', errorClass: 'text-danger' }

渲染为:

如果你也想根据条件切换列表中的 class,可以用三元表达式:

这样写将始终添加 errorClass,但是只有在 isActive 是 truthy时才添加 activeClass。

不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:

3.2.2 绑定stayle

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:

data: { activeColor: 'red', fontSize: 30 }

直接绑定到一个样式对象通常更好,这会让模板更清晰:

data: { styleObject: { color: 'red', fontSize: '13px' } }

同样的,对象语法常常结合返回对象的计算属性使用。

数组语法

v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:

自动添加前缀

当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transform,Vue.js 会自动侦测并添加相应的前缀。

从 2.3.0 起你可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。

3.3 条件渲染 v-if

3.3.1 v-if

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

Vue is awesome!

也可以用 v-else 添加一个“else 块”:

Vue is awesome!

Oh no

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 元素。


template不会影响DOM结构,如果在最外层加一个DIV,则实际DOM中存在此DIV,template实际DOM中不存在任何元素,只是控制template内元素是否显示,DOM中不会存在template。

3.3.2 v-show

另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:

Hello!

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS property display。

v-if vs v-show

  1. v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  2. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  3. 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换(调整display属性)。
  4. template只能使用v-if,不能和v-show一起使用
  5. 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

v-if 与 v-for 一起使用

  • 不推荐同时使用 v-if 和 v-for。
  • 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级

3.4 列表渲染 v-for

3.4.1 遍历

我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

  • {{ item.message }}
var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })

在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。

  • {{ parentMessage }} - {{ index }} - {{ item.message }}
var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } })

你也可以用 v-for 来遍历一个对象的 property。

  • {{ value }}
new Vue({ el: '#v-for-object', data: { object: { title: 'How to do lists in Vue', author: 'Jane Doe', publishedAt: '2016-04-10' } } })

你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:

3.4.2 v-for中的key

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

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

最常见的用例是结合 v-for:

  • ...

它也可以用于强制替换元素/组件而不是重复使用它。当你遇到如下场景时它可能会很有用:

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

例如:


  {{ text }}

当 text 发生改变时, 总是会被替换而不是被修改,因此会触发过渡。

建议使用对象主键作为key而不是idnex。如果有更新列表操作,index可能会导致数据错位现象。

3.4.3 过滤

有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。

  • {{ n }}
  • data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }

    在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个方法:

    • {{ n }}
    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 }) } }

    3.5 表单数据 v-model

    你可以用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

    注意:v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

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

    • text 和 textarea 元素使用 value property 和 input 事件;
    • checkbox 和 radio 使用 checked property 和 change 事件;
    • select 字段将 value 作为 prop 并将 change 作为事件。

    3.5.1 表单元素

    
    
    

    Message is: {{ message }}

    Multiline message is:

    {{ message }}



    Checked names: {{ checkedNames }}


    Picked: {{ picked }}
    new Vue({ el: '#example-4', data: { picked: '' } })

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

    3.5.2 修饰符

    .lazy

    在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件之后进行同步:

    
    
    

    .number

    如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符,并且type=“number”:

    
    

    这通常很有用,因为即使在 type=“number” 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

    .trim

    如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

    
    

    最后:

    • v-model 收集的就是 value ,用户输入的就是valuie
    • v-model 收集的就是 value,并且要给标签配置value
    1. 没有配置 input的value,那么收集的就是checked(true 或者 false )
    2. 配置值
    3.   v-model 初始值不是数组,收集的还是 checked 布尔值
      
    4.   v-model 初始值是数组,那么收集的就是数组中的值
      

    3.6 过滤器

    演示一个示例说明,比如,格式化时间戳显示到页面

    第三方库中先下载一个js https://www.bootcdn.cn/
    vue 学习笔记_第10张图片

    可以把这个js复制到新建一个js文件,实际中引入离线版。

    用法在 github中有说明
    vue 学习笔记_第11张图片
    vue 学习笔记_第12张图片

    3.6.1 计算属性实现

    
    

    {{clacTime}}

    const v = new Vue({ el: '#root', data: { time: 1636863902885, }, computed: { clacTime() { return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss'); } } })

    3.6.2 方法实现

    {{getFmtTime()}}

    methods: { getFmtTime() { return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss:SSS'); }, },

    3.6.3 过滤器

     

    {{time | timeFilter}}

    filters: { timeFilter(value) { return dayjs(this.time).format('YYYY-MM-DD-HH:mm:ss'); } }

    过滤器中默认第一个参数 value 就是 标签中前面要过滤的值 time

    如果使用多个过滤器

    {{time | timeFilter | filter2 }}

    ,意思是 第一个过滤器 timeFilter 过滤完成后结果,交给 filter2 。

    如果过滤器需要传递参数,filters中具体过滤器,第一个参数默认就是要过滤的value,第二个参数才是需要传递的值

    3.7 v-text

    更新元素的 textContent。如果要更新部分的 textContent,需要使用 {{ Mustache }} 插值。

    {{msg}}

    3.8 v-html

    
        

    更新元素的 innerHTML。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。

    在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html,永不用在用户提交的内容上。

    3.9 v-cloak

    这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

    [v-cloak] {
      display: none;
    }
    
    {{ message }}

    不会显示,直到编译结束。

    • 本质是一个特殊属性,Vue创建实例后,会删掉v-cload属性。
    • 配合CSS,可解决网速慢导致页面出现{{xxx}}的问题

    3.10 v-once

    只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

    3.11 v-pre

    跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

    {{ this will not be compiled }}
    

    4 生命周期

    Vue实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂在DOM、渲染-更新-渲染、卸载等一系列过程,我们成为Vue 实例的生命周

    期,钩子就是在某个阶段给你一个做某些处理的机会。

    vue 学习笔记_第13张图片

    beforeCreate( 创建前 )

    在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据。

    created ( 创建后 )

    实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测、属性和方法的运算,watch/event事件回调,完成了data 数据的初始化,el没有。 然而,挂载阶段还没有开始, $el属性目前不可见,这是一个常用的生命周期,因为你可以调用methods中的方法,改变data中的数据,并且修改可以通过vue的响应式绑定体现在页面上,,获取computed中的计算属性等等,通常我们可以在这里对实例进行预处理,也有一些童鞋喜欢在这里发ajax请求,值得注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合在这个方法发请求,建议在组件路由钩子beforeRouteEnter中完成

    beforeMount

    挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上。此时虚拟DOM在内存中,还未挂载到页面。此时还不能操作DOM,因为是虚拟DOM,操作也不奏效。

    mounted

    挂载完成,也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。

    beforeUpdate

    在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程

    updated(更新后)

    在由于数据更改导致地虚拟DOM重新渲染和打补丁只会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用

    beforeDestroy(销毁前)

    在实例销毁之前调用,实例仍然完全可用,

    1. 这一步还可以用this来获取实例,
    2. 一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件

    destroyed(销毁后)

    在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

    5 组件

    使用组件三步骤:

    1. 定义
    2. 注册
    3. 使用

    5.1 demo

    这里有一个 Vue 组件的示例:

    // 定义一个名为 button-counter 的新组件
    Vue.component('button-counter', {
      data: function () {
        return {
          count: 0
        }
      },
      template: ''
    })
    

    组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:

    new Vue({ el: '#components-demo' })

    因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。

    仅有的例外是像 el 这样根实例特有的选项,组件中不可用。

    5.2 创建组件注意

    当我们定义这个 组件时,你可能会发现它的 data 并不是像这样直接提供一个对象:

    data: {
      count: 0
    }
    

    取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

    data: function () {
      return {
        count: 0
      }
    }
    

    如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例。

    组件名

    一个单词组成:小写,首字母小写

    多个单词组成,中间加横杠-,首字母大写MySchool(这种需要使用脚手架)

    避开HTML默认标签名

    组件标签

    开始闭合

    自闭和标签(需要脚手架)

    关于组件:

    1. 组件本质是一个VueCompentment的构造函数,切不是程序员自定义的,是Vue.extend生成的
    2. 我们只需要在html中写组件注册时候的名字(注册 school,使用:)即可。Vue会自动创建该实例对象。即VUe帮我们执行:new VueCompentment(options)
    3. 每次调用Vue.extend,返回的是一个新的组件对象。
    4. 组件配置中,data函数,methonds,watch,computed 函数中,他们的this均是 VueCompent组件实例
    5. new Vue() 配置中,data函数,methonds,watch,computed 函数中,this 均是Vue实例对象
    6. 一个重要的内置关系,VueCompentment.prototype.proto__ === Vue.prototype,这样组件就可以访问vue原型对象中的属性和方法

    5.3 单文件组件

    5.3.1 定义组件

    
    
    
    

    上面是一个标准的单文件组件代码结构

    5.3.1.1 export 暴露

    单文件组件,是组件别的地方就要引用,所以要暴露,就是导出 export

    // 导出暴露
    export default {
    ...
    }
    --------------------------------------------------------
    // 引入的时候
    import compentName from xxx
    
    
    
    // 导出
    export {xxx}
    -----------------------
    // 引入
    import {xxx} from xxxxxx
    

    5.3.2 注册组件

    // 在使用的地方先引入
    import compentName from xxx   // 脚手架中,引入可以不写后缀 .vue
    // 注册
    const v = new Vue({
        el: '#root',
        data: {
            data: 'hah',
        },
        comments:{
            School,  // 在vue comments中注册,这是简写 也可写成 School:School,
            Student
        }
    })
    

    5.3.3 使用

    
        

    6 脚手架

    https://cli.vuejs.org/zh/

    cli: commond line interfacee

    6.1 安装

    安装

    可以使用下列任一命令安装这个新的包:

    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli
    

    安装之后,你就可以在命令行中访问 vue 命令。你可以通过简单运行 vue,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。

    你还可以用这个命令来检查其版本是否正确:

    vue --version
    

    升级

    如需升级全局的 Vue CLI 包,请运行:

    npm update -g @vue/cli
    
    # 或者
    yarn global upgrade --latest @vue/cli
    

    项目依赖

    上面列出来的命令是用于升级全局的 Vue CLI。如需升级项目中的 Vue CLI 相关模块(以 @vue/cli-plugin- 或 vue-cli-plugin- 开头),请在项目目录下运行 vue upgrade:

    # 用法: upgrade [options] [plugin-name]
    
    #(试用)升级 Vue CLI 服务及插件
    
    # 选项:
      -t, --to     # 升级  到指定的版本
      -f, --from   # 跳过本地版本检测,默认插件是从此处指定的版本升级上来
      -r, --registry   # 使用指定的 registry 地址安装依赖
      --all                 # 升级所有的插件
      --next                # 检查插件新版本时,包括 alpha/beta/rc 版本在内
      -h, --help        
    

    Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:

    • 通过 @vue/cli 实现的交互式的项目脚手架。
    • 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。
    • 一个运行时依赖 (@vue/cli-service),该依赖:
      • 可升级;
      • 基于 webpack 构建,并带有合理的默认配置;
      • 可以通过项目内的配置文件进行配置;
      • 可以通过插件进行扩展。
    • 一个丰富的官方插件集合,集成了前端生态中最好的工具。
    • 一套完全图形化的创建和管理 Vue.js 项目的用户界面。

    Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。

    6.2 脚手架创建一个demo

    C:\Users\Administrator\Desktop>vue vreate vue_test
    

    选择默认vue2创建项目

    6.2.1 项目目录介绍

    vue-cli目录解析:

    1. build 文件夹:用于存放 webpack 相关配置和脚本。开发中仅 偶尔使用 到此文件夹下 webpack.base.conf.js 用于配置 less、sass等css预编译库,或者配置一下 UI 库。
    2. config 文件夹:主要存放配置文件,用于区分开发环境、线上环境的不同。 常用到此文件夹下 config.js 配置开发环境的 端口号、是否开启热加载 或者 设置生产环境的静态资源相对路径、是否开启gzip压缩、npm run build 命令打包生成静态资源的名称和路径等。
    3. dist 文件夹:默认 npm run build 命令打包生成的静态资源文件,用于生产部署。
    4. node_modules:存放npm命令下载的开发环境和生产环境的依赖包。
    5. src: 存放项目源码及需要引用的资源文件。
    6. src下assets:存放项目中需要用到的资源文件,css、js、images等。
    7. src下componets:存放vue开发中一些公共组件:header.vue、footer.vue等。
    8. src下emit:自己配置的vue集中式事件管理机制。
    9. src下router:vue-router vue路由的配置文件。
    10. src下service:自己配置的vue请求后台接口方法。
    11. src下page:存在vue页面组件的文件夹。
    12. src下util:存放vue开发过程中一些公共的.js方法。
    13. src下vuex:存放 vuex 为vue专门开发的状态管理器。
    14. src下app.vue:使用标签渲染整个工程的.vue组件。
    15. src下main.js:vue-cli工程的入口文件。
    16. index.html:设置项目的一些meta头信息和提供
      用于挂载 vue 节点。
    17. package.json:用于 node_modules资源部 和 启动、打包项目的 npm 命令管理
    18. package-lock.json:包版本管理,保证每次下载包都是里面配置的版本。
    19. babel.config.js Es6 --> ES5 ,用脚手架自动配置的就可以。

    6.2.2 配置

    脚手架依赖 webpack, webpack配置在 webpack.config.js中,是隐藏的(比较重要,不让修改,所以隐藏起来了)。可通过命令显示:

    # 停止项目,在项目目录中运行: 
    # 这个命令把脚手架默认配置整理成一个js文件
    vue inspect > output.js 
    

    打开output.js,最下面,就是配置项目的入口文件

    entry: {
        app: [
            './src/main.js'
        ]
    }
    

    这个文件,是导出配置的文件,并不是项目启动依赖的配置,意思就是,在这个文件修改,不起作用,只是看的

    修改默认配置

    如果需要修改默认配置,在vue-cli官网:https://cli.vuejs.org/zh/config/#全局-cli-配置,左侧列出来的配置就可以修改。

    vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。你也可以使用 package.json 中的 vue 字段,但是注意这种写法需要你严格遵照 JSON 的格式来写。

    这个文件应该导出一个包含了选项的对象:

    // vue.config.js
    
    /**
     * @type {import('@vue/cli-service').ProjectOptions}
     */
    module.exports = {
      // 选项...
    	lintOnSave:false // 关闭语法检查
    }
    

    修改了 vue-cli 脚手架的配置以后,一定要重启项目

    lintOnSave

    • Type: boolean | ‘warning’ | ‘default’ | ‘error’
    • Default: ‘default’
      是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码。这个值会在 @vue/cli-plugin-eslint 被安装之后生效。
      设置为 true 或 ‘warning’ 时,eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败。
      如果你希望让 lint 错误在开发时直接显示在浏览器中,你可以使用 lintOnSave: ‘default’。这会强制 eslint-loader 将 lint 错误输出为编译错误,同时也意味着 lint 错误将会导致编译失败。
      设置为 error 将会使得 eslint-loader 把 lint 警告也输出为编译错误,这意味着 lint 警告将会导致编译失败。

    7 传值

    7.1 ref 子 -> 父 传值

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

    
    

    hello

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

    关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。

    ref` 被用来给元素或子组件注册引用信息( dom中id的替代者)。

    应用在html标签中获取真实DOM元素,应用在组件上,是获取组件实例对象

    
    

    hello,{{data}}

    -------------------------- showDom(){ console.log('1',this.$refs) console.log('2',this.$refs.title) console.log('3',this.$refs.sch) }

    7.2 props 父 -> 子 传值

    父组件:

    父组件传入属性值

    
    
                        
                        

    你可能感兴趣的:(vue.js,学习,javascript)