记录一些Vue2笔记

744 阅读10分钟

Vue 2 笔记

介绍

Vue是一套渐进式框架,用来动态构建用户界面(view)。

基本认识

MVVM模式

M:model,数据对象(data中的数据)
V:view,模板页面(页面中所显示的内容),是动态的html页面
VM:VueModel,new 的Vue对象,也就是vm对象

模板页面(view)语法

双大括号表达式:显示数据

<!-- textContent  整个内容-->
<p>{{msg}}</p>

<!-- textContent  整个内容-->
<p v-text="msg"></p>  

<!-- innerHTML 标签内文本 -->
<p v-html="msg"></p>  

指令,以v-开头的自定义标签属性

强制数据绑定
v-bind:xxx=“yyy”
简写::xxx=“yyy”

<!-- 完整写法 -->
<img v-bind:src='imgUrl' alt=""> 
<!-- 简洁写法 -->
<img :src='imgUrl' alt="">  

绑定事件监听

v-on:事件名=“事件回调”
简写:@事件名=“事件回调”

<button v-on:click="callback">test1</button>
<!-- 可自定义参数 -->
<button @click="callback2('abc')">test2</button>
<!-- 还可传变量 -->
<button @click="callback2(imgUrl)">传变量</button>

计算属性与监视

计算属性

模板页面(view)适用于简单的声明式逻辑
计算属性是vm实例对象中的另一个配置对象,适用于复杂逻辑
默认计算属性
当计算属性中只有一个回调函数时,此回调函数默认是getter,可显示当前属性数据

// 此回调函数什么时候执行:1.初始化显示时执行,2.相关属性数据发生变化时
// 用来干什么:计算并返回当前属性的值
computed: { 
	//计算属性中的一个方法,方法的返回值为属性值,回调函数
    fullName1(){
        return this.firstName + '_' + this.lastName
    },
}
计算属性高级
通过getter(计算属性的get方法) 实现对属性数据的显示
通过setter(计算属性的set方法) 实现对属性数据的监视

