VUE入门实践(2)

234 阅读8分钟

1、MVVM模式

1.1、MVC模式的意思是,软件可以分成三个部分。各部分之间的通信方式如下。

  • View 传送指令到Controller
  • Controller完成业务逻辑之后,改变Model状态
  • Model将新的数据发送到View,展示给用户
  • 所有通信都是单向的

1.2、MVVM

  • MVVM采用双向绑定,视图层(View)的变动,自动反映在ViewModel,反之亦然。Angular和Vue,React采用这种方式。
  • MVVM模式中,一个ViewModel和一个View匹配,完全和View绑定,所有View中的修改变化,都会更新到ViewModel中,同时VewModel的任何变化都会同步到View上显示。之所以自动同步是ViewModel中的属性都实现了observable这样的接口,也就是说当使用属性的set方法,会同时触发属性修改的事件,使绑定的UI自动刷新。

2、Hello Word

打开HelloWorld.vue,删除多余的内容,写一个最简单的文本插值和数据绑定,改变input的内容,下面也跟着一起改变

<template>
  <div class="hello">
    <input v-model="msg"/>
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data: () => {
    return {
      msg: 'Hello Vue!'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
input {
  font-size: 20px;
}
</style>


运行项目,打开首页

3.生命周期

每个Vue实例在被创建之前都要经过一系列的初始化过程。例如,实例需要配置数据观测(data observer)、编译模版、挂载实例到DOM,然后在数据变化时更新DOM 。在这个过程中,实例也会调用一些生命周期钩子 ,这就给我们提供了执行自定义逻辑的机会。

它可以总共分为8个阶段:

  • 1.beforeCreate:在实例初始化之后,数据观测(data observer) 和event/watcher 事件配置之前被调用。

  • 2.created:实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

  • 3.beforeMount:在挂载开始之前被调用:相关的render 函数首次被调用。该钩子在服务器端渲染期间不被调用。

  • 4.mounted:el 被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。如果root 实例挂载了一个文档内元素,当mounted被调用时vm.$el 也在文档内。该钩子在服务器端渲染期间不被调用。

  • 5.beforeUpdate:数据更新时调用,发生在虚拟DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。该钩子在服务器端渲染期间不被调用。

  • 6.updated:由于数据更改导致的虚拟DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件DOM 已经更新,所以你现在可以执行依赖于DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或watcher取而代之。该钩子在服务器端渲染期间不被调用。

  • 7.beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。

  • 8.destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

4、VUE组件

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:

vuejs组件的重要选项:

data: function () {
  return {
    count: 0
  }
}
  • data:vue的所有数据都是放在data里面的,data 必须是一个函数,这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例

  • methods:就是自己定义的一下方法

  • watch:监听属性,如果对应一个对象,键是观察表达式,值是对应回调,值也可以是方法名,或者是对象,包含选项

  • props:父组件通过 props 向下传递数据给子组件;子组件通过 events 给父组件发送消息

  • created:html加载完成之前执行,执行顺序:父组件-子组件

  • mounted:html加载完成后执行,执行顺序:子组件-父组件

  • computed:计算属性允许我们对指定的视图,复杂的值计算。这些值将绑定到依赖项值,只在需要时更新。

  • methods VS computed:虽然这两种方式输出的结果是相同的,但是性能将遭受毁灭性的打击。使用这种方法totalMarks()方法在每次页面渲染时都被执行一次(例如,使用每一个change)。如果我们有一个计算属性,那么Vue会记住计算的属性所依赖的值(在我们这个示例中,那就是results)。通过这样做,Vue只有在依赖变化时才可以计算值。否则,将返回以前缓存的值。这也意味着只要results还没有发生改变,多次访问totalMark计算属性会立即返回之前的计算结果,而不必再次执行函数。上面两个示例也说明,在Vue中计算属性是基于它们的依赖进行缓存的,而方法是不会基于它们的依赖进行缓存的。从而使用计算属性要比方法性能更好。

简单展示一下props的用法:

父组件:

<template>
  <div class="hello">
    <ul>
      <child v-for="(item,index) in list" :key="index" v-bind:item="item"></child>
    </ul>
  </div>
</template>

<script>
import child from './Child'
export default {
  name: 'HelloWorld',
  components: { child },
  data: () => {
    return {
      list: [123, 456, 789]
    }
  }
}
</script>

子组件:

<template>
    <li>{{ item }}</li>
</template>

<script>
export default {
  props: ['item']
}
</script>

dom结构

5、VUE常用指令

5.1、v-text

v-text主要用来更新textContent,可以等同于JS的text属性。

<span v-text="msg"></span>

5.2、v-html

双大括号的方式会将数据解释为纯文本,而非HTML。为了输出真正的HTML,可以用v-html指令。它等同于JS的innerHtml属性。

export default {
  name: 'HelloWorld',
  data: () => {
    return {
      html: '<p style="color: red;">测试内容</p>'
    }
  }
}


<span v-html="html"></span>

5.3、v-if

v-if可以实现条件渲染,Vue会根据表达式的值的真假条件来渲染元素。

<span v-if="flag">标识为true</span>

5.4、v-else

v-else是搭配v-if使用的,它必须紧跟在v-if或者v-else-if后面,否则不起作用。

<span v-if="flag">标识为true</span>
<span v-else>标识为false</span>

5.5、v-else-if

v-else-if充当v-if的else-if块,可以链式的使用多次。可以更加方便的实现switch语句。

<span v-if="flag === 1">标识为1</span>
<span v-else-if="flag === 2">标识为2</span>
<span v-else-if="flag === 3">标识为3</span>
<span v-else>标识为false</span>

5.6、v-show

用于根据条件展示元素。和v-if不同的是,如果v-if的值是false,则这个元素被销毁,不在dom中。但是v-show的元素会始终被渲染并保存在dom中,它只是简单的切换css的dispaly属性。

<span v-show="flag">标识为true</span>
<span v-show="!flag">标识为true</span>

5.7、v-for

v-for指令根据遍历数组来进行渲染

export default {
  name: 'HelloWorld',
  data: () => {
    return {
      list: [123, 456, 789]
    }
  }
}
<p v-for="(item, index) in list" :key="index">{{item}}</p>

index是一个可选参数,表示当前项的索引

5.8、v-model

用于在表单上创建双向数据绑定。

v-model会忽略所有表单元素的value、checked、selected特性的初始值。因为它选择Vue实例数据做为具体的值。

<input v-model="msg"/>
<h1>{{ msg }}</h1>

改变input输入框的内容h1标签的内容也会跟着改变

修饰符:

.lazy:默认情况下,v-model同步输入框的值和数据。可以通过这个修饰符,转变为在change事件再同步。

<input v-model.lazy="msg">

.number自动将用户的输入值转化为数值类型

<input v-model.number="msg">

.trim自动过滤用户输入的首尾空格

<input v-model.trim="msg">

5.9、v-on

v-on主要用来监听dom事件,以便执行一些代码块。表达式可以是一个方法名。 简写为:【 @ 】

v-on:click="test"

等效于

@click="test"

事件修饰符

.stop: 阻止事件继续传播

.prevent: 事件不再重载页面

.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理

.self 只当在 event.target 是当前元素自身时触发处理函数

.once 事件将只会触发一次

.passive 告诉浏览器你不想阻止事件的默认行为