一、初始Vue
1、前置工作
(1)给浏览器安装Vue Devtools 插件
(2)标签引入Vue包
(3)阻止vue在启动时生成生产提示Vue.config.productionTip = false
2、初始Vue
(1)想让Vue工作,就必须先创建一个Vue实例,且要传入一个配置对象比如下面的el,data;
(2)root容器里的代码依然符合HTML规范,只不过混入了一些vue语法
(3)root容器里的代码被称为【vue模板】
(4)一个容器对应一个实例,一一对应
(5)插值语法{ {xxx}} 中的xxx要写js表达式,且xxx可以自动读取到data中的所以属性。
(6)一旦data中的数据发生改变,那么模板中用到该数据的地方会自动更新
<!-- 准备好一个容器 -->
<div id="root">
<h1>hello,{
{name}}</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止vue在启动时生成生产提示
new Vue({
el: '#root', //(或可以用:document.getElemnetById('root')直接指定)用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
data: { //data中用于存储数据,数据供el所指定的容器使用,值暂时写成了一个对象,后边应该是个函数
name: '世界',
address: '苏州'
},
});
</script>
二、模板语法
1、插值语法
功能:用于解析标签体内容
写法:{ {xxx}},xxx是js表达式,可以直接读取到data中的所以区域
2、指令语法
功能:用于解析标签(包括:标签属性、标签内容、绑定事件...)
举例:<a v-bind:href="xxx">可以简写为<a :href="xxx">,xxx是js表达式,可以直接读取到data中的所以区域
<!-- 准备好一个容器 -->
<div id="root">
<h1>插值语法</h1>
<h2>hello,{
{name}}</h2>
<hr>
<h1>指令语法</h1>
<a v-bind:href="school.url">点击去百度{
{school.name}}</a>
<a :href="school.url.toUpperCase()">点击去百度</a> <!-- //.toUpperCase(),字母换成大写 -->
</div>
<script>
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el: '#root',
data: {
name: 'xjx',
school: {
name: '湖科大',
url: 'https://www.baidu.com/',
}
}
})
</script>
三、数据绑定
vue中有两种数据绑定方式
1、单项绑定:v-bind ,数据只能从data流向页面。
2、双向绑定:v-model ,数据不仅从data流向页面,还可以从页面流向data
备注:
1、双向绑定一般应用在表单类元素上,如input,select
2、v-model:value可以简写成v-model
四、el与data 的两种写法
1、el的两种写法
(1)new Vue时配置el属性
(2)先创建Vue实例对象,随后在通过vm.$mount('#root')指定el的值
2、data的两种写法
(1)对象式:data:{}
(2)函数式:后期学到组件式,必须用函数式,否则会报错.data(){return{}}
注:
由vue管理的函数,一定不要写箭头函数,因为vue中的箭头函数,this是指向windows的,不是指向vue实例对象的。
<script>
Vue.config.productionTip = false
/* el的第一种用法 */
/* new Vue({
el: '#root',
data: {
name: '小席'
}
}) */
/* el的第二种用法 */
/* const x = new Vue({
data: {
name: '小席'
}
})
x.$mount('#root') */
//data的第一种写法:对象式
/* new Vue({
el: '#root',
data: {
name: '小席'
}
}) */
//data的第二种写法:函数式
new Vue({
el: '#root',
data() { //data: function () {}
console.log(this) //此处this表示Vue的实例对象
return {
name: '小席'
}
}
})
</script>
五、MVVM模式
M:model(模型) data中的数据
V:view(视图) 模板代码
vm:viewmodel(视图模型) vue实例
注:1 data中的所有属性,最后都出现在了vm身上
2 vm的所有属性及vue原型上的所有属性,在vue模板中都可以使用
六 、数据代理
1、Object.defineProperty
(要定义属性的对象,要定义或修改的属性的名称或 Symbol ,要定义或修改的属性描述符)方法
三个参数
<script>
Vue.config.productionTip = false
let number = 18
let person = {
name: '小席',
sex: '女'
}
Object.defineProperty(person, 'age', {
/* value: 18,
configurable: true, //控制属性是否可以被删除,默认值是false
enumerable: true, //控制属性是否可以被枚举
writable: true, //控制属性是否可以被修改 */
//读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
return number
},
//修改person的age属性时,get函数(getter)就会被调用,且会收到修改的具体值
set(value) {
number = value
}
})
</script>
2、vue中的数据代理
(1)通过vm对象来代理data对象中属性的操作(读/写)
(2)vue数据代理的好处:更加方便的操作data中的数据
(3)基本原理
通过object.defieProperty(),把data对象中的所有属性添加到vm中
为每一个添加到vm上的属性,都指定getter和setter
在getter和setter内部去操作(读写)data中对应的属性
七、计算属性与监听属性
1、计算属性complute
1、定义:要用的属性存在,要通过已有属性计算
2、原理:底层借助object.defineProperty方法提供的getter和setter
3、与model相比,内部有缓存机制,效用更高,调试方便
4、注:
计算属性会直接出现在vm上,直接读取即可
如果计算属性要被修改,必须要写set函数去响应,引起计算时所依赖的数据发生改变
<div id="app">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="lastName"><br>
<!-- 不是{
{fullName()}} -->
姓名:<span>{
{fullName}}</span>
</div>
<script>
Vue.config.productionTip = false
const vm = new Vue({
el: '#app',
data: {
firstName: '小',
lastName: '希'
},
// 计算属性
computed: {
/* // 完整写法
fullName: {
//get的作用,当有人读取了fullName时,get就会被调用,且get的返回值是fullName的值
//get什么时候被调用?两种情况 1、初次读取fullName,之后都是在缓存里调用 2、所依赖的数据发生变化时
get() {
console.log('get被调用了')
// console.log(this) //这里的this是指vm
return this.firstName + '-' + this.lastName
},
//当fullName被修改时set被调用
set(value) {
console.log('set', value)
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
} */
//简写:只有被读取,没有被修改时才能用简写。下面的函数就相当于getter
fullName() {
//get的作用,当有人读取了fullName时,get就会被调用,且get的返回值是fullName的值
//get什么时候被调用?两种情况 1、初次读取fullName,之后都是在缓存里调用 2、所依赖的数据发生变化时
console.log('get被调用了')
// console.log(this) //这里的this是指vm
return this.firstName + '-' + this.lastName
}
}
})
</script>
计算属性中的setter函数运行原理
2、监听事件watch
1、当被监视的属性发生变化时,回调函数自动调用,进行相关操作
2、监视的属性必须存在,才能进行监视
3、监视的两种写法:
(1)在vue实例对象中传入watch方法配置
(2)通过vm$watch('监听的事件',handle())监视
<div id="app">
<h2>今天天气很{
{info}}</h2>
<!-- 绑定事件的时候:@xxx="yyy",yyy可以简单写一些表达式。比如下边的可以写为@click="isHot = !isHot" -->
<button @click="changeWeather">点击切换</button>
</div>
<script>
Vue.config.productionTip = false
const vm = new Vue({
el: '#app',
data: {
isHot: true
},
computed: {
info() {
return this.isHot ? '热' : '凉快'
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot
}
},
//监听事件
watch: {
info: {
immediate: true, //初始化时让handle调用一下
//当info发生变化时handle被调用
handler(newValue, oldValue) {
console.log('info被修改了', newValue, oldValue)
}
}
}
})
//监听事件的另一种写法
vm.$watch('info', {
immediate: true, //初始化时让handle调用一下
//当info发生变化时handle被调用
handler(newValue, oldValue) {
console.log('info被修改了', newValue, oldValue)
}
})
深度监视deep
(1)vue中的watch默认不监视对象内部值的改变(一层)
(2)配置deep:true可以监视对象内部的改变
注:
(1)vue本身可以监视对象内部值的改动,但vue提供的watch默认不可以
(2)使用watch时根据数据的具体结构,决定是否采用深度监视
watch: {
info: {
immediate: true, //初始化时让handle调用一下
//当info发生变化时handle被调用
handler(newValue, oldValue) {
console.log('info被修改了', newValue, oldValue)
}
},
//监听a(监听多级结构中的某个属性的变化)
'number.a': {
handler() {
console.log('a发生变化了')
}
},
//监听多级结构中的所以属性的变化
number: {
deep: true,
handler() {
console.log('number发生变化了')
}
}
}
3、两者的区别
(1)complute能完成的功能,watch都能完成
(2)watch能完成的不一定complute能完成,例如,watch能进行异步操作,setTimeout()
注:
(1)被vue管理的函数,最好都写成普通函数,这样this的指向才能是vm,或组件实例对象
(2)所有不被vue管理的函数(定时器的回调函数、ajax的回调函数、promise的回调函数等),最后写成箭头函数,这样this的指向才能是vm,或组件实例对象
八、键盘事件
1.Vue中常用的按键别名:
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用)
上 => up
下 => down
左 => left
右 => right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
3.系统修饰键(用法特殊):ctrl、alt、shift、meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐)
5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
<div id="root">
<h2>欢迎来到{
{name}}学习</h2>
<input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
Vue.config.keyCodes.huiche = 13 //定义了一个别名按键
new Vue({
el:'#root',
data:{
name:'尚硅谷'
},
methods: {
showInfo(e){
// console.log(e.key,e.keyCode)
console.log(e.target.value)
}
},
})
</script>
九、绑定样式
1. class样式
写法:class="xxx" xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2. style样式
:style="{fontSize: xxx}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象。
<div id="app">
<!--1、 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
<div class="basic" :class="mood" @click="changeMood">{
{name}}</div> <br><br>
<!-- 2、绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
<div class="basic" :class="classArr">{
{name}}</div> <br /><br />
<!-- 3、绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
<div class="basic" :class="classObj">{
{name}}</div> <br /><br />
<!-- 4、绑定style样式--对象写法 -->
<div class="basic" :style="styleObj">{
{name}}</div> <br /><br />
<!-- 5、绑定style样式--数组写法 -->
<div class="basic" :style="styleArr">{
{name}}</div>
</div>
<script>
Vue.config.productionTip = false
new Vue({
el: '#app',
data: {
name: '小希',
mood: 'normal',
classArr: ['atguigu1', 'atguigu2', 'atguigu3'],
classObj: {
atguigu1: false,
atguigu2: false,
},
styleObj: {
fontSize: '40px',
color: 'red',
},
styleObj2: {
backgroundColor: 'orange'
},
styleArr: [{
fontSize: '40px',
color: 'blue',
},
{
backgroundColor: 'gray'
}
]
},
methods: {
changeMood() {
const arr = ['happy', 'sad', 'normal']
const index = Math.floor(Math.random() * 3)
this.mood = arr[index]
},
},
})
</script>
十、条件渲染
1.v-if
写法:
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
2.v-show改变的是display
写法:v-show="表达式"
适用于:切换频率较高的场景。
特点