01-Vue 介绍 以及 学习总结(这里不详细展开)
作者:尤雨溪
Vue.js 是一套构建用户界面的 渐进式框架。
Vue中文网
Vue3中文文档
vue-router
vue-cli
Vue介绍:
特点:MVVM框架、双向数据绑定原理、数据驱动、易学、轻量、组件化、简洁、高效、模块友好
MVVM框架:Model(模型) View(视图) View Modle(视图数据)
- V:html界面
- M:存数据的
- VM:通过视图去操作数据,也能通过数据操作视图(双向数据绑定),是数据和界面的调度者
拓展 MVC:Model View Control (模型、视图、控制器) 代表框架 - react
Vue和angular简单对比:
Vue----简单,易学,弱主张,只要会点html、css、js,加点vue的思想就能学会(自由)
- 指令以v-xxx,属性方法均挂在Vue的实例上,适用于移动端项目
angular---学习曲线陡峭,框架粘性很强(强主张)只要一开始用,那么这个项目就要一直用它,不能喝别的框架耦合。
- 指令以ng-xxx,属性方法均挂在$scope上,适用于pc端项目
均不支持IE8以下版本
vue 对比 react 的优势:
API设计上简单,语法简单,学习成本低
基于依赖追踪的观察系统,并且异步队列更新
简单的语法及项目搭建 ,更快的渲染速度和更小的体积
渲染性能:
渲染用户界面的时候,dom的操作成本是最高的,那为了尽可能的减少对dom的操作,Vue和React都利用虚拟DOM来实现这一点,但Vue的Virtual DOM实现(一个陷阱的叉子)的权重要轻得多,因此比React的引入开销更少。
Vue 和 React 也提供功能性组件,这些组件因为都是没有声明,没有实例化的,因此会花费更少的开销。当这些都用于关键性能的场景时,Vue 将会更快。
更新性能:
在react中,当一个组件的状态发生变化时,它将会引起整个组件的子树都进行重新渲染,从这个组件的根部开始。那为了避免子组件不必要的重新渲染,您需要随时使用shouldComponentUpdate,并使用不可变的数据结构。 在Vue中,组件的依赖关系在它的渲染期间被自动跟踪,因此系统准确地知道哪些组件实际上需要重新渲染。这就意味着在更新方面,vue也是快于React
开发中:
在开发中,Vue 每秒最高处理 10 帧,而 React 每秒最高处理不到 1 帧。这是由于 React 有大量的检查机制,这会让它提供许多有用的警告和错误提示信息。vue在实现这些检查时,也更加密切地关注了性能方面。
Vue 学习总结
这里记录了学过的内容,想自学Vue,把下面内容都学一遍。由于篇幅问题,这里不详细展开
插值表达式
两个由花括号组成{{ }}
,vue 会在编译过程中,对插值表达式进行编译。
定义 公共组件 和 私有组件
当前学习了几个 Vue 提供的标签了?分别的作用是什么?
<component></component>
:空标签(占位符)通常和:is="组件名"
一起使用,在react中有<React.Fragment></React.Fragment>
<template></template>
:在被控制的 #app 外面,使用 template 元素,定义组件的模板结构。<div id='app2'>
<login></login>
</div>
<template id='tmpl2'>
<h1>定义一个 template 私有组件 login</h1>
</template>
const vm2 = new Vue({
el: "#app2",
components: { // 定义实例内部私有组件
login: {
template: '#tmpl2'
}
},
});
<transition></transition>
:使用 transition 元素,把需要被动画控制的元素,包裹起来(详情查看vue-动画)。<transition-group></transition-group>
:给通过 v-for 循环渲染出来的列表添加动画。<router-view></router-view>
:这是 vue-router 提供的元素,专门用来,当作占位符的,将来路由规则,匹配到的组件就会展示到这个 router-view 中去。所有,我们可以吧 router-view 认为是一个占位符
<router-link to='/'></router-link>
:默认渲染成 a 标签,可通过 tag 属性设置渲染的标签类型,类似 react 中的import { Link } from 'react-router';
<Link to='/'></Link>
vue 的指令是什么?自带的指令有哪些?
- v-cloak: 使用 v-cloak 能够解决 插值表达
<p>{{ msg }}</p>
式闪烁的问题。(闪烁?一瞬间出现字符串{{ msg }}
,而不是解析后的内容) - v-text: 使用 v-text , 是没有闪烁问题的,应为在标签中没有写任何内容。
- v-html: 可以解析字符串中的 html 标签,插值表达式 和 v-text 不行。
- v-bind: 绑定属性机制,简写
:
。 - v-on: 事件绑定机制,简写
@
,语法:v-on:不带on的事件='注册的函数'
,举例:v-on:mouseover="showFn"
。 - v-for: 可循环遍历数组,对象,渲染出来的标签,记得使用
:key
。 - v-model: 双向数据绑定,通常用在 表单元素。
- v-if、v-else、v-slse-if:就是字面意思,可用来判断需要渲染的标签,每次都会重新删除或创建元素,有较高的切换性能消耗。
- v-show:每次更新不会重新进行DOM的删除和创建操作,只是切换了元素的 display: none 样式,有较高的初始渲染性能消耗。
- v-if、v-show、:is 作用类似,都可以完成组件的切换。按具体的业务需要,酌情使用。
- v-slot:插槽,缩写:
#
- v-once:不需要表达式,只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
- v-pre:不需要表达式,跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。示例:
<span v-pre>{{ this will not be compiled }}</span>
不会编译 插值表达式,最后显示出来的内容将是{{ this will not be compiled }}
- ...
自定义全局指令和私有指令
过滤器(私有过滤器、全局过滤器)的注册和使用
修饰符(事件修饰符、按键修饰符、自定义按键修饰符)
特殊 attribute(属性)
- is
- ref
- key
- ...
vue 实例上的属性和生命周期函数
const vm = new Vue({ el: "#app",
data: { // 数据状态
firstName: "",
lastName: "",
// fullName: "",
},
methods: { // 私有方法
show() {
this.fullName = this.firstName + "-" + this.lastName;
},
},
watch: { // 监听属性
// 当 firstName 发生改变的时候,触发对应的函数。
firstName: function (newVal, oldVal) {
this.show();
},
lastName: function () {
this.show();
}
},
computed: { // 计算属性
// 当函数中的所使用到的数据状态发生改变,触发函数。
fullName() {
return this.firstName + "-" + this.lastName;
}
},
filters: { // 私有过滤器
},
directives: { // 注册私有指令
},
components: { // 定义实例内部私有组件
},
router, // 将路由规则对象,注册到 vm 实例上,用来监听 URL 地址变化,然后展示对应的组件。
store, // 将 Vuex.Store 的实例,注册到 vm 实例上。
beforeCreate() {
// 在此生命周期函数执行的时候,data 和 methods 中的数据都还没有被初始化
},
created() {
// 在此生命周期函数执行的时候,data 和 methods 中的数据都被初始化好了。(请求数据,关闭loading状态)
},
beforeMount() {
// 模板已经编译完成,尚未渲染到页面中去
},
mounted() {
// 表示内存中的模板已经真实挂载到页面中,用户可以看到渲染好的页面了(DOM渲染之后,可以获取页面的元素(主要是数据生成出来的元素))
// mounted 是实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了。
},
beforeUpdate() {
// 状态更新之前执行此函数,此时 data 中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始从新渲染DOM节点。
},
updated() {
// 实例更新完毕之后调用此函数,此时 data 中的状态值和界面是哪个显示的数据,都已经完成了更新,界面已经被重新渲染好了。
},
beforeDestroy() {
// 实例销毁之前调用,在这一步,实例任然完全可用。(关掉定时器、状态的初始化)
clearTimeout(this.timer)
},
destroyed() {
// 实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器都会被移除,所有的字实例也会被销毁。
}
})
注意:组件上的属性,基本上和实例是一致的。但是也有不同,主要看一下不同点
不同点:
- 组件的 data 是个函数,返回一个对象,对象里才是数据,而实例的 data 就是一个对象。
- 组件:多了一个 props 属性,来接收父级传递过来的数据。
- name 属性:
+ 只有作为组件选项时起作用,
+ 允许组件模板递归地调用自身。注意,组件在全局用 Vue.component() 注册时,全局 ID 自动作为组件的 name。
+ 指定 name 选项的另一个好处是便于调试。有名字的组件有更友好的警告信息。
name: "temp", data() {
return {
msg: '这是组件中的 data 定义的数据',
num: 1
}
},
props: ["父级传过来的数据"],
.vue 文件的学习
在项目中,每一个 .vue 文件都是一个 vue 组件。它包含了三个部分 template、script、style,分别写 html、js和css。
举个例子:
<template> <div class="child">
<p>子组件</p>
<span>来自 {{ msg }} </span>
<input type="button" value="点击修改父级数据" @click="change('子组件')" />
<p>{{ $store.state.msg }}:{{ $store.state.num }}</p>
<input type="button" value="vuex.num + 1" @click="$store.commit('add', 1)" />
<Grandson :msg="msg" @change="change"></Grandson>
</div>
</template>
<script>
import Grandson from "./Grandson";
export default { // 必须有`export default {}`不然保存
name: "Child",
data() {
return {
msg: "组件自身的数据",
};
},
methods: {
change(param) {
this.$emit("change", param);
},
},
components: {
Grandson,
},
props: ["msg"],
};
</script>
<style lang="less" scoped>
/*
这里安装了less和less-loader,使用属性 lang 来加载。
使用scoped之后样式只影响组件自身,这样可以避免影响到其他组件,如果不加该样式作用范围是全局的。
*/
.child {
width: 80%;
height: 80%;
background-color: lightsteelblue;
position: absolute;
right: 0;
bottom: 0;
margin: auto;
}
</style>
但有时候我们需要改变其他组件的样式,比如 比较常见的 引入第三方组件 , 我们需要修改样式时,就需要用到深度选择器
如 >>> , 有些像Less, Sass 之类的预处理器无法正确解析 >>>,这种情况下你可以使用 /deep/ 代替,效果是一样的
.a >>> .b { /* ... */ }.a /deep/.b { /* ... */ }
深度选择器的作用范围是本组件及其所有子组件孙组件。。。
问题:加了scoped再使用深度选择器有时候会失效,如element的tooltip组件,因为此时第三方组件的DOM结构在vue挂载点之外了,加了scoped即使 使用深度选择器也不会起作用。
解决办法:这个时候在单文件组件中可以写两个style标签,一个加scoped 一个不加, 把需要修改样式的第三方组件css放在不加scoped的标签就可以了。详情也可查看文档相应内容
<style>/* 全局样式 */
</style>
<style scoped>
/* 本地样式 */
</style>
以上是 01-Vue 介绍 以及 学习总结(这里不详细展开) 的全部内容, 来源链接: utcz.com/z/377823.html