Vue介绍
Vue基础
知识点
- Vue常用指令
- Mixin混入
- Vue生命周期qianduan
前端开发环境配置
Vue的开发形式有多种,有script标签引入的形式,也有脚本架启动Web服务的形式。
本阶段我们采用脚手架的形式学习,在此先全局安装@vue/cli,如下:
npm i @vue/cli@4.1.1 -g
或者:
npm install -g vue-cli
下载完成后,通过如下指令查看安装版本:
vue --version
或者
vue --v
通过次脚手架初始化一个Vue项目:
vue create demo1
按照步骤都选择Yes 或者默认的便可,新建项目需要一些时间。
新建完成后,我们需要修改一下配置,找到node.modules/@vue/cli-service/lib/options.js路径下该文件,直接在devServer中添加disableHostCheck: true

通过如下命令启动 demo1 项目:
cd demo1
npm run serve
待项目启动后,点击右侧边栏[Web 服务],打开浏览器如下所示,说明开发环境配置成功了:

清空App vue 文件里面的代码,我们开始Vue指令。
v-text && v-html
- 相同点
都能展示数据,且属于单项绑定。即数据的变化会影响插值的变化,而插值的变化,不会影响数据的变化。其实v-text也可以简写为{{}}。
- 不同点
v-text:只能渲染纯文本,浏览器不会对其进行html解析。
v-html:用于输出 html,浏览器会解析 html。
下面通过代码实例来验证,打开App vue代码如下:
1 <template> 2 <div id="app"> 3 <p>{{ text }}</p> 4 <p>{{ html }}</p> 5 <p v-text="html"></p> 6 <P v-html="html"></p> 7 </div> 8 </template> 9 10 <script> 11 export default { 12 name 'App', 13 data(){ 14 return{ 15 text:‘大家好,我是木头魂’, 16 html:‘<strong>大家好,我是壮壮的木头魂</strong>’, 17 } 18 } 19 } 20 </script> 21 <style></style>
v-if、 v-else && v-show
- 相同的
通过变量控制标签内容的显示或隐藏。
- 不同点
v-if 在浏览器上表现为整个DOM 节点不会被渲染;
v-show的呈现形式相当于给DOM节点添加了一个CSS属性——display:none;
v-else则类似 JS 语法的if else判断语句,需要紧跟在v-if后面。
下面通过代码实例来验证,APP vue代码如下:
1 <template> 2 <div id="app"> 3 <p v-if="isShow">我是十三1</p> 4 <p v-else>我是十三2</p> 5 <p v-if="!isShow">我是十三1</P> 6 <p v-else> 我是十三2</p> 7 <p v-show="!isShow">我是消失的十三</p> 8 </div> 9 </template> 10 <script> 11 export default{ 12 name:'App', 13 data(){ 14 return { 15 isShow:true, 16 }; 17 } 18 }; 19 </script> 20 <style></style>
浏览器展示效果如下:

v-for
v-for指令解决的是模板循环渲染问题,没有Vue、React等框架之前都是通过 for 循环拼接字符串的形式,通过
Append 将拼接好的节点塞入指定的DOM 节点。现在有了v-for指令,就不用这么麻烦了,得到数组之后,只需以(
item,index)in array的形式渲染数据。
下面是代码演示:
<template> <div id="app"> <div v-for="(item,index) in list";key="index"> {{ index }}{{ item }}</div> </div> </template> <script> export default{ name:‘App’, data(){ return{ list:['小红','小明',‘小智’,‘小明’], }; }, }; </script> <style></sttle>
浏览器效果如下:

