vue基础知识汇总
vue基础知识汇总
一、简介
1.vue是一套用于构建用户界面的渐进式JavaScript框架
2.特点:
- 采用组件化模式,提高代码复用率、且让代码更好维护
- 声明式编码,让编码人员无需直接操作DOM,提高开发效率
- 使用虚拟DOM+优秀的Diff算法,尽量复用DOM节点
二、安装
- 包含完整的警告和调试模式:https://yuejs.org/js/vue.js
- 删除了警告, 30.96KB min+gzip:https://vuejs.org/js/vue.min.js
直接用<script>
引入,Vue被注册为一个全局变量
<script type="text/javascript" src="../js/vue.js"></script>
三、使用
//root容器里面的代码被称为“vue模板”
<div id="root">
<h1>hello,{{name}}</h1>
</div>
//第一种写法
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip = false
new Vue({
//el用于指定当前vue实例为哪个容器服务,值通常为css选择器字符串
el:'#root',
//data用于存储数据,数据供el所指定的容器去使用
data:{
name:"元元元"
}
})
</script>
//第二种写法
<script type="text/javascript">
const vm = new Vue({
data:function(){
//这里的this是vue实例对象vm
return{
name:"xxx"
}
}
})
v.$mount('#root')
</script>
//第三种写法
<script type="text/javascript">
const vm = new Vue({
data(){
//这里的this是vue实例对象vm
return{
name:"xxx"
}
}
})
v.$mount('#root')
</script>
//第四种写法
<script type="text/javascript">
const v = new Vue({
data:()=>{
//这里的this是全局window对象
return{
name:"xxx"
}
}
})
v.$mount('#root')
</script>
- vue实例和容器是一一对应的
- 真实开发中只有一个vue实例,而且会配合着组件一起使用
- {{xxx}}中写js表达式,且xxx可以自动读取到data中的所有属性,一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新
四、指令
内置指令
- v-bind : 单向数据绑定,可简写为:xxx
- v-model : 双向数据绑定
- v-for : 遍历数组/对象/字符串
- v-on : 绑定事件监听,可简写为@
- v-if : 条件渲染(动态控制节点是否存存在)
- v-else : 条件渲染(动态控制节点是否存存在)
- v-show : 条件渲染(动态控制节点是否展示)
- v-text :
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别: v-text会替换掉节点中的内容,{{xx}}则不会。 - v-html:
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v- html可以识别html结构。
3.严重注意: v-html有安全性问题! ! ! !
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html.永远不要用在用户提交的内容上! - v-cloak(没有值) :
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xx}}的问题。 - v-once(没有值):
1.v-once所在节点在初次动态渲染后,就视为静态内容了
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。 - v-pre:
1.跳过其所在节点的编译过程。
2.可利用它跳过没有使用指令语法、没有使用插值语法的节点,会加快编译。
<style>
[v-cloak]{
display:none;
}
</style>
<div id="root">
<h2 v-cloak>{{name}}</h2>
</div>
<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js”></script>
自定义指令
Vue模板语法有2大类:
1.插值语法:
功能:用于解析标签体内容。
写法: {{xxx}}, xxx是js表达式,且可以直接读取到data中的所有属性。
2. 指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)。
举例: v-bind:href-“xxx” 或简写为 :href=“xxx”, xxx同样要写js表达式,且可以直接读取到data中的所有属性。
备注: Vue中有很多的指令,且形式都是: v-??? 此处我们只是拿v-bind举个例子。
定义语法:
(1).局部指令:
new Vue({
directives:{指令名:配置对象}
})
或
new Vue({
directives{指令名:回调函数}
})
(2).全局指令:
Vue.directive(指令名,配置对象)
或Vue .directive(指令名,回调函数)
配置对象中常用的3个回调:
(1).bind:指令与元素成功绑定时调用。
(2).inserted:指令所在元素被插入页面时调用。
(3).update:指令所在模板结构被重新解析时调用。
三、备注:
1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词。要使用kebab-case命名方式,不要用camelCase命名。
<div id="root">
<h2>当前的n值是: <span v-text="n"></span> </h2>
<h2>放大10倍后的n值是: <span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
Vue.directive('fbind',{
bind(){
},
inserted(){
},
update(){
}
})
Vue.directive('big',function(element,binding){
element.innerText=binding.value*10
})
new Vue({
el:'#root',
data:{
n :1
},
directives:{
//big函数何时会被调用?
//1.指令与元素成功绑定时(一上来)
//2.指令所在的模板被重新解析时。
big(element,binding){
//这里的this是window
element.innerText=binding.value*10
},
fbind:{
//指令与元素成功绑定时(一上来)
bind(){
//这里的this是window
},
//指令所在元素被插入页面时
inserted(){
//这里的this是window
},
//指令所在的模板被重新解析时
update(){
//这里的this是window
}
}
}
})
</script>
五、模板语法
- 插值语法
//功能:用于解析标签体内容。
//写法: {{xxx}}, xxx是js表达式,且可以直接读取到data中的所有属性。
<a href="">{{url}}</a>
- 指令语法
//功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。
//v-bind:href="xxx"或:href="xxx", xxx同样要写js表达式,
//可以直接读取到data中的所有属性。
<a v-bind:href="url"></a>
//v-bind可以简写成:
<a :href="url"></a>
六、数据绑定
- 单向数据绑定
//数据只能从data流向页面
<input type="text" v-bind:value="name"/>
- 双向数据绑定
//v-model只能应用在表单类元素
<input type="text" v-model:value="name"/>
//v-model:value可以简写为v-model
<input type="text" v-model="name"/>
七、理解MVVM模型
- M: 模型(Model) :对应data中的数据
- V: 视图(View) :模板
- VM: 视图模型(ViewModel) : Vue 实例对象
- data中所有的属性,最后都出现在了vm身上。
- vm身上所有的属性及Vue原型上所有属性。在Vue模板中都可以直接使用。
八、数据代理
Object.defineProperty(person,'age',{
value:18,
enumerable:true, //控制属性是否可以枚举,默认为false
writable:true,//控制属性是否可以被修改
configurable:true, //控制属性是否可以被删除
//读取person的age属性时,get函数(getter)就会被调用
get:function(){
return 'hello'
}
//修改person的age属性时,set函数(setter)就会被调用
set(value){
return 'world'
}
})
数据代理:通过一个对象代理对另一个对象中属性的操作
- Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
- Vue中数据代理的好处:更加方便的操作data中的数据
- 基本原理:
通过object.defineProperty()把data对象中所有属性添加到vm上。
为每个添加到vm 上的属性,都指定一个getter/setter 。
在getter/setter内部去操作(读/写) data中对应的属性。
let obj1 = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj1.x
}
set(value){
obj1.x = value
}
})
九、事件处理
事件的基本使用:
1.使用v-on:xxx或@xxx绑定事件。其中xxx是事件名
2.事件的回调需要配置在methods对象中,最终会在vm上;
3. methods中配置的函数,不要用箭头函数!否则this就不是vm了;
4. methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象;
5. @click=“demo” 和 @click="demo($event)"效果一致。但后者可以传参;
<div id="root">
<button v-on:click="showInfo1">按钮</button>
<button @click="showInfo2($event,66)">按钮</button>
</div>
<script type="text/javascript>
new Vue({
el:"#root",
data:{
},
methods:{
showInfo1(event){
//这里的this是vm
console.log(event.target.innerText)
},
/*
showInfo:(event)=>{
//这里的this是window对象
}
*/
showInfo2(event,number){
alert(number);
}
}
})
</script>
十、事件修饰符
Vue中的事件修饰符:
1.prevent:阻止默认事件
2.stop: 阻止事件冒泡
3.once:事件只触发一次
4.capture:使用事件的捕获模式:
5.self:只有event.target是当前操作的元素时才触发事件
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
<div id="root">
<button @click.prevent="showInfo">按钮</button>
</div>
<script type="text/javascript">
new Vue({
el:"#root",
data:{
},
methods:{
showInfo(){
}
}
})
十一、键盘事件
<div id="root">
<input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo"/>
</div>
<script type="text/javascript"/>
Vue.config.productionTip=false;
new Vue({
el:"#root",
data:{
},
methods:{
showInfo(e){
//if(e.keyCode !== 13) return
console.log(e.target.value)
}
}
})
</script>
- Vue中常用的按键别名:
回车=>enter
删除=>delete (捕获“删除”和“退格”键)
退出=>esc
空格=>space
换行=>tab (必须配合keydown使用)
上=>up
下=>down
左=>left
右=>right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)(CapsLock=>caps-lock)
3.系统修饰键(用法特殊) : ctrl、alt、shift、 meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐),该特性已经从Web标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持
5. Vue.config.keyCodes.自定义键名=键码,可以去定制按键别名
十二、计算属性
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了0bjcet.defineProperty方法提供的getter和setter.
3. get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods 实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
(1).计算属性最终会出现在vm上,直接读取使用即可。
(2).如果计算属性要被修改。那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生变化
<div id="root">
姓:<input type="text" v-model="firstName"/>
名:<input type="text" v-model="lastName"/>
全名:<span>{{fullName}}</span>
</div>
<script type="text/javascript>
new Vue({
el:"#root",
data:{
firstName:"张",
lastName:"三"
},
computed:{
fullName:{
//get什么时候调用?
//1.初次读取fullName时(计算属性会被缓存)
//2.所依赖的数据发生变化时
get(){
//这里的this是vm
return this.firstName+this.lastName;
},
//set
set(value){
const arr=value.split('-')
this.firstName=value[0]
this.lastName=value[1]
}
}
}
})
</script>
//简写方式 (只读不写)
computed:{
fullName(){
return this.firstName+this.lastName;
}
}
十三、监视属性
监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作
2.监视的属性必须存在才能进行监视! !
3.监视的两种写法:
(1) new Vue时传入watch配置
(2) 通过vm.$watch监视
<div id="root">
<span>今天天气很{{info}}</span>
<button @click="weatherChanged">切换天气</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
isHot:true
},
methods:{
weatherChanged(){
this.isHot=!this.isHot
}
},
computed:{
info(){
return this.isHot?'炎热':'凉爽'
}
},
//方法一
watch:{
isHot:{
immediate:true,//初始化时让handler调用一次
//handler在isHot改变时被调用
handler(newValue,oldValue){
xxx
}
}
//简写(只有handler时)
/*
* isHot(newValue,oldValue){
* xxx
* }
*/
}
})
</script>
//方法二
vm.$watch('isHot',{
immediate:true,
handler(newValue,oldValue){
xxx
}
})
/*
* 简写:
* vm.$watch('isHot',function(newValue,oldValue){
* xxx
* })
*/
//深度监视
//(1)Vue中的watch默认不监测对象内部值的改变(一层)
//(2)配置deep :true可以监测对象内部值改变(多层)。
//备注:
//(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
//(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
<div id="root">
<button @click="numbers.a++">加1</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
numbers:{
a:1,
b:2
}
},
watch:{
//监视多级结构中全部属性的变化
numbers:{
deep:true,
handler(newValue,oldValue){
xxx
}
},
//监视多级结构中某个属性的变化
"numbers.a":{
immediate:true,//初始化时让handler调用一次
//handler在isHot改变时被调用
handler(newValue,oldValue){
xxx
}
}
}
})
</script>
十四、computed和watch之间的区别
- computed能完成的功能,watch都可以完成。
- watch能完成的功能,Computed不一定能完成,例如: watch可以进行异步操作。
两个重要的小原则:
1.所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数、promise的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象。
十五、绑定class样式
:class=“xxx” xxx可以是字符串、对象、数组。
<div id="root">
<!--绑定class样式,字符串写法,适用于样式的类名不确定,不需要动态指定-->
<div class="basic" :class="normal" @click="changeMood">{{name}}</div>
<!--绑定class样式,数组法-->
<div class="basic" :class="arr">{{name}}</div>
<!--绑定class样式,对象法-->
<div class="basic" :class="classObj">{{name}}</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
name:'xxx',
normal:"normal",
arr:['style_1','style_2','style_3','style_4'],
classObj:{
xxx:false,
xxxx:false,
}
},
methods:{
changeMood(){
this.normal="happy"
}
}
})
</script>
十六、绑定style样式
:style=" {fontSize: xxx}" 其中xxx是动态值。
;style="[a,b]"其中a、b是样式对象。
<div id="root">
<div class="basic" :style="{fontSize:40+'px'}">{{name}}</div>
<div class="basic" :style="styleObj">{{name}}</div>
<div class="basic" :style="[styleObj,styleObj2]">{{name}}</div>
<div class="basic" :style="styleArr">{{name}}</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
name:'xxx',
styleObj:{
fontSize:"40px"
},
styleObj2:{
fontSize:"480px"
},
styleArr:[
{
fontSize:"40px"
},
{
fontSize:"80px"
}
]
},
})
</script>
十七、条件渲染
1.v-if
(1).v-if="表达式”
(2).v-else-if="表达式”
(3) v-else="表达式”
适用于:切换频率较低的场景。
特点:不展示的D0M元素直接被移除。
注意: v-if可以和v-else-if、v-else一起使用, 但要求结构不能被“打断”
2.v-show
写法: v-show=" 表达式"
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉(display:none)
3.使用v-if的时,元素可能无法获取到,而使用v-show定可以获取到。
<div id="root">
<button v-show="true">按钮</button>
<button v-show="showOrHidden">按钮</button>
<button v-if="true">按钮</button>
<button v-if="showOrHidden">按钮</button>
<div v-if="n==1">Angular</div>
<div v-else-if="n==2">React</div>
<div v-else-if="n==3">Vue</div>
<div v-else></div>
<!--template只能和v-if一起使用,而不能和v-show一起使用-->
<template v-if="n==1">
<h2>1</h2>
<h2>2</h2>
<h2>3</h2>
</template>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
showOrHidden:true
},
})
</script>
十八、列表渲染
V-for指令
1.用于展示列表数据
2.语法: v-for="(item, index) in xxx" :key=“yyy”
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<div id="root">
<!--遍历数组-->
<ul>
<li v-for="p in persons" :key="p.id">{{p.name}}-{{p.age}}</li>
</ul>
<!--遍历数组2.0-->
<ul>
<li v-for="(p,index) in persons" :key="index">{{p.name}}-{{p.age}}</li>
</ul>
<!--遍历对象-->
<ul>
<li v-for="(value,key) of car" :key="k"></li>
</ul>
<!--遍历字符串-->
<ul>
<li v-for="(char,index) of str" :key="index"></li>
</ul>
<!--遍历指定次数-->
<ul>
<li v-for="(number,index) of 5" :key="index"></li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
persons:[
{
id:'001',
name:'张三',
age:18
},
{
id:'002',
name:'李四',
age:20
},
],
car:{
name:"xxx",
type:"xxx",
price:"xxx"
},
str:"helloWorld",
},
})
</script>
面试题: react、vue中的key有什么作用? ( key的内部原理)
1.虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据[新数据]生成[新的虚拟DOM],随后Vue进行[新虚拟DOM]与[旧虚拟DOM]的差异比较,比较规则如下:2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变,直接使用之前的真实DOM !
②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key:创建新的真实DOM,随后渲染到到页面。3.用index作为key可能会引发的问题:
(1). 若对数据进行:逆序添加、逆序刷除等破环顺序操作: 会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
(2).如果结构中还包含输入类的DOM:会产生错误DOM更新==>界面有问题。4.开发中如何选择key?: (1).最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。 (2).如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示, 使用index作为key是没有问题的
十九、列表过滤
<div id="root">
<input type="text" placeholder="请输入关键词" v-model="keyWord">
<ul>
<li v-for="(p,index) of filPersons" :key="index"></li>
</ul>
</div>
<script type="text/javascript>
Vue.config.productionTip=false
new Vue({
el:"#root",
data:{
keyWord:"",
persons:[
{id:"001",name:"马冬梅",age:19,sex:"女"},
{id:"002",name:"周冬雨",age:20,sex:"女"},
{id:"003",name:"周杰伦",age:21,sex:"男"},
{id:"004",name:"温兆伦",age:22,sex:"男"},
],
filPersons:[]
} ,
watch:{
keyWord:{
immediate:true,
handler(value){
this.firPersons = this.persons.filter((p)=>{
return: p.name.index0f(value)!== -1
}
}
}
}
})
</script>
<div id="root">
<input type="text" placeholder="请输入关键词" v-model="keyWord">
<ul>
<li v-for="(p,index) of persons" :key="index"></li>
</ul>
</div>
<script type="text/javascript>
Vue.config.productionTip=false
new Vue({
el:"#root",
data:{
keyWord:"",
persons:[
{id:"001",name:"马冬梅",age:19,sex:"女"},
{id:"002",name:"周冬雨",age:20,sex:"女"},
{id:"003",name:"周杰伦",age:21,sex:"男"},
{id:"004",name:"温兆伦",age:22,sex:"男"},
],
} ,
computed:{
filPersons(){
return this.persons.filter((p)=>{
return: p.name.index0f(this.keyWord)!== -1
}
}
}
})
</script>
二十、列表排序
<div id="root">
<input type="text" placeholder="请输入关键词" v-model="keyWord">
<button @click="sortType=2">年龄升序</button>
<button @click="sortType=1">年龄降序</button>
<button @click="sortType=0">原顺序</button>
<ul>
<li v-for="(p,index) of filPersons" :key="index"></li>
</ul>
</div>
<script type="text/javascript>
Vue.config.productionTip=false
new Vue({
el:"#root",
sortType:0,
data:{
keyWord:"",
persons:[
{id:"001",name:"马冬梅",age:19,sex:"女"},
{id:"002",name:"周冬雨",age:20,sex:"女"},
{id:"003",name:"周杰伦",age:21,sex:"男"},
{id:"004",name:"温兆伦",age:22,sex:"男"},
],
} ,
computed:{
filPersons(){
const arr = this.persons.filter((p)=>{
return: p.name.index0f(this.keyWord)!== -1
}
if(this.sortType){
arr.sort((a,b)=>{
return this.sortType==1?(b.age-a.age):(a.age-b.age)
})
}
return arr;
}
}
})
</script>
二十一、vue监听数据变化的底层原理
Vue监视数据的原理:
1.vue会监视data中所有层次的数据。
2.如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式,请使用如下API:
Vue.set(target, propertyName/index, value)
或vm.$set(target, propertyName/index,value)
3.如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1).调用原生对应的方法对数组进行更新。
(2).重新解析模板,进而更新页面。
4.在Vue修改数组中的某个元素一定要用如下方法:
(1).使用这些API: push()、pop()、shift()、unshift()、splice()、sort()、reverse()
(2).Vue.set()或vm.$set()
(3).使用filter()、concat()、slice()生成的新数组替换原数组
特别注意: Vue.set()
和vm.$set()
不能给vm或vm的根数据对象添加属性! ! !
//简单模拟
<script type="text/javascript>
let data = {
name:'元元元',
address:'北京'
}
//创建一个监视的实例对象,用于监视data中属性的变化
const obs = new Observer (data)
//准备一个vm实例对象
let vm = {}
vm._data = data = obs
function Observer(obj){
//汇总对象中所有的属性形成个一数组
const keys = object.keys(obj)
//遍历
keys.forEach((k)=>{
object.defineProperty(this,k,{
get(){
return obj[k]
},
set(val){
console.log(`${k}被改了,我要去解析模板。生成虚拟DOM.....我要开始忙了`)
obj[k] = val
})
}
}
</script>
Vue.set(vm._data.student,'sex','男')
vm.$set(vm._data.student,'sex','女')
vm.$set(vm.student,'sex','女')
Vue.set(vm._ data.student.hobby,1,'打台球')
vm.$set(vm._ data.student.hobby,1,'打台球')
二十二、v-model收集表单中的数据
收集表单数据:
若: <input type="text"/>
.则v-model收集的是value值,用户输入的就是value值。
若: <input type="radio"/>
.则v-model收集的是value值,且要给标签配置value值。
若: <input type="checkbox"/>
1).没有配置input的value属性,那么收集的就是checked(勾选or未勾选,是布尔值)
2).配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked (勾选or未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
备注: v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤
<div id="root">
<form @submit.prevent="demo">
账号: <input type="text" v-model.trim="userInfo.account"><br/><br/>
密码: <input type="password" v-model="userInfo.password"><br/><br/>
年龄:<input type="number" v-model.number="userInfo.password"><br/><br/>
性别:
男<input type="radio" name="sex" v-model="userInfo.sex" value="femal">
女<input type="radio" name="sex" v-model="userInfo.sex" value="male"> <br/><br/>
爱好:
学习<input type="checkbox" v-model="userInfo.hobby" value="study">
打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
<br/><br/>
所属校区
<select v-model="userInfo.city">
<option value="">请选择校区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen" >深圳</option>
<option value="wuhan" >武汉</option>
</select>
其他信息:
<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
<input type="checkbox" v-model="userInfo.aggre">阅读并接受<a href= "#">《用户协议》</a>
<button>提交</button>
</form>
</div>
<script type="text/javascript">
Vue.config.productionTip=false
new Vue({
el:"#root",
data:{
userInfo:{
account:"",
password:"",
sex:"",
hobby:[],
city:"",
other:"",
aggre:""
}
},
methods:{
demo(){
console.log(JSON.stringify(this.userInfo))
}
}
})
</script>
二十三、过滤器
- 定义:对要显示的数据进行特定格式化后再显示(适用于些简单逻辑的处理)。
- 语法:
1.注册过滤器: Vue.filter(name, callback)或new Vue{filters:{}}
2.使用过滤器: {{ xxx| 过滤器名}} 或v-bind:属性= "xx| 过滤器名” - 备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据,是产生新的对应的数据
<div id="root">
<!--计算属性实现-->
<h3>{{fmtTime}}</h3>
<!--methods实现-->
<h3>{{getFmtTime()}}</h3>
<!--过滤器实现-->
<h3>{{time | timeFormater}}</h3>
<!--过滤器传参实现-->
<h3>{{time | timeFormater('YYY_MM_DD')}}</h3>
<!--过滤器传参实现-->
<h3>{{time | timeFormater('YYY_MM_DD') | mySlice}}</h3>
<h3 :x="time | timeFormater('YYY_MM_DD') | mySlice"></h3>
</div>
<script type="text/javascript">
Vue.config.productionTip=false
//全局过滤器
Vue.filter('mySlice',function(value){
return value.slice(0,4)
})
new Vue({
el:"#root",
data:{
time:1621561377603 //时问戳
},
computed: {
fmtTime(){
return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
}
},
methods: {
getFmtTime(){
return dayjs(this.time).format('YYY年MM月DD日 HH:mm:ss')
},
},
//局部过滤器
filters:{
timeFormater(value,str="YYY年MM月DD日 HH:mm:ss"){
return dayjs(this.time).format(str)
},
mySlice(value){
return value.slice(0,4)
}
}
</script>
二十四、vue生命周期
生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子
2.是什么: Vue在关键时刻帮我们调用的一些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向是vm或组件实例对象。
<div id="root">
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
},
//vue完成模板的解析并把真实的DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
//这里的this是vm
}
})
</script>
常用的生命周期钩子:
- mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅消息等[初始化操作]。
- beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息等[收尾工作]。
关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据。也不会再触发更新流程了。
二十五、组件
- 模块 向外提供特定功能的js程序,一般就是一个js文件;复用js,简化js的编写,提高js运行效率
- 组件 用来实现局部(特定)功能效果的代码集合(html/css/js/image…) ;复用编码,简化项目编码,提高运行效率
- 模块化 当应用中的js都以模块来编写的,那这个应用就是一一个模块化的应用。
- 组件化 当应用中的功能都是多组件的方式来编写的,那这个应用就是一个组件化的应用
二十六、非单文件组件
一个文件中包含有n个组件
//创建school组件
const school = Vue.extend({
template:`<div>xxx</div>`,
data(){
return {
studentName:'xxx',
age:18
}
}
})
//注册组件:创建vm(局部注册)
new Vue({
el:'#root',
components:{
school:school,
}
})
//使用
<div id="root">
<school></school>
</div>
Vue.component('hello',hello) //全局注册组件
new Vue({
el:'#root'
})
//使用
<div id="root">
<hello></hello>
</div>
一、Vue中使用组件的三大步骤:
定义组件(创建组件)
注册组件
使用组件(写组件标签 )
二、如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options )时传入的那个options几乎一样,但也有点区别:
1.e1不要写,最终所有的组件都要经过一个vm的管理,由vm中的e1决定服务哪个容器。
2. data必须写成函数,避免组件被复用时,数据存在引用关系。
3. 使用template 可以配置组件结构。
三、如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component( ‘组件名’ ,组件)
四、编写组件标签:
<school></school>
五、几个注意点:
1.关于组件名:
一个单词组成:
- 第一种写法(首字母小写): school
- 第二种写法(首字母大写): School
多个单词组成:
- 第一种写法( kebab-case命名): ‘my-school’
- 第二种写法( CamelCase命名): MySchool (需要Vue脚手架支持)
注意:
(1).组件名尽可能回避HTML中已有的元素名称,例如: h2、 H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
2.关于组件标签:
第一种写法: <school></school>
第二种写法: <school/>
备注:不用使用脚手架时, 会导致后续组件不能渲染。
3. 一个简写方式:
const school = Vue.extend(options)可简写为: const school = options
二十七、组件的嵌套
二十八、VueComponent
- 组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
- 我们只需要写
<school/>
或<school></school>
. Vue解析时会帮我们创建组件的实例对象,即Vue帮我们执行: new VueComponent(options)。 - 每次调用Vue.extend,返回的都是一个全新的VueComponent!!!
- 关于this指向:
(1).组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是[ VueComponent实例对象:VC]。
(2).new Vue(options)配置中:
data函数、methods中的两 数、watch中的两数、computed中 的函数它们的this均是[Vue实例对象:VM]。 - vm管理着vc(vm.$children),组件是可复用的vue实例,所以它们与new Vue接收相同的选项,但它们也有区别,不能同等看待。
二十九、Vue和VueComponent的关系
VueComponent.prototype._ proto_ === Vue.prototype 让组件实例对象(vc) 可以访问到Vue原型上的属性、方法。
三十、单文件组件(.vue文件)
一个文件中只包含有一个组件
//School.vue MySchool.vue
<template>
<!--组件的结构-->
<div class='demo'>
<h2>{{schoolName}}</h2>
<button @click="showName"></button>
</div>
</template>
<script>
//组件交互相关的代码(数据、方法等等)
1. export const school = Vue.extend({
data(){
return{
shoolName:'湖南工商大学'
}
},
methods:{
showName(){
alert(this.shoolName)
}
}
})
2. export {shool}
3. export default shool
4. export default Vue.extend({
data(){
return{
shoolName:'湖南工商大学'
}
},
methods:{
showName(){
alert(this.shoolName)
}
}
})
5. export default {
name:'School',
data(){
return{
shoolName:'湖南工商大学'
}
},
methods:{
showName(){
alert(this.shoolName)
}
}
}
</script>
<style>
/*组件的样式*/
.demo{
background-color:orange;
}
</style>
//App.vue汇总所有的组件
<template>
<div>
<School></School>
</div>
</template>
<script>
import School from './School'
export default {
name:'App',
components:{
School:School
}
}
</script>
<style>
</style>
//main.js
import App from './App'
new Vue({
el:'#root',
component:{App}
})
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root">
<App></App>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript" src="./main.js"></script>
</body>
</html>
更多推荐
所有评论(0)