目录
十七、怎么定义vue-router的动态路由?怎么获取传过来的值?
一、对MVVM的理解
MVVM核心思想,是关注model的变化,让MVVM框架利用自己的机制自动更新DOM,也就是数据-视图分离,数据不会影响视图。
MVVM是Model-View-ViewModel的缩写
- Model是代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
- View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
- ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
MVVM采用双向数据绑定,view中数据变化将自动反映到viewmodel上,反之,model中数据变化也将会自动展示在页面上。把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。
二、vue实现双向数据绑定
在表单元素中通过v-model指令把用户输入的值和data(模型)中的数据进行绑定,页面输入的内容时发生变化,data(模型)中的数据会发生变化,如果是data中的数据发生变化,页面(视图)也会相应做出相应的变化。
三、vue组件
3.1什么是组件
组件(component)是vue.js最强大的功能之一。组件的作用就是封装可重复使用的代码,通常一个组件就是一个功能体,便于在多个地方都能够调用这个功能体。 每个组件都是Vue的实例对象。 我们实例化的Vue对象就是一个组件,而且是所有组件的根组件
3.2全局注册组件
注意点
- 组件中的data是一个函数,不是对象
- 组件中必须有一个唯一的根元素
- 模板中内容较多时候建议使用模板字符串
3.3局部注册组件
注意
- 局部注册的子组件只能在注册过的父组件中使用
- components是注册组件的意思
四、v-show和v-if的区别
元素的显示和隐藏
v-show渲染出来的是标签是样式display:none和display:block进行切换
v-if是页面渲染这个结构显示还是隐藏
v-if是是否渲染显示出来,v-show是已经渲染了,切换了display:none属性。
如果页面频繁切换的时候,考虑到性能问题,推荐使用 v-show
五、vue生命周期
在vue中,vue的生命周期是指,从创建vue对象到销毁vue对象的过程。
5.1钩子函数
钩子函数是vue框架中内置的一些函数,随着vue的生命周期阶段,自动执行
阶段 | 方法名 | 方法名 |
---|---|---|
初始化 | beforeCreate | created |
挂载 | beforeMount | mounted |
更新 | beforeUpdate | updated |
销毁 | beforeDestroy | destroyed |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="message = 'Hello world'">点击</button>
<h3 id="h3">{{message}}</h3>
</div>
<script>
const vn = new Vue({
el: '#app',
data(){
return {
message: 'Hello Vue!'
}
},
methods:{
show(){
console.log('执行了show函数');
}
},
beforeCreate(){ //这是我们遇到的第一个生命周期函数 表示实例完全被创建出来之前,会执行它
// console.log(this.message);
// this.show()
// 注意:在beforeCreate生命周期函数执行时,data和methods中的数据还没被初始化
},
created(){ // 这是遇到的第二个生命周期函数
// console.log(this.message);
// this.show()
// 在created中,data和methods都已经被初始化好了
// 如果要调用methods中的方法,或者操作data中的数据,只能在created中操作
},
beforeMount(){ //这是遇到的第三个生命周期函数,表示 模板已经在内存中编译完成了,
//但是尚未把模板渲染挂载到页面中
// console.log(document.getElementById('h3').innerHTML);
// 在beforeMount执行的时候,页面中的元素还没有被真正替换过来,只是之前写的一些模板字符串
},
mounted(){ //这是遇到的第四个生命周期函数, 表示内存中的模板,已经真实的挂载到页面中,
//用户已经可以看到渲染好的页面
// console.log(document.getElementById('h3').innerHTML);
//注意mounted是实例创建期间的最后一个生命周期函数,当执行完mounted,实例就已经完全被创建好了
//此时如果没有其它操作的话 这个实例就静静的躺在我们的内存中 一动不动
},
// 接下来是运行中的两个事件 (只有页面内容发生改变时才会触发!!!!@!!)
beforeUpdate(){ //这时候,表示 我们的界面还没有被更新 (但是数据已经是更新了!@!!!!)
// console.log('页面上的数据是'+document.getElementById('h3').innerHTML);
// console.log('此时的message数据是'+this.message);
// 得出结论: 当执行beforeUpdate的时候 页面中的显示的数据,还是未更新的
// 此时data数据已经是最新的了,页面尚未和最新数据保持同步
},
updated(){
console.log('页面上的数据是'+document.getElementById('h3').innerHTML);
console.log('此时的message数据是'+this.message);
// updated事件执行的时候,页面和data的数据已经保持同步了 都是最新的
}
})
</script>
</body>
</html>
六、绑定class的用法
1、对象方法 v-bind:class="{'orange': isRipe, 'green': isNotRipe}"
2、数组方法v-bind:class="[class1, class2]"
3、行内 v-bind:style="{color: color, fontSize: fontSize+'px' }"
七、计算属性computed和监听器watch的区别
当有一些数据需要随着另外一些数据变化时,建议使用computed。
当有一个通用的响应数据变化的时候,要执行一些业务逻辑或异步操作的时候建议使用watcher。
计算属性是在模板语法中做一些相对复杂些的逻辑
监听器一般用于执行异步操作或者比较消耗性能的时候,主要是用于监听data中的数据变化。
八、vue路由
8.1路由的基本使用步骤
- 添加路由链接<router-link>
- 添加路由填充位<router-view>
- 定义路由组件
- 配置路由规则并创建路由实例
- 把路由挂载到vue根实例中
8.2路由传参
声明式传参
(1)params传参
-显示参数
在url中会显示出传参的值,刷新页面不会失去拿到的参数,使用该方式传值的时候,需要在路由提前配置好参数:
路由传参
<router-link to="/home/1">Home</router-link> |
路由规则定义
{
path: "/home/:id",
name: "Home",
component: Home
}
Home页面接收传递的参数:
mounted() {
console.log(this.$route.params.id);
}
-不显示参数
在url中不会显示出传参的值,但刷新页面会失去拿到的参数,使用该方式 传值 的时候,需要子路由提前配置好name参数:
App.vue中定义传递参数
<router-link :to="{name:'Home',params:{id:1}}">Home</router-link> |
路由规则中配置好规则
{
path: "/home",
name: "Home",
component: Home
}
在Home页面通过下面的方法接收参数
mounted() {
console.log(this.$route.params.id);
}
(3)query传参
query 传过去的参数会拼接在地址栏中(?name=xx),刷新页面数据不会丢失,使用path和name都可以:
App.vue中通过path和name两种方式都可以传参
<router-link :to="{path:'/home',query:{id:1}}">Home</router-link>
<router-link :to="{name:'Home',query:{id:1}}">Home</router-link> |
路由规则中配置好规则
{
path: "/home",
name: "Home",
component: Home
}
在Home页面如下接受参数:
mounted() {
console.log(this.$route.query.id);
}
3.6.2 编程式传参
(1)params传参(显示参数)
路由规则配置如下:
{
path: "/about/:id",
name: "About",
component: About
}
在显示路由跳转的页面,添加按钮和事件,处理逻辑如下:
比如在Home.vue添加跳转逻辑
<button @click="handle(1)" >跳转</button>
methods: {
handle(id) {
this.$router.push({
path: `/about/${id}`
});
}
}
那么在About页面接收的方法如下:
mounted() {
console.log(this.$route.params.id);
}
(2)query方式传参
路由规则如下:
{
path: "/about",
name: "About",
component: () => import("../views/About.vue")
}
- 编程式路由path方式
Home.vue中定义
<button @click="handle" >跳转</button>
methods: {
handle() {
this.$router.push({
path: "/about",
query: {
id: 1
}
});
}
}
About.vue中定义
mounted() {
console.log(this.$route.query.id);
}
- 编程式路由name方式
Home.vue中
<button @click="handle" >跳转</button>
methods: {
handle() {
this.$router.push({
name: "About",
query: {
id: 1
}
});
}
}
About.vue中接受参数
mounted() {
console.log(this.$route.query.id);
}
九、vue与Angular和React的区别?
9.1与AngularJS的区别
相同点:
都支持指令:内置指令和自定义指令;
都支持过滤器:内置过滤器和自定义过滤器;
都支持双向数据绑定;
都不支持低端浏览器。
不同点:
AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;
在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;
Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。
9.2 与React的区别
相同点:
React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;
中心思想相同:一切都是组件,组件实例之间可以嵌套;黑化的要考!
都提供合理的钩子函数,可以让开发者定制化地去处理需求;
都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;
在组件开发中都支持mixins的特性。
不同点:
React采用的Virtual DOM会对渲染出来的结果做脏检查;
Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。
十、事件修饰符
10.1.stop阻止事件冒泡
<style>
#big {
width: 100px;
height: 100px;
background-color: red;
}
#small {
width: 50px;
height: 50px;
background-color: yellow;
}
</style>
</head>
<body>
<div id="app">
<div id="big" @click="fn1">
<!-- .stop是阻止事件冒泡的修饰符 -->
<div id="small" @click.stop="fn2"></div>
</div>
</div>
</div>
<script>
var vue = new Vue({
el: "#app",
data: {
info: ''
},
methods: {
fn1: function() {
console.log('大盒子被点击了')
},
fn2: function() {
console.log('小盒子被点击了')
},
}
});
</script>
</body>
10.2.prevent是阻止默认行为的修饰符
<!-- .prevent是阻止默认行为的修饰符 -->
<a href="https://www.baidu.com" @click.prevent="fn3">跳转</a>
10.3.enter和.delete
<div id="app">
<input type="text" v-model="info" @keyup.enter="fn4">
<input type="text" v-model="info" @keyup.delete="fn5">
</div>
<script>
var vue = new Vue({
el: "#app",
data: {
info: ''
},
methods: {
fn4: function() {
console.log(this.info)
},
fn5: function() {
this.info = ''
}
}
});
</script>
按回车输出到控制台,按delete键删除
十一、组件中data为什么是函数?
因为组件是用来复用的,JS 里对象是引用关系,这样作用域没有隔离,而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。
十二、对于vue是一套渐进式框架的理解
渐进式代表的含义是:主张最少
Vue可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用。
也可以整个用它全家桶开发,当Angular用。
还可以用它的视图,搭配你自己设计的整个下层用。
你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。
十三、vue.js的两个核心是什么?
数据驱动和组件化
十四、vue中key值的作用
key的作用主要是为了高效的更新虚拟DOM。
使用key来给每个节点做一个唯一标识,另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
十五、v-for和v-if的优先级
v-for的优先级比v-if高
十六、组件
16.1vue中子组件调用父组件的方法
第一种方法是直接在子组件中通过this.$parent.event来调用父组件的方法。
第二种方法是在子组件里用
$emit
向父组件触发一个事件,父组件监听这个事件就行了。第三种是父组件把方法传入子组件中,在子组件里直接调用这个方法。
16.2vue中父组件调用自组件的方法
父组件利用ref属性操作子组件方法。
16.3vue组件传值
父传子
步骤:
1、父组件定义数据
2、父组件通过属性的方式给子组件传递数据
3、子组件通过props属性接受数据并做参数设置
4、子组件使用传递过来的数据
子传父
步骤:
1、子组件绑定事件
<button @click='childClick'>点击</button>
调用this.$emit方法传递数据,第一个参数是自己定义的事件名,第二个参数是传递的数据
2、父组件监听传递的事件childhandle
3、父组件中对监听的事件做处理,拿到传递的数值再在页面显示或其他处理。
十七、怎么定义vue-router的动态路由?怎么获取传过来的值?
动态路由的创建,主要是使用path属性过程中,使用动态路径参数,以冒号开头,如下:
{
path: '/details/:id'
name: 'Details'
components: Details
}
当匹配到/details下的路由时,参数值会被设置到this.$route.params下,所以通过这个属性可以获取动态参数
this.$route.params.id
十八、vue-router有哪几种路由守卫
全局守卫:beforeEach
后置守卫:afterEach
全局解析守卫:beforeResolve
路由独享守卫:beforeEnter
十九、$route和$router的区别是什么?
$route 是路由信息对象||跳转的路由对象,每一个路由都会有一个route对象,是一个局部对象,包含path,params,hash,query,fullPath,matched,name等路由信息参数。
$router为VueRouter的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等。