Vue开发指南之基础篇

前言

博主博客,欢迎来访http://lawsan.xyz
写这编文章也是为了回顾之前学的Vue,查漏补缺。此篇文章涵盖Vue的基本知识以及开发技巧等。这篇文章不讲Vue的相关原理,只会讲Vue 2.0在开发中常见的知识点。你准备好了吗?

安装

CDN引入
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
NPM
npm install vue
命令行工具(CLI)

安装Vue-cli npm install -g @vue/cli
利用脚手架创建一个Vue项目 vue create 项目名称 这是vue-cli3创建项目的命令;vue-cli2创建一个Vue项目 vue init webpack 项目名称

Vue实例

实例&&数据&&方法

当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

var data = {a:1}
var vm = new Vue({
	el:'#app',
	data:data,
	methods:{},
	props:[],
	components:{},
	created:function(){}
	....
})
vm.a == data.a //true
vm.a = 2; data.a == 2 //true 
//反之亦然
data.a = 3; vm.a == 3 //true 
vm.$data === data // => true
vm.$el === document.getElementById('app') // => true

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

生命周期

beforeCreate:只是初始化一些生命周期函数和默认事件,其他的均未创建。
created:初始化data和methods了。
beforeMount:数据已经准备好了,还没渲染到页面。
mounted:将编译好的HTML挂载到页面,完成了渲染。
beforeUpdate:数据被修改,当是还没被重新渲染到页面。
updated:重新渲染页面,页面已经是修改后的了。
beforeDestroy:Vue实例进入销毁状态,data、methods,以及过滤器和指令都是可以用的。
destroyed:Vue实例已经被销毁。
看懂下面这张图就行

模板语法

插值

文本
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值。

<span>Message: {{ msg }}</span>

无论何时,绑定的数据对象上 msg property 发生了改变,插值处的内容都会更新。
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

<span v-once>这个将不会改变: {{ msg }}</span>

原始HTML

<p>Using v-html directive: <span v-html="rawHtml"></span></p>

v-html可能会引发XSS攻击,因此绝不要对用户提供的内容使用插值。
Attribute && 表达式

<div v-bind:id="dynamicId"></div>
{{ ok ? 'YES' : 'NO' }}
指令

v-if:判断true或者flase,是否插入元素。
v-else:经常和v-if一起用,还有v-else-if
v-for:遍历循环,注意要绑定:key
v-on:处理事件,v-on:事件名="表达式||函数名",简写@事件名="函数名"
v-bind:绑定属性,v-bind:属性名="属性值"简写:属性名="属性值"
v-show:原始的显示与隐藏,与v-if不同,v-if是插入元素或者删除元素,开销大。
v-html:插人原始HTML,插入的元素要用 >>> css选择器渲染。
v-text:插入文本。
v-cloak:解决vue解析时出现页面闪烁问题。
v-model:双向数据绑定。

修饰符

@submit.prevent="fName":.prevent阻止事件默认行为。
@click.stop="fName":.stop阻止事件冒泡,.capture可以发生事件捕获,.self只触发本身。
@keyup.enter="fName":.enter键盘回车事件,当然还有很多按键,请看我的另一篇文章Vue监听回车事件@keyup
@click.once="fName":.once事件只触发一次。
<el-input @keyup.enter.native="search"></el-input>:.native在自定义组件中,要加native才能监听原生的事件。
<input v-model.lazy="msg" >:.lazy惰性更新,也就是说不会更新那么快,等输入完成后才更新。
<input v-model.trim="msg">:.trim去除前后空格。
<input v-model.number="msg">:.number将输入的字符串变成数字。
.sync:对prop进行双向绑定,用法如下

//父组件
<fa-comp :fatest.sync="test"></fa-comp>
//子组件
this.$emit('update:fatest,sontest);

.passive:提升移动端的性能,大概解释就是每次滚动都会有一个默认事件触发,加了这个就是告诉浏览器,不需要查询,不需要触发这个默认事件。
利用vue中的修饰符能让你的开发事倍功半。

计算属性和侦听器

基础实例

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护,所以,对于任何复杂逻辑,你都应当使用计算属性。

<p>Reversed message: "{{ reversedMessage() }}"</p>
computed: {
	// 计算属性的 getter
	reversedMessage: function () {
	// `this` 指向 vm 实例
	return this.message.split('').reverse().join('')
	}
}
计算属性缓存 vs 方法
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。

计算属性 vs 侦听属性

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。

//computed实现属性计算
computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  },
  //watch实现属性计算
 watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
计算属性的 setter

计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

监听器

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

Class 与 Style 绑定

绑定 HTML Class

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

<div :class="{ active: isActive }" :class="classObject"></div> //两种形式
//...
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

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

<div :class="[activeClass, errorClass]" :class="[isActive ? activeClass : '', errorClass]"></div> //也可以使用三元表达式
//...
data: {
  isActive:false, 
  activeClass: 'active',
  errorClass: 'text-danger'
}
绑定内联样式

对象语法

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

数组语法

<div v-bind:style="[baseStyles, overridingStyles]"></div>