index 数组对象所对d应的索引值,渲染模板的时候如果需要做一些逻辑运算的时候,会用到这个索引值,比如只让索引值为偶数的项进行渲染,就可以结合之前的v-if、v-show指令去实现需求。
小知识1:v-for和v-if不要一起用
v-for优先级高于v-if,当它们处于同一个的节点,v-for的优先级比v-if更高,这意味着v-if将重复运行于每个v-for循环。比较好的解决方案是,先通过computed属性将需要渲染的列表提前过滤,再将过滤后的列表放到模板中渲染,这样做的目的是让页面渲染效率更高,避免不必要的资源浪费。
小知识2:v-for 可以渲染Object类型数据
比如上述例子我们可以改变如下:
<template> <div id="app"> <div v-for="(val,key,index) in listobj" : key="index"> {{ index }}{{ val.name }} </div> </div> </template> <script> export default { name: 'App', data() { return{ listObj;{ hong:{ name:'小红', } ming:{ name:‘小明’, } zhi:{ name:‘小智’, } gang:{ name:'小刚', }, }, }; }, }; </script> <style></style>
v-on
v-on 就是监听事件,可以用v-on指令监听DOM事件来触发一些方法函数。
v-on有一种简写形式,用 @ 符号代替。它还能监听一些键盘事件,如键盘的回车键v-on:keyup.enter等,可以类推其他的键盘事件。
下面看代码示例:
<template> <div id="app"> <p>数字:{{ count }},</p> <button v-on;click="add">加</button> <input v-model="username" y-on;keyup,enter="login" /> </div> </template> <script> export default { name:'App', data() { return { count :1, username: ' ', }; }, methods:{ add: function (){ this.count++; }, login:function (){ console.log(this.username); } } }; </script> <style></style>
效果如下:

键盘事件一般用作输入框,用户名或密码的输入回车事件监听。
v-model
在 Vue 的众多指令里,v-model 算是举足轻重的,因为它的双向绑定特性,能解决很多业务上的复杂需求,下面就用几个小示例来诠释它的强大,代码演示如下:
<template> <div id="app"> <p>用户名:{{ username }}</p> <input v-model="username" /> </div> </template> <script> export default { name: 'App', data() { return { username: '', }; }, }; </script> <style></style>

2.结合复选框
<template> <div id="app"> <h2>checkbox</h2> <label for="apple">苹果</label> <input type="checkbox" v-model="fruit.apple" value="apple" /> <label for="banana">香蕉</label> <input type="checkbox" v-model="fruit.banana" value="banana" /> <br /> {{ fruit }} </div> </template> <script> export default { name: 'App', data() { return { fruit: { apple: true, banana: false, }, }; }, }; </script>
<style></style>

结合复选框实现切换复选框内的值,动态地改变数据
3.结合单选框
<template> <div id="app"> <h2>radio</h2> <label for="male">男</label> <input type="radio" v-model="sex" value="男" /> <label for="female">女</label> <input type="radio" v-model="sex" value="女" /> <br /> {{ sex }} </div> </template> <script> export default { name: 'App', data() { return { sex: '男', }; }, }; </script> <style></style>

