1.v-if和v-show的区别?它们的使用场景?
vue中的 v-if 和 v-show 二者都可以动态的控制元素的隐藏和显示,但是他们控制的原理是不同的。
v-if
v-if 控制元素显示或隐藏是把dom元素整个的渲染或者删除,如果删除,也就是页面中不存在这个dom元素,以此达到隐藏的效果;所以v-if在每次切换的时候都会重新创建或者销毁元素,有较高的切换性能消耗;而且v-if是惰性的,如果在初始渲染时条件为假,那就什么也不做,直到条件第一次变为真时,需要渲染时才会开始渲染条件块。
v-show
v-show则是无论你的初始条件是什么,元素都会被渲染,就是dom元素始终是存在的,v-show只是简单的基于css切换;因此它拥有比较高的初始渲染消耗;
使用场景
如果元素需要进行比较频繁的切换的话,推荐使用v-show,
如果很少用到切换,或者元素可能永远都不会显示出来的话,就使用v-if
2.Vue实例是怎么拿到data属性的?
详细看:https://www.jianshu.com/p/9f15c58124cf
看一段简单代码先:
new Vue({
el:"#myApp",
data:{
userName:"laoWangTou",
age:16
},
methods:{
run(){
// 输出结果:laoWangTou今年16岁了
console.log(this.userName+"今年"+this.age+"岁了");
}
},
created(){
// this为什么可以调用methods的run方法?
this.run();
}
})
对于以上代码可能会有两个小疑问:
1、为什么钩子函数中的 this.run 可以调用到methods对像下的方法run?
2、为什么methods对象下的run方法可以通过this获得data下的属性?
要弄明白这两个问题首先你要明白下面几个点:
1.this即是通过Vue生成的实例vm
const vm = new Vue({
el:"#myApp",
created(){
console.log(vm === this);// true
}
})
2.$data与data是相等的
const data ={};
const vm = new Vue({
el:"#myApp",
data,
created(){
console.log(this.$data === data);// true
}
})
console.log(vm.$data === data);// true
3.$data的属性被修改,vm实例下的属性也会发生相应的变化
const vm = new Vue({
el:"#myApp",
data:{
userName:"laoWangTou",
age:16
},
created(){
this.$data.userName = "xiaoZhang"
this.$data.age = 18;
// 输出结果:xiaoZhang今年18岁了
console.log(this.userName+"今年"+this.age+"岁了");
}
})
// 输出结果:xiaoZhang今年18岁了
console.log(vm.userName+"今年"+vm.age+"岁了");
通过之前的两个疑问及得到的个结论,咱们可以先来个小猜测:
1、在实例化Vue的时候设置属性$data,用来接收对象的data值
2、vm实例中代理了data的属性
3、methods下的方法赋值给了vm实例
于是,结合Vue.js的源码模拟出了以下较易理解的代码:
// 定义了一个构造函数
function Vue(options) {
this.$data = options.data || {};
this.initState(options);
}
Vue.prototype.initState = function (opts) {
if(opts.data)
this.initData(opts.data);
if(opts.methods)
this.initMethods(opts.methods);
if(opts.created)
opts.created.call(this);
}
Vue.prototype.initData = function (data) {
var keys = Object.keys(data);
var i = keys.length;
while (i--){
const key = keys[i];
this.proxy("$data",key);
}
}
Vue.prototype.initMethods = function (methods) {
for (var key in methods) {
this[key] = methods[key];
}
}
Vue.prototype.proxy =function(sourceKey, key) {
Object.defineProperty(this, key, {
get() {
return this[sourceKey][key]
},
set(val){
this[sourceKey][key] = val;
}
});
};
3.created 和 mounted区别?
created:是在模板渲染成HTML前调用的,此时data已经准备完毕,el仍是undefined,因为没有渲染成HTML,所以不能操作dom节点,它主要用来初始化一些数据;
mounted:是在模板渲染成HTML之后调用的,此时data,el都已准备好,可以操作html的dom节点,可以通过id什么的来查找页面元素,也可以加载一些组件什么的;
4.inject与provide的作用?
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。它可以用来子组件访问父组件对象实例。provide
选项允许我们指定我们想要提供给后代组件的数据/方法。
它与$parent有什么区别?
通过this.$parent只能访问父级的属性方法,如果想访问父级的父级就要this.$parent.$parent。这样就比较麻烦,因此在两级以上推荐使用依赖注入。