和绑定HTML Class 大同小异,这里就不做多描述了。
注意:当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transform,Vue.js 会自动侦测并添加相应的前缀。
前缀多重值
你可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,如下

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

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

条件渲染

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

v-if,v-else,v-else-if,v-for,v-show在前面的指令那里都有解释,这里就不做多描述了。

不推荐同时使用 v-ifv-for;当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
注意
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外。也就是说v-if切换是,复用了已有元素。要用key 管理可复用的元素

列表渲染

在 v-for 里使用对象
<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>

在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。

维护状态

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:

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

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

数组更新检测

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括(可以改变原数组的方法):push,pop,shift,unshift,splice,sort,reverse;
当然也可以使用数组替换,用新数组替换原来的旧数组,达到数据变化以驱动视图更新。例如 filter()concat()slice(),虽然不能改变原数组,但是可以赋值替换的方式来改变原数组。

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。

在 v-for 里使用值范围

v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。

<div>
  <span v-for="n in 10">{{ n }} </span>
</div>
//结果:1,2,3...10

事件处理

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

 <button v-on:click="greet">Greet</button>

除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:

<button v-on:click="say('hi')">Say hi</button>

事件修饰符,在前面有说了,这里就不做多描述。

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
.exact修饰符允许你控制由精确的系统修饰符组合触发的事件。

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button v-on:click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">A</button>

鼠标按钮修饰符.left,.right,.middle;

表单输入绑定

基础用法

v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源,v-model是双向数据绑定的;
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。
    绑定文本:<input v-model="message" >
    多行文本:<textarea v-model="message" ></textarea>
    复选框:<input type="checkbox" v-model="checked">
    单选框:
<input type="radio" id="one" value="One" v-model="picked">
<input type="radio" id="two" value="Two" v-model="picked">

选择框:

<select v-model="selected" multiple> //如果可以多选,加上multiple
	<option disabled value="">请选择</option>
	<option>A</option>
	<option>B</option>
	<option>C</option>
</select>
值绑定
<!-- 当选中时,`picked` 为字符串 "a" -->
<input type="radio" v-model="picked" value="a">

<!-- `toggle` 为 true 或 false -->
<input type="checkbox" v-model="toggle">

<!-- 当选中第一个选项时,`selected` 为字符串 "abc" -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>
修饰符

.trim,.lazy,number;在模板语法里面有讲解了,这里就不做多描述。

组件

组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
**(单个根元素)**示例:

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
组件复用

你可以将组件进行任意次数的复用:

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

注意当点击按钮时,每个组件都会各自独立维护它的 count。因为你每用一次组件,就会有一个它的新实例被创建。组件之间是独立的,复用的时候也会产生独立的作用域。
data 必须是一个函数
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

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

这也就是为什么,组件复用的时候,复用组件之间的数据是不互通的,作用域相互独立。
为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册局部注册。至此,我们的组件都只是通过 Vue.component 全局注册的:

组件通信

父向子传props:

//...父组件
<son :title="hello" ></son>
//...
//...子组件
{{title}}
props:[title]
//...

子传父 e m i t : 子 组 件 通 过 ‘ emit: 子组件通过` emit:emit`触发父组件的事件,而达到数据传递的效果。

//...父组件
<son @getSonData="sonData" ></son>
methods:{
	sonData(data){
		console.log(data) //data为子组件传递过来的数据
	}
}
//...
//...子组件
<button @click="sendData">向父组件传数据</button>
methods:{
	sendData(){
		this.$emit('getSonData','我是子组件传递过来的数据')
	}
}
//...

EventBus 事件总线传递数据

在组件上使用v-model
<input v-model="searchText">

等价于

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

当用在组件上时,v-model 则会这样:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

为了让它正常工作,这个组件内的 必须:

  • 将其 value attribute 绑定到一个名叫 value 的 prop 上
  • 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出。
    写成代码之后是这样的:
Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})

现在 v-model 就应该可以在这个组件上完美地工作起来了:

<custom-input v-model="searchText"></custom-input>
通过插槽分发内容:

和 HTML 元素一样,我们经常需要向一个组件传递内容,像这样:

<alert-box>
  Something bad happened.
</alert-box>

幸好,Vue 自定义的 <slot>元素让这变得非常简单:

Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})
动态组件

有的时候,在不同组件之间进行动态切换是非常有用的,比如在一个多标签的界面里:
上述内容可以通过 Vue 的 元素加一个特殊的 is attribute 来实现:

<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>

在上述示例中,currentTabComponent 可以包括:已注册组件的名字,或一个组件的选项对象

解析 DOM 模板时的注意事项

有些 HTML 元素,诸如 <ul><ol><table><select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li><tr><option>,只能出现在其它某些特定的元素内部。
这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

<table>
  <blog-post-row></blog-post-row>
</table>

这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is attribute 给了我们一个变通的办法:

<table>
  <tr is="blog-post-row"></tr>
</table>

需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:

  1. 字符串 (例如:template: '...')
  2. 单文件组件 (.vue)
  3. <script type="text/x-template">

写在最后

Vue的基础篇就到这里结束,下篇深入了解组件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值