vue 从入门到精通之【vue数据视图】(一)
vue
Vue是"渐进式框架":vue.min.js只包含了vue的核心内容【例如:options api 、数据处理、template模板视图解析等操作】;真实项目中我们还会根据需求,导入
vuex实现公共状态管理
vue-router 实现SPA(single page application)单页面应用
element-ui/antdv/iview/vant/cube基于这些UI组件库快速创建项目
axios 实现数据通信
@vue/cli 基于vue的脚手架创建工程化项目
Vue是基于MVVM模式构建的框架,它本身实现了viewModel层实现监听数据/视图的变化,从而去渲染视图/修改数据。所有我们学习vue主要考虑两条主线:
- Model数据层
- View视图层
mvvm 和 mvc
- vue MVVM双向数据绑定
- angular (简称:ng) MVVM
- react MVC 单向数据绑定
虚拟 DOM
Model数据层
指定视图:3种方式
let vm = new Vue({
// 指定视图
el: "#app"
});
let vm = new Vue({});
vm.$mount('#app');
let vm = new Vue({
render:h=>{},
template: `
<div>
最后把数据渲染在这个视图中
</div>
`
});
构建数据模型【需要在视图中渲染数据】
- 设置的数据直接挂载到vm实例对象上,vm.msg;
- 挂载到实例上的东西能够直接在视图中使用;
- 后期更改数据,vue会监听到数据的更改,通知视图按照最新的数据重新渲染;我们把修改后视图会重新渲染的数据称之为响应式数据(状态)
let vm = new Vue({
// 指定视图
// el: "#app",
// 构建数据模型【需要在视图中渲染数据】
/*
(1)设置的数据直接挂载到vm实例对象上,vm.msg;
(2)挂载到实例上的东西能够直接在视图中使用;
(3)后期更改数据,vue会监听到数据的更改,通知视图按照最新的数据重新渲染;我们把修改后视图会重新渲染的数据称之为响应式数据(状态)
*/
data: {
msg: 'hello world1'
}
});
vm.text = 'zf';//也是挂到实例上 vm.text
vm.$mount('#app');
setTimeout(() => {
// 后期更改数据,vue会监听到数据的更改,通知视图按照最新的数据重新渲染;我们把修改后视图会重新渲染的数据称之为响应式数据(状态)
vm.msg = '111 world1';//修改msg值,并且重新渲染
// 修改后数据并不会重新渲染=>非响应数据
vm.text = '3231';//修改text
vm.$forceUpdate();//这个方法会强制让视图重新渲染
}, 1000)
响应式数据VS非响应式数据
- 都可以修改值
- 响应式数据在值修改之后,会通知视图重新渲染,因为其基于Object.defineProperty对其做了get/set劫持;当我们修改数据的时候,会触发set函数,在set函数中一方面会把值修改,一方面通知视图渲染;
在vue的项目中,我们只需要展开实例,看哪些数据做了get/set,做了劫持的数据就是响应数据。
new Vue的时候,在data中指定的数据,vue默认就会对其做了劫持处理,所有数据式响应式的;自己直接挂在实例上的式非响应式数据。
- 在vue开发中,我们把需要的数据一般都写在data中,(哪怕现在不用,我们也在data中初始化一下),目的是让这些数据变成响应式数据
- 而且对data中所有层级做深层次的监听劫持
- 对于数组来讲,数组本身会做劫持,但是数组中的每一个索引项并没有做劫持,如果内容是对象,还会做劫持;修改数组值会触发重新渲染vm.arr=100,修改数组堆内存中的信息,不会触发重新渲染vm.arr[0]=100
- vue为了解决这个问题,把数组中的7个方法(push/pop/shift/unshift/splice/sort/reverce)进行了重写,后期我们操作这7个方法,不仅可以修改数据中的某一项的内容,而且也会触发视图的重新渲染。
修改数据如何让视图重新渲染
vue.prototype
- vm.$forceUpdate();//这个方法会强制让视图重新渲染;
- vm.set([object],[key],[value]):针对于data中某个对象开始没有初始化某个属性,后期才加的(这个属性默认式非响应式的,该值视图不会重新渲染);$set可以在后续把对象中的这个属性设置为响应式的。
vue 实例
Vue 的实例:在入口文件中,基于 new Vue 创建的一个实例 “vm”
_vnode:编译完的虚拟 DOM 对象「最后 vue 内部会把这个虚拟 DOM 对象,基于 DOM-DIFF 后,变为真实的 DOM,插入到页面中」
$children:记录所有子元素/子组件的实例,它是一个数组
el:编译后的内容挂载到这个容器中 基于options:{el:'#app'}指定,或者基于vm.$mount('#app')指定
$attrs:
$listeners:
$options:存储当前实例的一些配置项 components / directives / filters / render ...
$parent:获取其父元素/父组件的实例
$refs:存储设置的所有的 ref 的值「通过 ref 获取 DOM 元素,直接操作 DOM,也可以基于它获取调用的子组件实例」
$root:根 DOM 元素/实例
$scopedSlots:存储所有的作用域插槽
$slots:存储所有的插槽
$data:所有观察的数据对象
$props:所有接收的属性对象
Vue视图层
template中存在大量的指令,用来构建视图和完成相关的效果
指令
v-text:把数据渲染到指定的容器中(真实开发中我们一般都是基于小胡子语法{{}}处理)v-html:可以识别html字符串,可以将字符串的标签进行渲染,其余两种方式只能当作字符渲染
v-html
v-show:[boolen]控制元素的显示隐藏(原理:控制display=none/block);不管结果是true还是false,元素都渲染出来了,只是display的值不同;
v-if:[boolen]也可控制元素的显示隐藏,和v-show不一样,如果值是false元素是不进行渲染的(页面中没有这个元素),只有结果是true元素才会进行渲染
---对于频繁控制显示隐藏的操作,我们应该使用v-show,如果使用v-if会频繁的创建和销毁,这样性能较差;非频繁操作下,我们可以使用v-if,这样对于v-if=false的元素可以不进行编译渲染,提高编译渲染的速度!!
v-else-if
v-else
v-for 「循环渲染的元素,需要设置唯一的key属性」
v-on 实现事件绑定「简写 @」事件="要执行的方法" 缩写:@事件="方法" 原理:基于DOM2事件绑定实现的 addEventListener【好处:后期自己获取这个DOM元素对象进行事件绑定,也不会和@click绑定的方法冲突】
v-bind 给某个属性动态绑定值 「简写 :」
v-model 表单元素实现双向数据绑定「监听视图的改变,控制数据更新」
a. 把状态值赋值给文本框的value
b. 基于input事件,监听文本框内容改变,当内容改变的时候,去修改对应的状态值
v-slot 插槽「简写 #」
[下面的两个指令可以做优化]
v-pre 编译的时候,有这个指令的元素/组件是无需进行编译的,真实项目中,我们完全可以把一些"静态内容"不进行任何编译,以此来优化视图编译的速度。
v-once 只有第一次元素/组件进行渲染,后期重新渲染的时候,直接跳过编译,不进行渲染,适用于第一次动态绑定,后期不会再更新的内容
v-cloak 在非工程化的vue项目中,在js没有加载出来之前,页面会呈现原始的语法({{}}),只有js加载完成,才能把template语法编译为真实DOM渲染到页面中;为了防止这种效果,在js没有编译之前是隐藏的,js编译完再让容器呈现出来,此时看到的都是编译好的效果。[v-colck]{display:none;}
小胡子语法
{{需要渲染的数据内容}}
事件和表单的修饰符
[事件] @click.stop.prevent="handle"
.stop 阻止冒泡传播
.prevent 阻止默认行为
.capture 在捕获阶段触发
.self 只有event.target事件源是本身自己操作的元素时候触发
.once 事件只执行一次,第一次执行完移除事件绑定
.passive
<div @click.self="handle">
<button>按钮</button>
</div>
//只有点击的元素是div,才会执行handle;点击button,因为冒泡传播机制,也会触发div的点击行为,但是因为设置了.self修饰符,所以handle不执行!!
按键修饰符 @keyup.enter
.enter 按下Enter键 改写为 .13
.tab
.delete
.esc
.space
.up
.down
.left
.right
还可以自定义按键修饰符 Vue.config.keyCodes.f1 = 112 -> @keyup.f1='handle'
基于系统修饰符,实现组合按键 @keyup.alt.67的意思是Alt+C
.ctrl
.alt
.shift
.meta
.exact 控制只有按下这个键才会触发「不能按其他键 精准控制」
[表单] input v-model.lazy='name'
.lazy 把v-model默认是基于input事件监听内容改变的,改为基于change事件监听
■ 【input】只要正在输入就会触发,不一定输入的内容进入到了文本框;
■ 【change】内容已经进入文本框,按下enter才会触发;比input性能消耗低,流畅度也低。
.number 把输入的值{字符串类型}转换为数字类型 文本框默认输入的内容是字符串,.number vue内部会把其变成数字【如果出现非有效数字,则会把其干掉】
.trim 去除字符串的首尾空格
select下拉框 v-model="city"
■ 拿city状态值和option中的value做比较,和谁一样,就默认选中谁
■ 拿监听下拉框的change事件,选中的是谁,就把哪一项的value赋值给city状态
在radio单选框中 v-model="sex"
■ 会把v-model 状态值相同的作为同一组,一组中只能选中一个【可以自己设定name】;
■ 会根据sex状态值和value值做对比,相同的则有选中状态;
■ 监听每一个radio的change事件,把选定radio的value值赋值给状态sex
在checkbox单选框中 v-model="hobby"
给元素设置样式 class style
- :class="{box:true,active:true/false}" active是class的样式类名,它的值true/false决定元素是否拥有这个样式类名;
- :class="['box',num>10?'active':'']";
- style="color:red" :style="color:'red',fontSize:num>10?'20px':'14px'"