vue是一个响应式的前段视图层框架。
响应式:我们在编写模版代码时,仅需关注数据变化即可,数据变化,ui即会变化
视图层:类似我们接触的其他前端模版,仅仅是ui层面的内容
框架:库提供由其父代码调用的功能,而框架定义整个应用程序的设计。开发人员不调用框架,而是调用库,相反,框架以某种特定方式调用和使用代码。
1、vue.js的简单demo
例子1:
<div id='app'>
<p>Message is: {{ message }}p>
<input v-on:input="onInput" v-bind:value="message">input>
div>
<script>
var app = new Vue({
el:'#idd',
data:{message},
methods:{
onInput(e) {
this.message = e.target.value;
}
}
})
script>
例子2:
<div id='app'>div>
<script>
new Vue({
el: '#idd',
template: `hello world!
`,
componts:{}
//或者引入组件,在template里使用
created() {
this.$log();
}
})
script>
2、vue.js引入
vuejs有多种引入方式。
1)、直接引用vue.js,适合小型项目获部分使用vue
引入全部vuejs,运行时编译及渲染;引入部分vuejs,仅引入渲染部分
2)使用vue-cli工程化启动整个vue项目
{{}}是模版中用于动态显示数据的,它接受一个表达式,这里注意一下表达式和语句的区别。ifelse或者一行表达式后面跟着分号就是一个语句,一个方法,一个变量就是表达式。
1、标签中的属性
v-bind:我们能将data中的值绑定到当前属性中,可简写为:
v-on:能够绑定实例中配置的事件,可简写为@
v-for:列表级渲染,迭代渲染所有子元素
v-if/v-else/v-show:控制子元素视图显隐
v-model:应用于表单,创建与元素的双向绑定,v-model内部绑定了input方法
v-html:将最终的值结果渲染为html
v-text:等同于直接在文本处使用{{}}
2、 a t t r s , attrs, attrs,listeners,inheritAttrs, s l o t s , slots, slots,props
a t t r s : 包含了父作用域中不被认为 ( 且不预期为 ) p r o p s 的特性绑定 ( c l a s s 和 s t y l e 除外 ) 。当一个组件没有声明任何 p r o p s 时,这里会包含所有父作用域的绑定 ( c l a s s 和 s t y l e 除外 ) ,并且可以通过 v − b i n d = ” attrs: 包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 props 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=” attrs:包含了父作用域中不被认为(且不预期为)props的特性绑定(class和style除外)。当一个组件没有声明任何props时,这里会包含所有父作用域的绑定(class和style除外),并且可以通过v−bind=”attrs” 传入内部组件——即它适合在中间层组件,将接收的父组件绑定的所有除了自己的props声明的属性之外的属性,然后传递给子组件。
l i s t e n e r s : 包含了父作用域中的 ( 不含 . n a t i v e 修饰器的 ) v − o n 事件监听器。它可以通过 v − o n = ” listeners: 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=” listeners:包含了父作用域中的(不含.native修饰器的)v−on事件监听器。它可以通过v−on=”listeners” 传入内部组件——和attrs类似。
inheritAttrs:
默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrs 到 false,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 $attrs 可以让这些特性生效,且可以通过 v-bind 显性的绑定到非根元素上。
inheritAttrs:默认值 true,继承所有的父组件属性(除 props 的特定绑定)作为普通的HTML特性应用在子组件的根元素上,如果你不希望组件的根元素继承特性设置 inheritAttrs: false ,但是 class 属性会继承。(简单的说,inheritAttrs:true 继承除 props 之外的所有属性;inheritAttrs:false 只继承 class style 属性)
上述特性的使用完全可以降低在不使用Vuex以及事件总线的情况下,组件跨级props以及事件传递的复杂度。
inheritAttrs例子:
<script>
<template>
<div class="parent">
<child-component aaa="1111"></child-component>
</div>
</template>
<script>
import ChildComponent from './child'
export default {
components: {
ChildComponent
}
}
</script>
<script>
<template>
<div class="child">子组件</div>
</template>
<script>
export default {
inheritAttrs: true,
mounted() {
console.log('this.$attrs', this.$attrs)
// 当inheritAttrs为true时:输出this.$attrs, {a: "1111"}
// 当inheritAttrs为false时:输输出this.$attrs, {a: "1111"}
// 所以可以看出来$attrs值与inheritAttrs无关
}
}
</script>
元素结果:如果自组件props接受了aaa则不会有对应这句话:默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。如果你不希望组件的根元素继承特性设置 inheritAttrs: false ,但是 class 属性会继承。
例子 a t t r s 和 attrs和 attrs和listeners:
a组件
<template>
<div id="app">
<!-- 此处监听了两个事件,可以在B组件或者C组件中直接触发 -->
<child1 :pchild1="child1" :pchild2="child2" :pchild3="child3" @method1="onMethod1" @method2="onMethod2"></child1>
</div>
</template>
<script>
import Child1 from "./Child1.vue";
export default {
data() {
return {
child1:'1',
child2: 2,
child3:{
name:'child3'
}
};
},
components: { Child1 },
methods: {
onMethod1(msg1) {
console.log(`${msg1} running`);
},
onMethod2(msg2) {
console.log(`${msg2} running`);
},
},
};
</script>
child1:
<template>
<div class="child-1">
<h2>in child1</h2>
<p>props: {{ pchild1 }}</p>
<p>$attrs: {{ $attrs }}</p>
<hr/>
<!-- 通过 v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
<!-- C组件中能直接触发test的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
<child2 v-bind="$attrs" v-on="$listeners"></child2>
</div>
</template>
<script>
import Child2 from "./Child2.vue";
export default {
data() {
return {
child1:'child1'
};
},
components: { Child2 },
props: {
pchild1:{
type:String
}
},
inheritAttrs: false,
mounted() {
this.$emit("method1",this.child1);
},
};
</script>
child2:
<template>
<div class="child-2">
<h2>in child2:</h2>
<p>props: {{ pChild2 }}</p>
<p>$attrs: {{ $attrs }}</p>
<p>pchild3Name: {{ $attrs.pchild3.name }}</p>
<hr/>
</div>
</template>
<script>
export default {
data() {
return {
child2:'child2'
};
},
props: {
pChild2:{//注意这是大写,父组件传递过来的是小写,所以这里它没有值,且attr里有pchild2属性
type:String,
}
},
inheritAttrs: false,
mounted() {
this.$emit("method2",this.child2);
},
};
</script>
结果就是子组件里的 a t t r s 会获取父组件绑定的属性,子组件设置了 p r o p s 就会剔除这个 p r o p s 的属性, attrs会获取父组件绑定的属性,子组件设置了props就会剔除这个props的属性, attrs会获取父组件绑定的属性,子组件设置了props就会剔除这个props的属性,attrs里不会包含这个属性。 l i s t e n e r s 是获取父组件绑定的所有监听方法。比如 c h i l d 1 自己加属性进行绑定和加监听事件, c h i l d 2 的 listeners是获取父组件绑定的所有监听方法。比如child1自己加属性进行绑定和加监听事件,child2的 listeners是获取父组件绑定的所有监听方法。比如child1自己加属性进行绑定和加监听事件,child2的attr和 l i s t e n e r 是包含祖父组件和 c h i l d 1 组件的属性和监听方法,因为 c h i l d 1 进行 b i n d 和 v − o n 了。所以中间组件要记得 v − b i n d = " listener是包含祖父组件和child1组件的属性和监听方法,因为child1进行bind和v-on了。所以中间组件要记得v-bind=" listener是包含祖父组件和child1组件的属性和监听方法,因为child1进行bind和v−on了。所以中间组件要记得v−bind="attrs" v-on="$listeners"才能传递父组件的属性和方法给孙子组件。
s l o t s : t h i s . slots:this. slots:this.slot.default是子组件获取默认插槽的节点内容,如果是具名插槽,则是this.$slot.xxx来获取,这个在render函数里获取比较方便
$props:子组件内部接受的所有在父组件绑定的属性除了class,style除外。
3、compute属性
⼤部分时候,我们在模版也就是 html 中写表达式会让模版变得复杂,所以我们可以通过计算属性来简化我们的模版。
但⼤多数时候,我们也可以通过定义⽅法的形式来直接在表达式内调⽤函数。不过计算属性也可以模拟出使⽤参数的形式,计算属性和方法相比:
1)computed属性有惰性依赖,如果它内部依赖的值没有变化,它就不会进行计算,而方法只要ui进行渲染就会重新触发计算,即便变化的不是自己的值
2)computed不可以传值进去,function可以
4、组件
区分有状态组件与⽆状态组件
⼤部分时候,我们需要区分⼀些具有副作⽤的组件,例如某些组件我们需要发送 ajax 请求之后渲染⼀些数据,这时候我们就需要将这部分数据内容进⾏⼀个区分,推荐做法将 UI 部分渲染于⼦组件中,做⼀个只通过传⼊数据渲染的⽆状态组件,⽽在有副作⽤组件中维护所有的数据。
创建:beforeCreate->create->beforeMount->mounted->beforeDestory->destoryed
data数据改变时:beforeUpdate->updated
activated:
当页面重新显示的时候,执行。搭配 keep-alive、localStrage 和临时变量做页面性能优化。
deactivated:
当页面即将被隐藏或替换成其他页面时,执行。可以用来解绑在 activated 上绑定的全局事件。
注意:只有当组件在
内被切换,才会有activated 和deactivated 这两个钩子函数。keep-alive是用来缓存组件的,即组件在第一次进入进行创建后再次切换路由进出不会进行创建销毁,只会触发activated和deactivated两个钩子函数,它还提供include和exclude属性配置对应的组件名称(可以是export下的配置的name属性)即可只保留该组件进行缓存和对该组件不进行缓存的操作。
父组件和子组件的创建:
父beforeCreate->父create->父beforeMount->子beforeCreate->子create->子beforeMount->子mounted->父mounted;
销毁:父beforeDestory->子beforeDestory->子destoryed->父destoryed
update:父beforeUpdate->子beforeUpdate->子updated->父updated