0、关于vue的一些总结:
1、只要data里面的数据发生变化,vue模板就重新执行。
<div id="root">
<h1 :style="opacity1">学习vue</h1>
<h1 :style="{opacity:opacity}">学习vue</h1>
<h1 :style="{opacity}">学习vue</h1>
<button @click="change">点击我可以渐变</button>
{{change()}}
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
opacity1: 'opacity: .1',
opacity: .6,
},
methods: {
change() {
setInterval(() => {
this.opacity = this.opacity - 0.01
if (this.opacity <= 0) {
this.opacity = 1
}
}, 16)
}
},
});
</script>
在这个例子中,vue模板中的change()
会首先得到执行,然后调用methods中的定时器
,定时器发生变化,修改了opacity
,data里面的数据发生了变化,然后就重新解析vue模板,就又重新生成了一个定时器,导致一个循环,会不停生成定时器。
1、特点
1.采用组件化模式,提高代码复用率、且让代码更好维护。
2.声明式编码,让编码人员无需直接操作DOM,提高开发效率
命令式编码
3.使用虚拟DOM+优秀的Diff 算法,尽量复用DOM节点。
2、hello vue
vue的引入
就是写在引入css的地方就行了
例如:
<!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>
在这里引入
<script src="../vue.js"></script>
</head>
<body>
</body>
</html>
在线地址引入:
vue2
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
vue3
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
注意:
1.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象new Vue;
2.root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
3.root容器里的代码被称为[Vue模板];
4.Vue实例和容器是一一对应的
;
5.真实开发中只有一个vue实例,并且会配合着组件一起使用;
6.{{xxx}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性
7.一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
注意区分: js表达式 和 s代码(语句)
表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
(1). a
(2). a+b
(3). demo(1)
(4). x === y ?a’: b’
js代码(语句)
(1). if( ){ }
(2). for( ){ }
<!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>
<script src="../vue.js"></script>
</head>
<body>
<!-- 准备一个容器 -->
//-------------------------------------------------------
<div id="root">
<h1>hello,{{name}}</h1>
<h1>今年{{age}}岁了!</h1>
</div>
<!-- 这个就没有效果,以为没有选择器选中他 -->
<h1>{{name}}</h1>
//-----------------------------------------------------------
<script type="text/javascript">
// Vue.config.productionTip = false;//设置为 false 以阻止 vue 在启动时生成生产提示。
// 创建vue实例--------------------------------------------------
const x = new Vue({
// el:document.querySelector("#root"), //这样也是可以的
el: '#root', //el用于指定当前Vue实例为那个容器服务,值通常是css选择器字符串
data: {
name: 'world',
age: 23,
}
});
//--------------------------------------------------------
</script>
</body>
</html>
3、模板语法
注意:
Vue模板语法有2大类:
1.插值语法:
功能:用于解析标签体内容。
写法: {{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
2.指令语法:
功能:用于解析标签(包括: 标签属性、标签体内容、绑定事件…)
举例: v-bind:href="xxx”或 简写为 :href=“xxx”,
xxx同样要写is表达式,且可以直接读取到data中的所有属性。
备注: Vue中有很多的指令,且形式都是: v-???,此处我们只是拿v-bind举个例子。
v-bind:xxx=?。?可以直接写变量,而不用写{{ }}
<!-- 准备一个容器 -->
<div id="root">
<h1>插值语法</h1>
<h1>hello,{{name}}</h1>
<h1>今年{{age}}岁了!</h1>
<h1>指令语法</h1>
<a v-bind:href="url" target="_blank">点我去百度学习</a>
<a :href="url">v-bind:可以简写成:</a>
<h2>我的学校是{{school.name}}</h2>
</div>
<script type="text/javascript">
// 创建vue实例
const x = new Vue({
// el:document.querySelector("#root"), //这样也是可以的
el: '#root', //el用于指定当前Vue实例为那个容器服务,值通常是css选择器字符串
data: {
name: 'world',
age: 23,
url: 'https://www.baidu.com',
// 如果有多个name,不想换名字的情况下,可以用一个对象包括
school:{
name:'家里蹲',
}
}
});
</script>
3、数据绑定
1、单向绑定
<div id="root">
<!-- v-bind: 是单向绑定 -->
单向数据绑定:<input type="text" :value="name">
</div>
<script>
new Vue({
el:'#root',
data:{
name:'李旭亮',
}
})
</script>
data中的name属性,通过v-bind:属性绑定到value身上,如何input输入框里面的值就发生了变化。
通过修改vue工具中的name属性,可以改变input输入框里面的值。但是直接修改input输入框里面的值,却不能修改data里面的值。
v-bind:value=
name
类似于一个赋值
操作。
等号后面的值可以赋值给前面,而前面的值,不能给后面。
2、双向绑定
<div id="root">
<!-- v:bind 是单向绑定 -->
单向数据绑定:<input type="text" v-bind:value="name"><br>
双向数据绑定:<input type="text" v-model:value="name">
</div>
<!-- 这是错误的。因为v-model只能用在表单类元素(输出类元素)上 -->
<h2 v-model="name"></h2>
<!-- 简写形式 -->
单向数据绑定:<input type="text" :value="name"><br>
双向数据绑定:<input type="text" v-model="name">
Vue中有2种数据绑定的方式:
- 单向绑定(v-bind): 数据只能从data流向页面。
- 双向绑定(v-model): 数据不仅能从data流向页面,还可以从页面流向data。
备注:
- 双向绑定一般都应用在表单类元素上 (如: input、select等)
-
v-model:value 可以简写为 v-model
,因为v-model默认收集的就是value值。
4、el和data的二种写法
1、el
<div id="root">
<h1>hello,{{new Date()}}</h1>
<h1>hello,{{name}}</h1>
</div>
<script>
const v1 = new Vue({
// el: '#root',
data: {
name: '2023-4-6',
}
});
v1.$mount('#root');//和el:'#root'的效果一样
console.log(v1);
// 这样可以实现时钟效果
// setInterval(function () {
// v1.$mount('#root');//和el:'#root'的效果一样
// }, 1000)
</script>
2、data
<div id="root">
<h1>hello,{{new Date()}}</h1>
<h1>hello,{{name}}</h1>
</div>
<script>
// data的二种写法
new Vue({
el: '#root',
// 1、对象式-----------
// data:{
// name:'对象式'
// }
// 2、函数式-----------
data: function () {
console.log(this);//指的是实例对象,例如v1
return {
name: '函数式'
}
}
});
</script>
data与el的2种写法
e1有2种写法
- new Vue时候配置el属性。
- 先创建Vue实例,随后再通过vm.$mount('#root )指定el的值
data有2种写法
- 对象式
- 函数式
如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,
否则会报错。
一个重要的原则:
由Vue管理的函数
一定不要写箭头函数,一但写了箭头函数,this就不再是Vue实例了。而是指向window
5、mvvm模型
<div id="root">
<input type="text" v-model="name">
<h3>{{$options}}</h3>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: "河南牧业经济学院"
}
});
console.log(vm);
console.log(vm.name);//河南牧业经济学院
</script>
这个实例对象里面的所有东西,都可以直接用{ { } }
输出。
MVVM模型
- M:模型(Model) : data中的数据
- V:视图(view) : 模板代码
- VM: 视图模型(ViewModel): Vue实例
观察发现:
1.data中所有的属性,最后都出现在了vm身上。
2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
6、defineProperty
let person = {
name: 'lxl',
sex: '男'
}
Object.defineProperty(person, 'age', {
//这个值不可以被枚举、不可以被修改、不可以被删除
value: 54,
enumerable: true,//控制属性是否可以被枚举,默认值是false
writable: true,//控制属性是否可以被修改,默认值是false
configurable: true,//控制属性是否可以被删除,默认值是false
})
console.log(person);
// Object.keys(person) 可以输出对象的属性名
console.log(Object.keys(person));
set和get
- 注意:当使用了getter或setter方法,不允许使用writable和value这两个属性
- getter: 当访问该属性时,该方法会被执行。函数的返回值 会作为 该属性的值返回.
- setter: 当属性值修改时,该方法会被执行。该方法将接受唯一参数,即该属性新的参数值。
- 不要在getter中再次获取该属性值,也不要在setter中再次设置改属性,否则会栈溢出!
let num=19;
let person = {
name: 'lxl',
sex: '男'
}
Object.defineProperty(person, 'age', {
// 当有人读取person的age属性时,get函数就会被调用,且返回值就是age的值
get:function(){
console.log('有人读取age属性了');
// return 'age的值';
return num;
},
// 当有人修改person的age属性值时,set函数的(setter)就会被调用,且会收到修改的具体值
set(value){
console.log('有人修改了age属性值,其值是',value);
num=value;
// age=num=value;
}
})
console.log(person);
// Object.keys(person) 可以输出对象的属性名
console.log(Object.keys(person));
7、数据代理
// 数据代理:通过一个对象代理 对另一个对象属性的操作(读、写)
let obj = { x: 100 };
let obj2 = { y: 200 };
// 感觉就是
// 把对象obj的属性x追加给obj2,修改obj2的这个x还会影响obj的x属性
Object.defineProperty(obj2, "x", {
get() {
return obj.x;
},
set(value) {
obj.x = value;
}
});
1.Vue中的数据代理:
通过vm对象来代理data对象中属性的操作 (读/写)
2.Vue中数据代理的好处:
更加方便的操作data中的数据
3.基本原理:
- 通过object.defineProperty()把data对象中所有属性添加到vm上。
- 为每一个添加到vm上的属性,都指定一个getter/setter。
- 在getter/setter内部去操作 (读/写) data中对应的属性。
8、事件处理
事件的基本使用:
1、使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名。
1、v-on:click='abc’可以简写成@click=‘abc’
2、事件的回调需要配置在methods对象中,最终会在vm上;
3、methods中配置的函数,不要用箭头函数! 否则this就不是vm了;
4、methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
5、@click="demo"和 @click="demo($event)"效果一致,但后者可以传参;
<div id="root">
<h2>在{{address}}学习</h2>
<button v-on:click="showInfo1">点击提示信息1</button>
<button @click="showInfo2(985,$event)">点击提示信息2</button>
</div>
<script>
new Vue({
el: '#root',
data: {
address: '宿舍',
},
methods: {
// 在对象里面可以省略function
showInfo1(e) {
console.log(e.target);
alert('好好学习!');
},
showInfo2(num, e) {
console.log('showInfo2=' + num);
console.log(e);
},
},
});
</script>
1、事件修饰符
vue中的事件修饰符:
1、prevent: 阻止默认事件(常用) ;
2、stop: 阻止事件冒泡(常用) ;
3、once:事件只触发一次(常用) :
4、capture:使用事件的捕获模式:
5、self: 只有event.target是当前操作的元素是才触发事件:
6、passive:事件的默认行为立即执行,无需等待事件回调执行完毕:
<div id="root">
<a href="https://www.baidu.com/" @click.prevent="show">点击</a>
<!-- 如果是二层结构,只给孩子加stop就行了
如果有三层结构,那么就需要再加一个stop
-->
<div class="father" @click="show">
<button class="son" @click.stop="show">ok</button>
</div>
<!-- 无论点击多少次,只会触发一次事件 -->
<button @click.once="show">点击只触发一次</button>
<!-- 把默认的事件冒泡,改成捕获:捕获在父盒子身上加就可以了 -->
<div class="d1" @click.capture="showmsg(1)">
div1
<div class="d2" @click="showmsg(2)">
div2
</div >
</div>
<!-- <div class="father" @click.self="show"> -->
<div class="father" @click="show">
<button class="son" @click="show">ok</button>
</div>
</div>
<script>
new Vue({
el: '#root',
data:{
},
methods: {
show(e){
// e.preventDefault();//阻止默认事件
// e.stopPropagation();//阻止冒泡
// console.log('加油!');
console.log(e.target);
},
showmsg(msg){
console.log(msg);
}
},
});
</script>
事件冒泡
<!-- 如果是二层结构,只给孩子加stop就行了
如果有三层结构,那么就需要再加一个stop
因为冒泡是从内到外的,在vue中的.stop必须加在子盒子上
-->
<div class="father" @click="show">
<button class="son" @click.stop="show">ok</button>
</div>
点击ok,不会弹出父盒子的信息。
事件捕获
<!-- 把默认的事件冒泡,改成捕获:捕获在父盒子身上加就可以了 -->
<div class="d1" @click.capture="showmsg(1)">
div1
<div class="d2" @click="showmsg(2)">
div2
</div >
</div>
点击div2,先打印1,再打印2,符合捕获规则。
2、键盘事件
1.Vue中常用的按键别名:
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab
上 => up
下=> down
左=> left
右=> right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case (短横线命名)
3.系统修饰键(用法特殊) : ctr1、alt、shift、meta
(1).配合keyup使用: 按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用: 正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐)
5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
<div id="root"> <!--按下回车键会输出-->
<input type="text" placeholder="按下回车键会输出!" @keyup.enter="show">
<!-- 按下切换大小写键输出! 大写变小写,且变成小写的按钮前,需要加- -->
<input type="text" placeholder="按下切换大小写键输出" @keyup.caps-lock="show">
<!-- 按下ctrl写键输出! -->
<input type="text" placeholder="按下ctrl写键输出!" @keyup.ctrl="show">
</div>
<script>
new Vue({
el: '#root',
data: {
},
methods: {
show(e) {
// 当回车的时候输出------------------------
// console.log(e.keyCode);//回车键是13
// if (e.keyCode === 13) {
// console.log(e.target.value);
// } else {
// return console.log('请继续输入!');
// }
// if (e.keyCode !== 13) return
// console.log(e.target.value);
console.log(e.target.value);
}
},
});
</script>
<!-- 按下ctrl+y键输出! -->
<input type="text" placeholder="按下ctrl写键输出!" @keyup.ctrl.y="show">
3、计算属性
计算属性:
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理: 底层借助了objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?(1).初次读取时会执行一次。(2).当依赖的数据发生改变时会被再次调用。4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算屈性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="secondName"><br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
全名:<span>{{fullName}}</span> <br>
</div>
<script>
// vm中的数据只要发生变化,模版中的数据就会重新刷新
const vm= new Vue({
el: '#root',
data: {
firstName: "张",
secondName: '三',
},
computed: {
fullName: {
// get有啥作用:当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
// get什么时候被调用:1、初次读取fullName时。2、所依赖的数据发生变化时。
get() {
console.log('有人读取fullName时,get就会被调用,');
// console.log(this);//此处的this是vm
return this.firstName + '-' + this.secondName;
},
// set什么时候被调用,当fullName修改的时候
set(value) {
console.log('有人修改fullName时,set就会被调用,');
console.log('set', value);
const arr = value.split('-');
this.firstName = arr[0];
this.secondName = arr[1];
}
}
},
});
</script>
9、监视属性
1、天气案例
<div id="root">
在Vue中,当一个函数被定义为computed属性时,它会被自动缓存,
这意味着只有当其依赖的响应式数据发生变化时才会重新计算。
因此,在视图中使用computed属性时不需要加括号,
因为Vue会自动调用并返回计算结果。
<h2>今天天气很{{info}}!</h2>
<button @click="qieHuan">点击切换天气</button>
<!-- @xxx="yyy" yyy指可以写一些简单的语句 -->
<button @click="isHot = !isHot">点击切换天气2</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
},
computed: {
info: {
// get有啥作用:当有人读取info时,get就会被调用,且返回值就作为info的值
get() {
console.log('有人读取info时,get就会被调用,');
return this.isHot ? '炎热' : '凉爽';//返回值给了info
}
}
},
methods: {
// 这是一个函数
qieHuan() {
return this.isHot = !this.isHot;
}
// 点击切换按钮,假如返回一个false,然后data里面的属性发生了变化,
// 然后使computed里面发生改变
},
});
console.log(vm);
</script>
1.2、computed和methods有什么区别
Vue中的computed和methods都是用来处理数据逻辑的选项,但它们有一些区别:
computed属性是基于它的依赖缓存,只有在相关依赖发生改变时才会重新计算;而methods方法则是在每次调用时都执行一遍。
computed属性主要用于对多个数据进行计算得出结果,常用于模板中的表达式计算结果;而methods方法主要用于触发某个事件或操作,例如点击事件等。
在使用时,computed属性更像是一个响应式的变量,而methods方法更像是普通的函数。因此,当我们需要对数据进行计算并获得一个结果时,优先考虑computed属性;当我们需要触发一些事件或操作时,则选择methods方法。
2、监视属性
监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
<div id="root">
<h2>今天天气很{{info}}!</h2>
<button @click="qieHuan">点击切换天气</button>
<!-- @xxx="yyy" yyy指可以写一些简单的语句 -->
<button @click="isHot = !isHot">点击切换天气2</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
},
computed: {
info: {
// get有啥作用:当有人读取info时,get就会被调用,且返回值就作为info的值
get() {
console.log('有人读取info时,get就会被调用,');
return this.isHot ? '炎热' : '凉爽';//返回值给了info
}
}
},
methods: {
// 这是一个函数
qieHuan() {
return this.isHot = !this.isHot;
}
// 点击切换按钮,假如返回一个false,然后data里面的属性发生了变化,
// 然后使computed里面发生改变
},
// 监视属性
// watch: {
// isHot: {
// immediate: true,//初始化时,让handler调用一下
// // handler什么时候调用?当isHot发生改变时
// handler(newValue, oldValue) {
// console.log('isHot发生改变了', newValue, oldValue);
// }
// }
// }
});
console.log(vm);
vm.$watch('isHot', {
immediate: true,//初始化时,让handler调用一下
// handler什么时候调用?当isHot发生改变时
handler(newValue, oldValue) {
console.log('isHot发生改变了', newValue, oldValue);
}
})
</script>
3、深度监视
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变 (一层)
(2).配置deep:true可以监测对象内部值改变 (多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
<div id="root">
<h2>今天天气很{{info}}!</h2>
<button @click="qieHuan">点击切换天气</button>
<!-- @xxx="yyy" yyy指可以写一些简单的语句 -->
<button @click="isHot = !isHot">点击切换天气2</button>
<hr>
<h3>a的值是{{num.a}}</h3>
<button @click="add">点击让a的值++</button>
<button @click="num.a++">点击让a的值++</button>
<button @click="num={a:675,b:5643}">彻底改变num</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
num: {
a: 1,
b: 1,
}
},
computed: {
// info: {
// // get有啥作用:当有人读取info时,get就会被调用,且返回值就作为info的值
// get() {
// console.log('有人读取info时,get就会被调用,');
// return this.isHot ? '炎热' : '凉爽';//返回值给了info
// }
// }
// 省略get的写法
info() {
return this.isHot ? '炎热' : '凉爽';//返回值给了info
},
},
methods: {
// 这是一个函数
qieHuan() {
return this.isHot = !this.isHot;
},
// 点击切换按钮,假如返回一个false,然后data里面的属性发生了变化,
// 然后使computed里面发生改变
add() {
return this.num.a++;
}
},
// 监视属性
watch: {
isHot: {
// immediate: true,//初始化时,让handler调用一下
// handler什么时候调用?当isHot发生改变时
handler(newValue, oldValue) {
console.log('isHot发生改变了', newValue, oldValue);
}
},
// 'num.a': {
// handler() {
// console.log('a发生了变化');
// }
// },
num: {
// 监视多级结构中所有属性的变化
// num或者num里面的属性变了,都是变化
deep: true,
handler() {
console.log('num发生了变化');
}
}
}
});
console.log(vm);
</script>
4、监视属性的简写形式
<div id="root">
<h2>今天天气很{{info}}!</h2>
<button @click="qieHuan">点击切换天气</button>
<!-- @xxx="yyy" yyy指可以写一些简单的语句 -->
<button @click="isHot = !isHot">点击切换天气2</button>
</div>
<script>
let flag = true;
const vm = new Vue({
el: '#root',
data: {
isHot: true,
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽';//返回值给了info
},
},
methods: {
// 这是一个函数
qieHuan() {
return this.isHot = !this.isHot;
}
},
// 监视属性
watch: {
// 完整写法---------------------------------
// isHot: {
// immediate: true,//初始化时,让handler调用一下
// // handler什么时候调用?当isHot发生改变时
// handler(newValue, oldValue) {
// console.log('isHot发生改变了', newValue, oldValue);
// }
// },
// 当不需要配置项,例如immediate,deep的时候就可以简写
// 简写-----------------------------------------
// isHot(newValue, oldValue) {
// console.log('isHot发生改变了', newValue, oldValue);
// }
}
});
console.log(vm);
// 完整写法:------------------------------------------------
// vm.$watch('isHot', {
// immediate: true,//初始化时,让handler调用一下
// deep: true,
// // handler什么时候调用?当isHot发生改变时
// handler(newValue, oldValue) {
// console.log('isHot发生改变了', newValue, oldValue);
// }
// });
// 简写:---------------------------------------------------
vm.$watch('isHot', function (newValue, oldValue) {
console.log('isHot发生改变了', newValue, oldValue);
})
</script>
5、姓名案例-watch实现
computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如: watch可以进行异步操作。
两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
<div id="root">
姓:<input type="text" v-model="one"><br>
名:<input type="text" v-model="two"><br>
姓名:<span>{{three}}</span>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
one: '张',
two: '三',
three: '张-三'
},
computed: {
// fullName: {
// get() {
// return this.one + '-' + this.two;
// },
// set(value) {//fullName修改的值就是value
// let arr = value.split('-');
// this.one = arr[0];
// this.two = arr[1];
// }
// }
// 当不要set的时候,可以简写
// fullName() {
// return this.one + '-' + this.two;
// },
},
watch: {
one(newValue){//谁调用?this就指向谁
// 普通one函数里面的this
console.log(this);//vue
// 需求:延迟1s输出-------------------
setTimeout(()=> {
this.three = newValue + "-" + this.two;
// 这个this指向vue,而用正常函数的this,却指向function
// 箭头函数没有自己的this值,它会继承外部函数作用域中的this,也就是vm
// 如果是普通函数,这个函数在定时器里面,是window调用的
console.log(this);
},1000)
},
two(newValue) {
setTimeout(()=>{
this.three = this.one + "-" + newValue;
},1000)
}
}
});
</script>
10、绑定class、style样式
1、class样式写法
:class="xxx”xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2、style样式
:style="{fontsize: xxx}"其中xxx是动态值。
:style="其中a、b是样式对象。样式对象里面的key不能瞎写,必须是存在的style样式
<style>
#root div {
width: 300px;
height: 150px;
border: 1px solid pink;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
/* ---------------------------------- */
.cu {
font-weight: 700;
}
.size {
font-size: 70px;
}
.fStyle {
font-family: 华康娃娃体W5;
}
</style>
<div id="root">
<!-- 这里的change加不加()都行。这个color 必须绑定才有用 -->
<!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
<div @click="change" v-bind:class="color">123</div> <br>
<!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
<div :class="classArr">123</div>
<button @click="shanchu">点击删除一个属性</button>
<!-- 绑定class样式--对象写法,适用于: 要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
<div :class="classObj">123</div>
<!-- 这个地方必须写style样式 -->
<div :style="classStyle">绑定style样式</div>
<!-- 数组写法 -->
<div :style="[classStyle,classStyle2]">绑定style样式2</div>
<div :style="styleArr">绑定style样式3</div>
</div>
<script>
new Vue({
el: '#root',
data: {
color: null,
classArr: ['cu', 'size', 'fStyle', 'red'],
classObj: {
green: true,
cu: true,
fStyle: true,
size: true,
},
classStyle: {
fontSize: '40px',
color: 'red',
},
classStyle2: {
backgroundColor: 'yellow',
},
// 不常用---------------------------
styleArr: [
{
fontSize: '40px',
color: 'red',
},
{
backgroundColor: 'yellow',
}
]
},
methods: {
change() {
const arr = ['red', 'green', 'blue'];
const index = Math.floor(Math.random() * 3);
console.log(index);
this.color = arr[index];
},
shanchu() {
this.classArr.pop();
}
},
});
</script>
11、条件渲染
1.V-if
写法:
v-if=“表达式”
v-else-if=“表达式”
v-else=“表达式”
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除
。
注意: v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”
2.V-show
写法: v-show=“表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注: 使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到
被设置为 display: none 的盒子会从渲染树中移除,它不再占据自己原先的盒子位置并且对文档的布局也没有任何影响。这意味着其他元素可以占据该盒子原本所在的区域。
与之相反,如果将一个元素的 visibility 属性设置为 hidden,则改元素将隐藏,但仍会保留其原始空间,因此对布局仍有影响。
<div id="root">
<!-- 使用v-show做条件渲染 -->
<h2 v-show="1===4">正在学习{{name}}</h2>
<h2 v-show="true">正在学习{{name}}</h2>
<h2 v-show="a">正在学习{{name}}</h2>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: 'vue',
a: true,
},
});
</script>
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点击按钮n++</button>
<button @click="add">点击按钮(add)n++</button>
<!-- add的返回值是一个数和n++的效果一样 -->
<h2 v-if="1===n">anglar</h2>
<h2 v-if="2===n">react</h2>
<h2 v-if="3===n">vue</h2>
重点 如果if是正确条件,那么else if后面的代码将不会被执行-->
<h2 v-if="1===n">anglar</h2>
<h2 v-else-if="1===n">react</h2>
<h2 v-else-if="3===n">vue</h2>
<!-- template和if搭配 -->
<template v-if="n===1">
<h2>当n=1时,展示出来</h2>
</template>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: 'vue',
a: true,
n: 0,
},
methods: {
add() {
let num = this.n++;
if (num > 2) {
this.n = 1;
}
return num;
}
},
});
</script>
12、列表渲染
1、遍历数组对象
<div id="root">
<h2>遍历数组对象</h2>
<ul>
<!-- 遍历数组对象-------------------------------------------- -->
<!-- 这个:key,就是每一个节点的标识,就相当于身份证号 -->
<li v-for="p in persons" :key="p.id">
{{p.name}}-{{p.age}}
</li> <br>
<!--
()里面只有二个值
第一个:每一个对象
第二个:索引值:默认从0开始
第三个:是underfined。即未定义,未定义的不显示
-->
<li v-for="(a,b,c) in persons">
{{a}}-{{b}}----{{c}}
</li> <br>
<!--
p:是第一个,即是每一个对象
index:是二个,是索引号
-->
<li v-for="(p,index) in persons" :key="index">
{{p.name}}----{{p.age}}岁----{{index}}
</li> <br>
</ul>
</div>
new Vue({
el: '#root',
data: {
persons: [
{
id: 9,
name: '张三',
age: 345,
},
{
id: 2,
name: '李四',
age: 45,
},
{
id: 3,
name: '王五',
age: 57,
},
],
},
});
2、遍历对象与、字符串
<div id="root">
<h2>遍历对象</h2>
<ul>
<!--
第一个:属性值
第二个:属性名
第三个:索引号
第四个:未定义
-->
<li v-for="(a,b,c,d) in car">
{{a}}--{{b}}--{{c}}--{{d}}
</li>
</ul>
<h2>遍历字符串</h2>
<ul>
<!--
第一个:属性值
第二个:索引号
第三个:未定义(即:没有,可以直接忽略)
-->
<li v-for="(a,b,c,d) in str">
{{a}}--{{b}}--{{c}}--{{d}}
</li>
</ul>
</div>
new Vue({
el: '#root',
data: {
car: {
name: '红旗',
price: "50快",
origin: '中国',
},
str: 'hello',
},
});
只有遍历对象:
第一个是属性值
第二个是属性名
第三个是索引号
其他都是:
第一个是值
第二个是索引号
13、收集表单数据
若:<input type="text"/>
,则v-model收集的是value值,用户输入的就是value值。
账号:<input type="text" v-model.trim="accont">
密码:<input type="text" v-model.trim="password">
若:<input type="radio"/>
,则v-model收集的是value值,且要给标签配置value值。
性别:
<input type="radio" name="sex" v-model="sex" value="male">男
<input type="radio" name="sex" v-model="sex" value="female">女
若: <input type="checkbox"/>
1.没有配置input的value属性,那么收集的就是checked (勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked (勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组备注。
爱好:
<input type="checkbox" v-model="hobby" value="study">学习
<input type="checkbox" v-model="hobby" value="eat">吃饭
<input type="checkbox" v-model="hobby" value="sleep">睡觉
v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim: 输入首尾空格过滤
<!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>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<form @submit.prevent="demo"><!-- 绑定默认提交事件,并阻止提交 -->
<label>账号:<input type="text" v-model.trim="accont"></label> <br>
<label>密码:<input type="text" v-model.trim="password"></label> <br>
<label>年龄:<input type="number" v-model.number="age"></label> <br><br>
性别:
<label><input type="radio" name="sex" v-model="sex" value="male">男</label>
<label><input type="radio" name="sex" v-model="sex" value="female">女</label> <br><br>
爱好:
<label><input type="checkbox" v-model="hobby" value="study">学习</label>
<label><input type="checkbox" v-model="hobby" value="eat">吃饭</label>
<label><input type="checkbox" v-model="hobby" value="sleep">睡觉</label> <br><br>
所属校区:
<select v-model="city">
<option>请选择所在校区</option>
<option value="beijing">北京</option>
<option value="henan">河南</option>
<option value="shanghai">上海</option>
<option value="wuhan">武汉</option>
</select><br><br>
其他信息:
<textarea v-model.lazy="other"></textarea><br><br>
<input type="checkbox" v-model="agree">阅读并接受<a
href="https://passport.baidu.com/static/passpc-account/html/protocal.html">《用户协议》</a>
<button>提交</button>
</form>
</div>
<script>
new Vue({
el: '#root',
data: {
accont: '',
password: '',
age: '',
sex: 'female',
hobby: [],
city: 'henan',
other: '',
agree: '',
},
methods: {
demo() {
console.log(this._data);
console.log(JSON.stringify(this._data));
}
},
});
</script>
</body>
</html>
14、脚手架
0、脚手架的安装
具体步骤:
- 第一步(仅第一次执行):全局安装@vue/cli。
安装一次,以后都不用安装了
npm install -g @vue/cli
出现命令行界面,就表示安装成功了。
- 第二步:
切换到你要创建项目的目录
,然后使用命令创建项目。xxxx是项目名
vue create xxxx
然后选择vue3或者2。
安装成功!
- 4、运行vue。在项目根目录下,输入
npm run serve
成功访问!
1、ref属性
1.被用来给元素或子组件注册引用信息 (id的替代者)
2.应用在htm1标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3.使用方式:
打标识: <h1 ref="xxx">.....</h1>
或<School ref="xxx"</School>
获取: this.$refs.xxx
<template>
<div>
<h2 v-text="msg" ref="hh2"></h2>
<button @click="show">点我可以看见h1</button>
<School ref="sch"></School>
</div>
</template>
<script>
// 引入School组件
import School from "./components/School.vue";
export default {
name: "App",
data() {
return {
msg: "好好学习Vue",
};
},
methods: {
show() {
console.log(document.querySelector("h2"));//真实dom
console.log(this.$refs.hh2);//真实dom
// 这个vc指的是school里面的
console.log(this.$refs.sch);//school组件的实例对象
},
},
// 注册组件
components: {
School,
},
};
</script>
2、props配置
功能:让组件接收外部传过来的数据。
传递数据:
<Student name='李四' :age=56 sex='男'></Student>
<Student name='张三' sex='女'></Student>
接收数据:
第一种方式(只接收)
props:['name','age','sex',]
第二种方式(限制类型)
props:{
name:String,
age:Number,
sex:String,
}
第三种方式(限制类型、限制必要性、指定默认值)
props: {
name: {
type: String, //name的类型是字符串
required: true, //name是必要的
},
age: {
type: Number,
default: 999, //默认值
},
sex: {
type: String,
required: true,
},
},
备注: props是只读的,Vue底层会监测你对props的修改,如果进行了修改,
就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data
中一份,然后去修改data中的数据。
完整写法
Student.vue
<template>
<!--组件的结构 -->
<div class="demo">
<h2>学生名字:{{ name }}</h2>
<h2>学生年龄:{{ myAge }}</h2>
<h2>学生性别:{{ sex }}</h2>
<button @click="addAge">点我年龄加1</button>
<h2>{{ msg }}</h2>
</div>
</template>
<script >
// 组件交互相关的脚本
//简化版写法
export default {
// 如果不写name,别人在注册组件的时候,随便起名
// name的名称与文件名保持一致
name: "Student",
data() {
return {
// name: "lxl",
// age: 23,
// sex:'男',
msg: "--------------加油----------------",
// myAge是属性名,传过来的数据,先到props,再到data里面
myAge: this.age,
};
},
methods: {
addAge() {
this.myAge++;
},
},
// props:['name','age','sex',],//普通接收
// 接收的同时对数据进行类型限制
// props:{
// name:String,
// age:Number,
// sex:String,
// }
// 接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
props: {
name: {
type: String, //name的类型是字符串
required: true, //name是必要的
},
age: {
type: Number,
default: 999, //默认值
},
sex: {
type: String,
required: true,
},
},
};
</script>
<style>
.demo {
background-color: pink;
}
</style>
App.vue
<template>
<div>
<Student name='李四' :age=56 sex='男'></Student>
<Student name='张三' sex='女'></Student>
</div>
</template>
<script>
// 引入组件
import Student from "./components/Student.vue";
export default {
// app的作用:汇总所有组件
name: "App",
//注册组件
components: {
Student,
},
};
</script>
<style>
</style>
3、mixin混入
mixin(混入)
功能: 可以把多个组件共用的配置提取成一个混入对象使用方式:
第一步定义混合,例如:
{
data(){…},
methods:{…}
}
第二步使用混入,例如:
(1).全局混入: Vue.mixin(xxx)
(2).局部混入:mixins:[ ‘xxx’ ]
项目结构
mixin.js------------------------------------------------------------文章来源:https://www.toymoban.com/news/detail-411399.html
// 分别暴漏
export const mixin = {
methods: {
tishi() {
alert(this.name);
}
},
}
// 除了方法,还可以暴露数据
export const mixin2 = {
data() {
return {
x: 100,
y: 200,
}
},
}
School.vue---------------------------------------------------------文章来源地址https://www.toymoban.com/news/detail-411399.html
<template>
<!--组件的结构 -->
<div class="demo">
<h2>学校名字:{{ name }}</h2>
<h2>学校名字:{{ address }}</h2>
<button @click="tishi">点我提示学校</button>
</div>
</template>
<script >
// 引入mixin
import {mixin} from '../mixin'
//简化版写法
export default {
// 如果不写name,别人在注册组件的时候,随便起名
// name的名称与文件名保持一致
name: "School",
data() {
return {
name: "b站大学",
address: "online",
};
},
mixins:[mixin],
};
</script>
<style>
/* 组件的样式 */
.demo {
background-color: pink;
}
</style>
到了这里,关于vue基础知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!