computed:{
    fullName:{
        // 回调函数,计算并返回当前属性的值
        // 回调函数的特点:1.你定义的,2.你没有调用,3.但最终执行了
        // 回调函数用来干嘛的?什么时候被调用?
        // 执行:当需要读取当前属性值的时候回调,用处:根据相关的数据计算并返回当前属性的值
        get(){
            return this.firstName+' '+this.lastName
        },
        // 回调函数,监视当前属性值的变化,当属性值发生改变时回调,更新相关的属性数据
        //value就是fullName3的最新属性值
        set(value){
            // str.split()方法使用指定的分隔符字符串将一个str对象分割成子字符串数组
            const names = value.split(' ')//以空格分开
            this.firstName = names[0]
            this.lastName = names[1]
        }
}
// 调用get方法:
<h2>{{fullName}}</h2>
//调用set方法:
fn() {
	this.fullName = '略略略'
}

监视

可配置监视对象
可在在数据变化时执行异步或开销较大的操作

//配置监视,可用来响应数据的变化
watch:{
	//调用这个函数时说明firstName发生了变化
	//会接收两个参数:1.新的值 2.旧的值
    firstName:function(newVal, oldVal){
		//this就是vm实例对象
        console.log(this);
        this.fullName = newVal + ' '+ oldVal;
    }
}
调用$watch方法
// 所有vm实例对象的方法都以$符号开头
// 此方法与上面watch配置一样
vm.$watch("lastName",function(newVal, oldVal){
	this.fullName = newVal +' '+ oldVal
})
//需要有vm的实例 例如: const vm = new Vue();
计算属性和监视的区别
1. 计算属性基于响应式依赖来缓存,初始化执行一次,如果没有监测到数据变化,多次访问数据时,计算属性会立即返回之前的计算结果,所以它可利用缓存做大量的数据计算。

2. 只要数据变化,计算属性就会改变,比监听属性watch简单且方便。

3. watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

强制绑定class和style

class/style绑定可用来实现动态样式效果的技术
class绑定
class=‘xxx’
xxx可以是字符串、对象、数组

<p class="cClass" :class="a">xxx是字符串</p>
<!-- <p :class="{aClass:false,bClass:true}">xxx是对象</p>
	这样跟下面在data对象里设置isA的值为true是一样的 -->
<p :class="{aClass:isA,bClass:isB}">xxx是对象</p><!-- 用的多 -->
<p :class="['aClass','bClass']">xxx是数组</p>
style绑定
:style=’{color:activeColor,fontSize+“px”}’
其中activeColor/fontSize是data属性

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

条件渲染

条件渲染指令

v-if 如果if中条件为真,则以此处内容渲染页面
v-else 如果if中条件为假,则以此处内容渲染页面
v-show 如果此处属性值为真,则以此处内容渲染页面,如果属性为假,则隐藏

区别

v-if 隐藏时,是将标签移除,切换消耗高。在运行时如果条件很少改变,则用v-if
v-show 不移除,而是通过改变元素的css属性display来实现显示与隐藏。如果需要频繁切换,则用v-show

列表渲染

<ul>
    <li v-for="(p,index) in persons" :key="index">
        {{index}}--{{p.name}}--{{p.age}}
        <button @click="del(index)">删除</button>
        <button @click="update(index,{name:'cat',age:25})">更新</button>
    </li>
</ul>

<!-- v-for 可遍历数组、对象,并利用 key 管理可复用的元素 -->

<!-- key值 -->
因为 Vue 会尽可能高效地渲染元素,所以通常会复用已有元素而非从头开始渲染。
如果没有在两个可切换的输入框中分别加上唯一的key值,切换后,输入框中被输入的内容不会清除,会被复用
如果添加了key值,则向系统说明“这两个元素是独立的,不要复用他们”

事件处理

绑定监听

v-on:xxx=‘fn’
@xxx = ‘fn’
@xxxx = ‘fn(参数)’ , 默认事件形参:event (绑定监听时可不传参数event),隐含属性对象: $event

事件修饰符

<!-- 嵌套的元素,有事件冒泡,子元素的事件冒泡到父元素 -->
<div style="height: 200px;width: 200px;background-color: #bfa;" @click="test5">
    <div style="height:100px; width: 100px; background-color: tomato;" 	    		@click.stop="test6"></div>
</div>	
@xxx.stop
停止事件冒泡,相当于 event.stopPropagation()
@xxx.prevent
阻止事件的默认行为(a标签的自动跳转页面),相当于 event.preventDefault()
@xxx.passive
立即触发事件的默认行为,例如 scroll 滚动事件,提升移动端的性能
@xxx.once
点击事件只会触发一次
注意
在事件处理程序中调用 event.preventDefault() 等方法在js中很常见
但在 Vue 中要尽可能地只调用方法,代码只处理纯粹的数据逻辑,不处理 dom 事件
所以尽量少用事件修饰符来处理 dom 事件

表单输入绑定

<form action="/xxx" @submit.prevent="handleSubmit"><!-- 表单的原生方法onsubmit,提交表单 -->
    <span>用户名:</span> <input type="text" v-model="username"><br>
    <span>密码:</span><input type="password" v-model="password"><br>
</form>

v-model (双向数据绑定)自动收集数据,收集完之后就可使用ajax发送给后台

checkbox:

多选,收集到的数据为数组,data初始化数据时也要将其定义为数组,再为其写唯一的 value 值

radio:

单选,为每个选项写唯一的 value 值,后台收集的数据即 value 值

select:

下拉框,收集到的数据为数组,里面的元素为对象,包含标识符 id 和 name ,后台收集的数据为 id

vue 对象的生命周期

1. 初始化显示
   beforeCreate()
   created()
   beforeMount()
   mounted()

2. 更新显示
   beforeUpdate()
   updated()

3. 销毁 vue 实例
   beforeDestory()
   destoryed()

过滤器

<p>年月日:{{date | dateStr("YYYY-MM-DD")}}</p>

Vue.filter("dateStr",function(value,format){}
或者 
new Vue({
    filter: {
    	dateStr(date){}
	}
})

内置指令

常用内置指令

v:text:更新元素的 textcontent
v-html:更新元素的innerHTML
v-if:如果为 true,当前标签才会输出到页面
v-else:如果为 false,当前标签才会输出到页面
v-show:通过控制 display 样式来控制显示/隐藏
v-for:遍历数组/对象,最终列表显示
v-on:绑定事件监听,一般简写为@
v-bind:强制绑定解析表达式,可以省略v-bind
v-model:双向数据绑定
ref:指定唯一标识,vue 对象通过 $refs 属性访问这个元素对象
v-cloak:防止闪现,与css配合:[ v-cloak ] { display:none },v-cloak 这个指令会一直保持在元素上,直到关联实例结束编译。将其与css样式结合可隐藏有这个属性的标签,直到实例准备完毕,即数据加载完成后才显示
<!-- 不赋值,v-cloak默认为true -->
<p v-cloak>{{tt}}</p>
/* 属性选择器,有这个属性的元素的样式被设置为 */
[v-cloak]{
	display: none;
}

<p ref="text">{{tt}}~atguigu.com</p>
alert(this.$refs.text.textContent)

自定义指令

注册全局指令
/* "lower-text"为自定义的指令名 */
Vue.directive("lower-text",function(el,binding){ 
    el.innerHTML=binding.value.toLowerCase()
})
注册局部指令
new Vue({
     // 注册局部指令,配置一个对象
     // 局部指令,只在当前vm管理范围内有效,即选择器 #demo内
    directives:{
        /* 对象的属性名平时可不写引号,但此时属性名特殊有-连接,就需要引号 */
        "upper-text"(el,binding){
            el.innerHTML=binding.value.toUpperCase()
        }
}
使用指令
<p v-lower-text="msg1"></p>

插件

html文件中使用

引入插件库
将插件暴露在外,使其可用 window.myPlugin=myPlugin
声明使用插件 Vue.use(myPlugin)

vue 项目中使用

安装插件 npm i fastclick --save
main.js 中引入插件 import fastClick from ‘fastclick’
Vue.use(fastClick)

Vue项目的创建

Vue 脚手架 命令

1. ** npm install ** 安装依赖包
2. ** npm run serve ** 启动项目
3. ** npm bulid ** 项目打包,在命令行界面执行

安装

npm i webpack 项目文件名 ( vue-cli2 的创建方式)
或者 npm create 文件名 ( vue-cli3 的创建方式)

安装插件

npm i vuex --save ( --save 表示运行时也需要使用此插件,–save-dev 表示此插件只是开发时需要)
	vue-axios:发送ajax请求
    vue-router:路由
    vuex:状态管理
    vue-lazyload:图片懒加载
    vue-scroller, better-scroll:页面滚动相关
    mint-ui:基于 vue 的 UI 组件库(移动端)
    element-ui:基于 vue 的 UI 组件库( PC 端)

项目的运行

npm run dev (vue-cli2 的运行方式)
npm run serve ( vue-cli3 的运行方式)

项目的打包

在本地对当前项目进行编译打包,最终生成一个dist文件夹

项目的发布

使用静态服务器打包
npm i -g serve (静态服务器就叫 serve)
serve dist (运行 dist 文件夹)
访问:http://localhost:5000
使用动态web服务器(tomcat)
修改配置:webpack.prod.conf.js
output: { publicPath: ‘/xxx/’ (打包文件夹的名称) }
重新打包:npm run bulid
修改 dist 文件夹为项目名称:xxx
将 xxx 拷贝到运行的 tomcat 的 webapps 目录下
访问:http://localhost:8080/xxx

项目文件夹概览

<!-- 看整体文件作用 -->
1. build 和 config 文件都是配置文件夹
2. config 文件夹里的 index.js 文件
	有 port 端口号,两个项目运行时,要修改其中一个项目的端口号
	autoOpenBrowser 自动打开浏览器,改为 true
3. node_modules 依赖
4. src 文件夹是源码目录,写的代码都是包含在里面
	main.js 是入口文件,webpack.base.config.js 是它的配置
5. static 静态的,里面放一些全局的资源(样式、图片),可以在页面(index.html)里引用.gitkeep文件,专门	 为git服务的里面	
	git有一个特点,如果static文件夹什么都诶有,它会自动忽略
		如果不希望被忽略,则可以创建.getkeep文件,git就会将此文件夹版本控制起来
6. .babelrc文件
		balel可以用来将es6语法转换为es5语法,jsx语法转js语法
		jsx就是js+html,xml是html标签和一些自定义标签,可以看做js+html
	.babelrc文件就是描述babel是怎么运行的,也就是babel的配置文件
7. .eslintrc.js
	eslint的配置文件
8. .eslintignore文件
	eslint会默认会一些文件做检查,如果希望它忽略哪些文件,就可以在此文件中配置
9. index.html 主页
		其他的应用都是单页应用
10. package.json 文件
		当前应用的描述文件

eslint

eslint 是一个代码规范检查工具

配置

手动修改
在文件 .elintrc.js 中的 rules 配置对象中修改规则为 ‘off’ 或者 ‘0’, 例如:‘indent’ : ‘off’ 或者 ‘0’
修改配置完成,需重新运行项目 npm run dev
安装插件 Prettier 自动修复格式
<!-- 报错信息 -->
Missing semicolon 缺少分号
Missing space before opening brace 左大括号前缺少空格
Trailing spaces not allowed 不允许尾随空格
Unexpected trailing comma 意外的尾随逗号
Multiple spaces found before ‘+’ 在“+”之前找到多个空格
A space is required after ‘,’ “,”后需要空格
Expected indentation of 4 spaces but found 6 预期缩进4个空格,但找到6个
Infix operators must be spaced 中缀运算符必须间隔
‘title’ is never reassigned. Use ‘const’ instead “标题”从未重新分配。改用“const”

vue 组件

main.js

src 文件夹中的 main.js 文件是入口文件,用来创建 vue 实例

/* 这个文件是入口js:要创建Vue实例
*/
// 1.引入vue
import Vue from 'vue'
// 2.1引入App.vue
import App from './App.vue'

// 2.创建Vue实例
 new Vue({
    el:'#app', // 根据index.html文件
    // 将App.vue渲染到index.html中
    // 2.1.先引入App.vue
    // 2.2.映射标签名称
    components:{
        App
    }, 
    // 2.3 编译模板 ,内部的渲染函数会将模板挂载到html中去
    template:'<App/>'
})

App.vue

App.vue 是根组件,最终是将 App.vue 渲染到 index.html 中,所以要在 App.vue 中引入所有的子组件

组件

一个组件就是局部功能界面,局部功能界面里相关的所有资源(css/js/img…)都是组件的一部分

组件化编码的基本流程

页面显示 --> 用户操作
数据在哪个组件里,更新数据的行为(方法或函数)就必须定义在哪个组件里

拆分组件
实现静态页面框架
在静态页面中初始化数据(将数据在组件间传递)
实现动态组件:数据交互:用户点击提交、删除等
    确定数据是什么
    为数据定义一个名称,确定它的类型
    数据放到相应的组件中
    –此数据只有一个组件使用时,就放到那个组件里即可
    –此数据同时被几个组件使用,就需放到他们共同的父组件中
    –组件间通信

组件间通信

props

父传子,子再传给自己的子组件,一层一层传递

$emit

将子组件数据传递给父组件

$refs

只用于父组件直接访问子组件数据,不适用三层嵌套关系

消息订阅与发布

可用于多重嵌套组件间的数据传递,可直接从根组件将数据传递到任意嵌套的组件

安装插件pubsub

npm i pubsub-js --save

订阅消息
相当于绑定事件回调函数,可在初始化显示时订阅:PubSub.subscribe(‘eventName’,mes => {})

发布消息
相当于触发事件回调函数:PubSub.publish(‘eventName’,index)

slot 插槽

传递的数据是标签数据,组件标签被反复使用时适用
子组件模板预留多个插槽位置,多个占位,但占位本身不显示东西,由父组件决定展示什么内容
在子组件占位(布局),在父组件中插入标签数据并做样式调整(内容)

$bus 事件总线

// 将vue实例作为事件总线,监听不同组件间事件变化,使得组件间通信
Vue.prototype.$bus = new Vue() 
//在某个组件中发送事件
this.$bus.$emit("itemImageLoad") 
// 在某个组件中监听itemImageLoad图片加载事件
this.$bus.$on('itemImageLoad', this.itemImgListener)
destroyed () {
     // 离开组件时取消图片加载监听事件
     this.$bus.$off('itemImageLoad', this.itemImgListener)
},
......

mixin 混入

创建 mixin.js 封装重复的代码
export const itemListenerMixin = { 创建混入对象
     data()
     components:{}   可混入所有vm的配置对象
     methods: {}
 }
在需要的组件中导入
mixins:[itemListenerMixin]

将组件封装为插件

将 Toast.vue 组件封装为插件
在toast文件夹下创建 index.js
const obj = {}
 export default obj
main.js 中安装
import toast from 'components/common/toast' 
Vue.use(toast)
返回 index.js 中封装
[引入Toast组件,并将其创建为组件对象]
import Toast from './Toast'     
 const obj={}
 [调用Vue.use就是调用的对象的install方法函数] [默认会传一个Vue参数]
 obj.install=function(Vue){       
   [将Toast创建为组件构造器]
   const toastConstructor = Vue.extend(Toast)     
   [new组件构造器来创建一个组件对象]
   const toast = new toastConstructor()         
   [将组件对象手动地挂载到元素上]
   toast.$mount(document.createElement('div'))   
   [toast.$el对应的就是div,再将组件对象的模板添加进body里]
   document.body.appendChild(toast.$el)     
   [将组件对象添加进prototype中,方便其他组件使用:this.$toast]
   Vue.prototype.$toast = toast          
 }
[default是默认导出的obj,所以可以在导入时随便修改名字为toast]
 export default obj          

存储数据

sessionstorage

存储在内存中,当页面关闭时,数据就会被清除

localStorage

本地存储,将数据存储为文件,无论页面如何变化(关闭或刷新)都不会被清除数据,数据可长期保存