博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vue入门笔记
阅读量:6291 次
发布时间:2019-06-22

本文共 5825 字,大约阅读时间需要 19 分钟。

Vue的入门知识我分成了如上四个顶层概念。

vue实例、指令、组件、模板。
vue官方文档已经很易懂了,但是我希望把我的理解以及一些容易疏忽的地方记下来,方便我日后更轻松的使用它。

vue是什么

vue是一套构建用户界面的渐进式框架。我对渐进式框架的理解是,你可以充分的使用vue的功能,包括简单的功能和复杂的功能,完全按照vue的模式去构建程序。当然你也可以只使用类似数据响应的单一功能。他不强制要求你按照某个模式去书写,也就是说你可以在原有的代码基础上将少量功能用vue去实现也是可行的。

最喜欢的vue的两个特点是,响应式数据和组件。响应式数据省去了很多监听数据的代码,可以专注在构建界面上。而组件作为模块化思想下延伸出的一个手段,不仅可以很好的进行解耦使组件独立存在便于管理,而且可以很好的配合模块化技术进行模块化开发。ES6已经支持模块化。

vue和MVVM

data = Model

模板 + 指令 = View
new Vue() = ViewModel

模板

五种创建模板的方法:

  • DOM元素模板(Vue实例用)

  • script标签 + x-template

  • template属性

  • .vue文件中template标签

  • inline-template

DOM模板

直接用DOM元素作为模板的方式。仅限vue实例控制区域使用。下面四个是组件模板创建方式。

说明:受HTML限制,标签名不能用驼峰(html大小写不敏感)必须用aa-bb形式。另外受html标准影响,特殊元素内只允许存在特定元素,如tr内只能是td或th,如果想再类似tr里解析组件,要用is属性声明组件。

script标签 + x-template

将script内的内容作为模板的方式。注意组件必须有一个根元素。比如下面那个无用div。而且模板与组件分离了,不在同一个位置,不便于管理。不推荐。

Vue.component('hello-world', {  template: '#hello-world-template'})

template属性

最常规做法,也是最恶心的做法,在js语法环境写html代码,没有代码提示,没有格式化,恶心程度可想而知。