4、几个需要注意的修饰符
- .lazy:接管 input 的事件监听事件,输入的时候不会马上响应在展示层,当数据确认改变的时候才会显示出来;
- .trim:去掉首尾的空格,不会去除中间的空格;
- .number:输入的字符串转化为数字;
v-bind 、v-cloak、v-pre && v-once
v-bind
对变量属性的一个绑定,比如说需要绑定一个图片只需如下:
<img v-bind:src="imageSrc" /> // 可简写为 <img :src="imageSrc" />
绑定 CSS 样式,一般用在需要计算表达式的时候使用:
<div :class="className">绑定class</div> // 判断变量 <div :class="{classA: isShow}">绑定class中的判断</div> // 三元运算符 <div :class="isShow ? classA : classB">绑定class中的三元表达式判断</div> // 绑定 style <div :style="{color: blue, fontSize: font}">绑定style</div>
v-cloak
作用:在使用双大括号赋值时,页面数据没有返回之前,页面会闪烁一下 '"{{}}"'双大括号,只需在全局样式下添加如下:
[v-cloak] {
display: none;
}
在绑定的变量节点上加上 :
<div id="app" v-cloak> {{msg}} </div>
注意:Vue 1.x 和 Vue 2.x 中 v-cloak 的用法是不同的。Vue1.x 中,允许将 Vue 实例挂载在 body 上,而 Vue2.x 是不允许的,想对整个页面实例化,需要另外用一个 div 来容纳整个页面内容,对其进行实例化。
v-pre
直接跳过 Vue 的编译,输出原始值。在标签中如下使用:
<div v-pre>{{message}}</div>
最终在网页上输出的结果是 {{message}}。
v-once
只在第一次渲染时执行,之后的操作都被视为静态内容,跳出之后的所有渲染过程。
<template> <div id="app"> <p v-once>用户名:{{ username }}</p> <input v-model="username" /> </div> </template> <script> export default { name: 'App', data() { return { username: '十三', }; }, }; </script> <style></style>
全局 API:
举个比较好理解的例子,Vue 就好比一块蛋糕,生命周期钩子函数以及内部指令可以理解为做蛋糕用的面粉、糖、鸡蛋等。而全局 API 就是裹在蛋糕外面的奶油,让整个蛋糕(Vue)看起来更加美味。全局 API 的作用就是给 Vue 更多的自由,可以根据项目的需求,通过全局 API 来制作出各种各样的方法工具。
Vue.directive 自定义组件
之前也学了 v-model、v-show 等官方定义的指令,在项目的开发过程中,我们会有一些特殊的需求,要自定义指令,Vue.directive 就是为什么做这件事情的 API。
自定义组件
假如来了一个需求,需要让加上 v-color 指令的标签的字体颜色通过传入的变量值进行改变,比如 v-color="red" 标签就会变为红色。
代码演示如下,这里注意,继续沿用上一阶段环境,进入 App.vue:
<template> <div id="app"> <p v-color="color">嘻嘻哈哈</p> </div> </template> <script> export default { name: 'App', data() { return { color: 'red', }; }, }; </script> <style></style>
在 main.js 下添加如下代码:
import Vue from 'vue'; import App from './App.vue'; Vue.config.productionTip = false; Vue.directive('color', function (el, binding, vnode) { console.log('el', el); // 被绑定的node节点 console.log('binding', binding); // 一个对象,包含指令的很多信息 console.log('vnode', vnode); // Vue编译生成的虚拟节点 el.style = 'color:' + binding.value; }); new Vue({ render: (h) => h(App), }).$mount('#app');
浏览器效果如下所示:

回调函数参数
自定义组件的回调函数有三个参数。
- el:被绑定的node节点。
- binding:包含指令信息的对象参数。
- vnode:Vue编译生成的虚拟节点。
自定义组件的生命周期
自定义组件包含几个生命周期,也就是在调用自定义组件时,几个钩子函数会被触发,分别是如下:
- bind:只调用一次,在第一次绑定到元素上时被调用,初次化操作可以使用。
- inserted:被绑定的元素插入了父节点。
- update:被绑定的元素模板更新时调用。
- componentUpdated:被绑定的元素模板完成一次生命周期。
- unbind:指令和被绑定元素解绑时调用。
Vue.set全局操作
在解释Vue.set之前先了解一下 Vue的响应式原理:
当你把一个JS对象传给Vue实例的data属性时,Vue将遍历此对象的所有属性,并使用Object.defineProperty 把这些属性全部转为getter/setter。Object.defineProperty是ES5中一个无法shim的特性,这也就是为什么VUe不支持IE8以及更低版本的浏览器。
为什么要使用 Vue.set
受限于现代浏览器,Vue 检测不到对象的添加和删除;因为 Vue 在初始化实例时对 data 属性执行 getter/setter 转化操作,所以对象必须在 data 中才能让其响应式。
Vue 不允许在已经创建的实例上动态添加新的根级响应式属性,不过可以使用 Vue.set 方法将响应式属性添加到嵌套的对象上。代码演示如下
<template> <div id="app"> <p v-for="(item, index) in fruit" :key="index">{{ item }}</p> <button v-on:click="change">变</button> {{ fruit }} <button v-on:click="add">外部添加</button> </div> </template> <script> export default { name: 'App', data() { return { fruit: ['apple', 'banana', 'pear', 'grape'], }; }, methods: { change() { this.fruit[1] = 'melon'; }, add() { // Vue.set 的另一种写法 this.$set this.$set(this.fruit, 1, 'melon'); }, }, }; </script> <style></style>
浏览器效果如下所示:

当点击按钮“变”的时候,渲染没有变化,当点击按钮“外部添加”的时候,渲染数据发生了变化。
Vue.filter
全局过滤器是一个在项目中时常会用到的 API,使用场景也非常丰富,比如说数据的统计,保留小数点参数等
下面我们演示一个简单的过滤器,需求是使用过滤器将需要过滤的目标值加上 4,代码演示如下:
App.vue
<template> <div id="app"> <p>{{ count | sum }}</p> </div> </template> <script> export default { name: 'App', data() { return { count: 20, }; }, }; </script> <style></style>
main.js
import Vue from 'vue'; import App from './App.vue'; Vue.config.productionTip = false; Vue.filter('sum', function (value) { return value + 4; }); new Vue({ render: (h) => h(App), }).$mount('#app');
浏览器预览:

屏幕上会出现 24 这个数字,注意的是,声明 sum 过滤器,必须要放在声明实例 app 之前,否则不会被注入到实例中。
Vue.nextTick
nextTick 是一个比较重要的高级特性,应用场景在很多地方会出现。Vue 是异步渲染的框架,一开始就是如此,当你改变 data 属性内部的变量,视图不会立即更新,在此时你若是进行 DOM 操作,是拿不到最新的渲染结果,这个时候你就要借助 Vue.nextTick 高级特性,在该特性的回调函数内获取最新的渲染结果。
使用方法
this.$nextTick(function () { // 写在需要在某个操作改变 dom 结构之后 });
Mixin 混入
混入(mixin)提供了一个非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包括任意组件选项。当组件使用混入对象时,所有混入对象的选项将被「混合」进入该组件本身的选项。
上面这段摘录自 Vue 的官方文档,文字有点难理解,笔者通过举实例来解释 mixin 的具体用法。 其实我们可以用 Object 的思想去理解 mixin,假设有一个变量 A,它的值为 { a: 1, b: 2 },有另一个变量 B,它的值为 { a: 3, c: 4 },B 作为混入的对象混入 A,那么 A 中已有的属性 a 不会被覆盖,A 会新增一个 c 属性,最终 A 为 { a: 1, b: 2, c: 4 }。
实例
通过 Vue 的代码进行分析如下:
// mixin.js export default { data() { return { username: '张三', age: 30, hasWife: true, }; }, mounted() { console.log('mixin'); }, methods: { speak() { console.log('这是mixin'); }, cry() { console.log('这是cry'); }, }, }; // App.vue import mixin from './mixin'; export default { data() { return { username: '李四', age: 31, hasHusband: true, }; }, mounted() { console.log('app'); }, mixins: [mixin], methods: { speak() { console.log('这是app'); }, eat() { console.log('吃饭'); }, }, };
// 最终得到的结果如下 export default { data() { return { name: '李四', // name为共有属性,最终保留 app.vue 的 age: 31, // 同上 hasHusband: true, // app.vue 独有属性,保留 hasWife: true, // app.vue 没有的属性,会被添加进来 }; }, mounted() { // 在钩子函数中的,会被合并到 app.vue 的钩子函数中,minix中的代码会在前面 console.log('mixin'); console.log('app'); }, methods: { // 两边都有的方法,会被封装为一个数组,先执行 minix 中的,后执行 app 自己的 speak() { [ function () { console.log('这是mixin'); }, function () { console.log('这是app'); }, ].forEach((cb) => { cb(); }); }, // 自身独有的,保留 eat() { console.log('吃饭'); }, // 自身没有的方法,会被添加进来 cry() { console.log('这是cry'); }, }, };
上述为组件中使用 mixins 方法进行「混入」,下面我们来介绍「全局混入」,「混入」可以在入口页进行全局注册,但是使用它时要格外小心,一旦使用全局混入,它将会影响每一个之后创建的 Vue 实例。 官方示例如下:
// 为自定义的选项 'myOption' 注入一个处理器。 Vue.mixin({ created: function () { var myOption = this.$options.myOption; if (myOption) { console.log(myOption); } }, }); new Vue({ myOption: 'hello!', }); // => "hello!"
Vue 生命周期函数
- beforeCreate:在组件创建之前。
- created:在组件创建之后,一般用于初始化一些固定的数据。
- beforeMount:DOM 节点渲染之前。
- mounted:在 DOM 节点渲染完之后被触发,通常笔者都会在这个生命周期中通过 ajax 去获取服务端的数据,如果在 created 生命周期里获取数据并渲染视图,DOM 节点可能还未被渲染,有可能页面会报错,安全起见,数据统一放在 mounted 钩子函数内获取。
- beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
- updated:当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用 计算属性 或 watcher 取而代之。
- activated:被 keep-alive 缓存的组件激活时调用。
- deactivated:被 keep-alive 缓存的组件停用时调用。
- beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
- destroyed:实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。一般用于销毁页面内创建的
setTimeout等变量,防止内存泄漏。
每个生命周期都值得被深入研究,有兴趣可以对 Vue 的源码进行阅读分析。

浙公网安备 33010602011771号