Vue.component('my-component', {  template: '
A custom component!
'})

.vue文件的template标签

inline-template

直接在插入组件的位置,声明模板。不过和script模板一样,分离了,不便于管理。不推荐。

These are compiled as the component's own template.

Not parent's transclusion content.

vue实例

vue实例也就是MVVM中的VM(ViewModel)。负责连接view和model。

既然是VM,那么vue实例主要作用是操作数据和自身。

vue实例提供了几个用来操作数据的选项。

data

作为MVVM中的M(Model),data属性用来存储未经处理的原始数据对象。

特性:

  • 新添加的属性不会被响应

这个特性包括两点。

一点是指属性必须在 data 对象上存在它才是响应的。

var vm = new Vue({  data:{  a:1  }})// `vm.a` 是响应的vm.b = 2// `vm.b` 是非响应的

一点是指Vue 不允许在已经创建的实例上动态添加新的根级响应式属性。既不能将响应属性添加到嵌套的对象上。

vm.a.b = 2

添加响应式新属性的替代方案(2种)如下:

// 第一种Vue.set(vm.a, 'b', 2)this.$set(this.a,'b',2)// 第二种vm.a = Object.assign({}, vm.a, { b: 2 })this.a = Object.assign({}, this.a, { b: 2 })
  • 不能响应的数组操作及对应替代方法

// 不能响应vm.items[indexOfItem] = newValue// 替代方法Vue.set(example1.items, indexOfItem, newValue)// 不能响应vm.items.length = newLength// 替代方法example1.items.splice(indexOfItem, 1, newValue)

computed

vue称他为计算属性,用来对data数据进行处理。因为是对data进行计算,所以为了便于维护和理解,计算属性不要去修改data数据,仅仅引用即可。

特性:

  • 用return的数据渲染view

  • 数据是响应式的

  • 基于依赖缓存计算结果。计算属性只有在它的相关依赖发生改变时才会重新求值。

    比如两个div都靠计算属性A来渲染,那么渲染第二个div时不会重新执行计算属性A,而是直接返回渲染第一个div时计算的值

  • getter 和 setter。

    默认只有一个getter,作用是依赖data变化来执行getter。可以自己设一个setter,作用是直接给计算属性赋值时会触发setter。

methods

区别于computed的方法,通常用来作为事件的回调函数,或者不希望使用computed的缓存特性时作为computed的替代品。methods方法同样是数据响应式的。

特性:

  • 用return的数据渲染view

  • 数据是响应式的

  • 计算结果不缓存

问题:

如何在methods函数内引用事件元素本身?

通常直接用this就可以引用事件元素本身。

el.onclick = function(){  console.log(this)}

但是在Vue里this指向实例或组件自身,所以在Vue里这样引用事件元素本身。

  • warn: function (message, event) {  // 现在我们可以访问原生事件对象  if (event) event.preventDefault()  alert(message)  console.log(event.currentTarget) // 绑定事件的元素本身}

    这里需要说明的是,引用的event对象是原生event对象,不是类似jQuery包装过的event对象。而且之所在模板里传入$event是因为,event对象的兼容性问题。在IE和chrome内可以通过window.event引用event对象,也就是不需要event形参,但是火狐不可以,火狐必须有event形参,而且将event对象作为实参传入,当然只有一个event形参时不需要显示的将event作为实参传入。问题在于event形参如果是非第一位参数,就必须将event对象显示的作为实参传入。在原生JS中可以如下实现。显然vue提供了很好的解决方法。

    asd.onclick = function(event) {    var ee = event  function a (msg, event) {      console.log(event)      alert(msg)  }  a(window.value,ee)}

    watch

    当你想要在数据变化响应时,执行异步操作或开销较大的操作时请使用watch

    filter

    被用作一些常见的文本格式化。

    生命周期

    vue实例从创建到销毁的过程。在这个过程中可以通过配置生命周期钩子来处理一些逻辑。

    属性代理

    vue实例创建后,为了便于访问数据,vue实例对象会代理一些数据。

    vm.a直接访问data数据、vm.$data直接访问整个data对象

    指令

    用来在view层表明数据的用途

    v-if 和 v-show

    v-show是条件显示,只是切换display: none/block。

    v-if是条件渲染。

    特殊属性

    is

    用来声明该模板是哪个组件。解决两个问题。

    • 动态切换组件

    • 解决HTML元素限制

    // bad
    ...
    //good

    key

    vue有一个最大限度复用原则,可以复用的元素会经过少量修改继续复用。

    key属性可以屏蔽复用机制。有key属性的元素,每次都会重新渲染。

    说明:

    key值相同的元素之间也会复用,但是绑定key的元素被重新渲染时(渲染了非相同key的元素)原来的缓存会被清除,不再被复用

    ref

    vue实例对象可以通过变量名访问。但是组件没有变量名,所以没有可以访问的接口。

    ref提供了访问组件的接口。

    访问

    vm.$refs.child

    组件

    vue组件是实施前端组件化的一个手段。一个完整的前端组件应该包括属于某一前端UI模块HTML CSS JS部分。但是显然入门教程里的注册方式有模板和JS,但是少了CSS,有点残次品的感觉。所以条件允许我还是更喜欢.vue文件的方式封装组件。

    注册组件

    三种祖册方式

    • 全局注册(不说了)

    • 局部注册(不说了)

    • 用.vue文件封装组件,并用作为模块进行require

    引用组件

    给组件取个名

    访问组件

    var parent = new Vue({ el: '#parent' })// 访问子组件var child = parent.$refs.child

    内容分发

    简单理解就是,父组件模板里的内容应该如何处置。

    内容分发规则有以下几点:

    • 没有slot属性的内容分发给匿名slot

    • 有slot属性的内容分发给对应有相同name属性的slot

    • slot内的内容在没有被分发内容时显示,并不用任何标签进行包裹

    组件组合方式

    • 父子组件

    • 递归组件

    • 循环引用组件(A组件套了B组件,B组件里又套了A,A引用B B引用A)

    问题:

    递归组件:组件递归调用自身时会进入死循环,所以需要用类似v-if,并最终v-if值最终返回false
    循环引用组件:由于互相引用,导致引用关系混乱。在用webpack构建时,webpack无法判断先引用谁。如A引用B B引用A时首先导致混乱的是B组件。Vue提供了一个解决方法。

    beforeCreate: function () {  this.$options.components.TreeFolderContents = require('./B.vue')}

    组件通讯

    vue组件最长提的是解耦。每个组件只负责自己的部分,他只关心接收的数据。所以我觉得组件间的通讯是vue组件最重要的部分。

    父组件给子组件传递数据

    父组件给子组件传递数据遵循一个模式。

    1. 在父组件模板中声明传入的数据

    2. 在子组件中用props属性接收传入的数据

    这样一来,子组件完全解耦,他只负责接收。

    父组件模板传入

    在子组件接收

    Vue.component('child', {  // 声明 props  props: ['message'],  template: '{
    { message }}
    '})

    说明:

    • 传入数据是基本类型时,在子组件修改props会报错

    • 传入数据是对象时,在子组件修改props的情况,因为对象是引用类型,修改props会同事修改到父组件

    子组件通知父组件

    子组件给父组件传递数据遵循一个模式。

    1. 在父组件模板绑定并监听一个事件,该事件触发父组件方法。

    2. 在子组件触发监听的事件,进而触发父组件方法,并把数据作为参数传入该方法。

    具体实现:

    在父组件模板监听事件

    在子组件触发事件

    methods: {  increment: function () {    this.counter += 1    this.$emit('increment', data)  }}

    非父子组件通讯

    非父子组件通讯,由于两个组件独立存在,不能像父子间那样在父模板传入或监听。

    非父子组件通讯通过eventBus也就是一个空的vue实例对象作为中转站进行通讯。具体实现如下。

    1. 创建一个空的vue实例

    2. 在组件生命周期前期(通常是mounted)在中转站上声明一个事件监听,表示谁触发这个事件就相当于通知我了。

    3. 在另一个组件,触发这个事件,和子通知父一样。

    所以非父子和子传父的区别在于,声明监听事件的方式不同。

    具体实现:

    创建一个中转站

    var eventBus = new Vue()

    在A组件声明周期内,在中转站监听一个事件,并把该事件中的this指向自身(A组件本身)

    mounted: function () {    eventBus.$on('addBar', function () {        this.a++    }.bind(this))}

    在B组件中触发事件来通知A组件

    methods: {    aaaAdd: function () {        eventBus.$emit('addBar')    }}

    slot内传入数据

    与父传子一样的模式,在slot传入,在分发内容接收。

    具体实现:

    传入

    接收,具有特殊属性 scope 的 <template> 元素必须存在

    有没有发现?四种不同的通讯方式各不相同,用了四种不同的模式,而且有些在html文档里声明数据传入,有些在js文档里。我觉的很不优雅也不易理解和管理。

    动态切换组件并缓存组件

    原理很简单,通过内置的component元素绑定is来实现切换。

    但是切换出去的组件不会被缓存,重新切回来会重新渲染,如果想缓存。

    转载地址:http://wwuta.baihongyu.com/

    你可能感兴趣的文章
    项目管理中的导向性
    查看>>
    Android WebView 学习
    查看>>
    (转)从给定的文本中,查找其中最长的重复子字符串的问题
    查看>>
    HDU 2159
    查看>>
    spring batch中用到的表
    查看>>
    资源文件夹res/raw和assets的使用
    查看>>
    UINode扩展
    查看>>
    LINUX常用命令
    查看>>
    百度云盘demo
    查看>>
    概率论与数理统计习题
    查看>>
    初学structs2,简单配置
    查看>>
    Laravel5.0学习--01 入门
    查看>>
    时间戳解读
    查看>>
    sbin/hadoop-daemon.sh: line 165: /tmp/hadoop-hxsyl-journalnode.pid: Permission denied
    查看>>
    @RequestMapping 用法详解之地址映射
    查看>>
    254页PPT!这是一份写给NLP研究者的编程指南
    查看>>
    《Data Warehouse in Action》
    查看>>
    String 源码浅析(一)
    查看>>
    Spring Boot 最佳实践(三)模板引擎FreeMarker集成
    查看>>
    Fescar 发布 0.2.3 版本,支持 Redis 和 Apollo
    查看>>