入门呢案例分析
<div id="app">
<h1>你好,我是{{name}}</h1>
</div>
<script>
const x = new Vue({
el: '#app',
data() {
return {
name: '张三',
age: 20
};
},
});
</script>
总结
- Vue实例和容器时一一对应的关系,并且会配合着组件一起使用
- {{xxx}}中的xxx要写js表达式,且xxx可以自动读取data中的所有属性;
- 一旦data中的数据发生改变,那么模板中用到该数据的地方也会自动更新
模板语法
Vue模板语法分为2大类:
- 插值语法
- 功能:用于解析标签体内容
- 写法:{{xxx}},xxx时js表达式,而且可以直接读取到data中所有属性
- 指令语法
- 功能:用于解析标签(包括啊:标签属性,标签内容,绑定事件)
- 举例:v-bind:href=“xxx“简写为:href=“xxx”,xxx同样要写js表达式,且可以直接读取道data中的所有属性
- 备注:Vue中有很多的指令,且形式都是v-???开头,在此举得例子时v-bind
数据绑定
<div id="root">
单向绑定:<input type="text" v-bind:value="school.name">
双向绑定:<input type="text" v-model:value="school.name">
简写
单向绑定:<input type="text" :value="school.name">
双向绑定:<input type="text" v-model="school.name">
</div>
<script>
const x = new Vue({
el: '#root',
data() {
return {
uname: '张三',
age: 20,
url: "https://www.baidu.com/",
school: {
name: '河南科技学院'
}
};
},
});
</script>
Vue中有两种数据绑定
- 单向绑定(v-bind):数据只能重data流向页面
- 双向绑定(v-model):数据不仅可以从data流向页面,还可以从页面流向data
- 备注
- 双向绑定一般用在表单类元素上(如:input,select等)
- v-model:value可以简写成v-model,因为v-model默认收集的就是value值
el与data的两种写法
-
el有两种写法
- .new Vue时配置el属性
- 先创建Vue实例,随后再通过vm.$mount(‘#app’)指定el的值
-
data有两种写法
-
一个重要原则 由Vue管理的函数一定不要用箭头函数,箭头函数没有自己的this
MVVM模型
- M:模型(Model)
- V:视图(View)
- VM:视图模型(ViewModel):Vue实例对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YT8rVA4B-1666772187950)(img/image-20220906213326911.png)]
数据代理
let number = 13;
let person = {
name: '张三',
sex: '男',
adress: '郑州'
}
Object.defineProperty(person, 'age', {
get() {
return number
},
set(value) {
number = value;
console.log('有人修改了person的age值是' + value);
}
})
console.log(person);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CmqzKqIH-1666772187951)(img/image-20220907092507149.png)]
- 将obj2添加属性x,值为objx的值,当修改obj2的值时自动修改obj中的x值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nH42stzQ-1666772187952)(img/image-20220907153424087.png)]
事件处理
<div id="app">
<h1>开始练习</h1>
<button @click="showInfo1">点我提示信息(不传参)</button>
<!-- 采用占位符号$ -->
<button @click="showInfo2(18,$event)">点我提示信息(传参)</button>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
property: 'value',
};
},
methods: {
showInfo1(event) {
console.log(event.target);
},
showInfo2(number, e) {
console.log(number, e.target);
}
}
})
</script>
事件的基本使用
- 使用v-on:xxx或者@xxx绑定事件,其中xxx时事件名
- 时间的回调需要配置子methods中,最总会在vm中
- methods中配置的函数不要使用箭头函数!否则this就不是vm了
- methods中配置的函数,都是被Vue所管理的函数,this的指向时vm或者组件实例对象
- @click="demo"和@click="demo($event)"效果是一样的,但后者可以传参
Vue中事件的修饰符
Vue常用的事件修饰符,修饰符可以连续写
- prevent:阻止默认事件(常用)
- stop:阻止事件冒泡(常用)
- once:事件只触发一次
- capture:使用事件捕获模式
- self:只有event.target是当前操作的元素时才触发事件
- passive:事件的默认行为立即执行,无需等待回调函数执行完毕
<div id="app">
<h1>开始练习</h1>
<!-- 阻止事件默认行为,a标签的默认行为是跳转 -->
<a href="http://www.baidu.com" @click.prevent="a">点我进行页面跳转</a>
<!-- 阻止事件冒泡 -->
<div class="box1" @click.stop="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 事件只触发一次 -->
<div id="demo" @click="showInfo">
<button @click.once="showInfo">点击触发事件</button>
</div>
<!-- 使用事件捕获模式 -->
<div class="box1" @click.="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 使用事件捕获模式 -->
<div class="box1" @click.capture="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 点击div1才触发 -->
<div class="box1" @click.self="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 两种滑动滚轮的方式,scroll和wheel;
scoll默认事件和回调函数一起执行
wheel是执行回调函数后执行默认事件
-->
<ul class="ull" @scroll="move">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
property: 'value',
};
},
methods: {
a() {
alert('我可以跳转到百度')
},
showInfo(event) {
alert('Hello World ')
},
showMsg(number) {
alert('输出的值是' + number)
},
move() {
console.log('滚动了');
}
}
})
</script>
键盘事件
<div id="app">
<h1>开始练习</h1>
<input type="text" placeholder="按下回车提示输入信息" @keyup.enter="showInfo">
</div>
<script>
new Vue({
el: '#app',
data() {
return {
property: 'value',
};
},
methods: {
showInfo(e) {
console.log(e.key, e.keyCode);
}
}
})
</script>
Vue中常见的按键别名:
回车(enter) 删除(delete) 退出(esc) 空格(space) 换行(tab) 上(up) 下(down) 左(left) 右(right)
计算属性
<div id="app">
<h1>开始练习</h1>
姓:<input type="text" v-model="fistName"><br/><br/> 名:
<input type="text" v-model="lastName"><br/><br/> 全名:
<span>{{fullName}}</span>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
fistName: '张',
lastName: '三'
};
},
computed: {
fullName: {
get() {
console.log('get被调用了');
return this.fistName + '-' + this.lastName;
},
set(value) {
console.log('set方法被调用');
let arr = value.split('-');
this.fistName = arr[0];
this.lastName = arr[1];
}
}
}
})
</script>
计算属性:
- 定义:要用的属性不存在,要通过已有的属性计算得来
- 原理:底层借助了Objcet.defineproperty方法提供的getter和setter
- get函数什么时候执行?
- 当读取时会执行一次
- 当依赖的数据发生改变时会被再次调用
- 优势:与methods相比,内部有缓存机制(复用),效率高,调试方便
- 备注:
- 计算属性终会出现在vm上,直接读取使用即可(不能读取其中的get方法)
- 如果计算属性要被修改,那必须写set函数去影响修改,且set中要引起计算时以来的数据发生改变
监视属性
<div id="app">
<h1>开始练习</h1>
<h2>今天天气很{{weather}}</h2>
<button @click="changWeather">点击我更改天气</button>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
isHot: true
}
},
computed: {
weather: function() {
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changWeather() {
this.isHot = !this.isHot
}
},
watch: {
isHot: {
immediate:true,
deep:true,
handler() {
console.log('isHot被修改了');
}
}
}
watch: {
isHot(newValue,oldValue){
console.log('isHot被修改了');
}
}
})
</script>
监视属性watch:
- 当监视的属性发生变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视!!
- 监视的两种写法:
- new Vue时传入watch配置
- 通过vm.$watch监视
深度监视
<div id="app">
<h1>开始练习</h1>
<h2>
a的值是:{{number.a}}
</h2>
<button @click="number.a++">点我让a++</button>
<h2>
b的值是:{{number.b}}
</h2>
<button @click="number.b++">点我让b++</button>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
number: {
a: 1,
b: 2
}
}
},
watch: {
'number.a': {
deep: true,
handler() {
console.log('a改变了');
}
}
}
})
</script>
深度监视:
- vue中watch默认不见时对象内部的改变(一层)
- 配置的deep:true可以监视对象内部值的改变
备注:
- vue自身可以监视对象内部值的改变,但Vue提供的watch默认不可以
- 使用warch时根据数据的具体结构,决定是否采用深度监视
computed 和 watch之间的区别:
- computed能完成的功能,watch都能够完成
- watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
两个小原则:
- 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或者组件实例对象
- 所用不被Vue所管理的函数(定时器的回调函数,ajax的回调函数等,Promise的回调函数),最好写成箭头函数,这样this的指针才能是vm或者组件实例对象
绑定样式
<div id="app">
<h1>开始练习</h1>
<input type="text" :value="fullName"><br>
<button @click="changMood">点击更换姓名</button>
<!--class绑定样式字符串法,适用于:样式的类名不确定,需要动态指定 -->
<div class="basic" :class="color" @click="changeColor">点击更换颜色</div>
<!-- class绑定样式数组法,适用于要绑定的个数不确定,名字也不确定 -->
<div class="basic" :class="arr" >更换颜色</div>
<!-- class绑定样式对象法,适用于要绑定的个数不确定,名字也不确定 -->
<div class="basic" :class="classObj" >更换颜色</div>
<!-- style绑定样式对象法,适用于要绑定的个数不确定,名字也不确定 -->
<div class="basic" :style="styleObj" >更换颜色</div>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
fullName: '张三',
color: 'normal',
arr: ['style1', 'style2', 'style3'],
classObj: {
style1: false,
style2: false
},
styleObj: {
fontSize: '50px',
backgroundColor: 'yellow',
fontColor: 'gray'
}
}
},
methods: {
changMood() {
this.fullName = '王五'
},
changeColor() {
const arr = ['happy', 'sad', 'normal']
let index = Math.floor(Math.random() * 3)
this.color = arr[index];
},
}
})
</script>
条件渲染
<div id="app">
<h1>开始练习</h1>
<h2>a={{a}}</h2>
<button @click="a++">点击我实现a++</button>
<h2 v-show="false">我来自{{adress}}1</h2>
<!-- 中间结构不能够打断 -->
<h2 v-if="a==1">第一</h2>
<h2 v-else-if="a==2">第二</h2>
<h2 v-else-if="a==3">第三</h2>
<h2 v-else>第四</h2>
<!-- template只能和v-if配合使用 -->
<template v-if="n==1">
<h3>北京</h3>
<h3>上海</h3>
<h3>广州</h3>
</template>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
adress: '河南省',
a: 0
}
},
})
</script>
- v-if
- v-if;v-else-if;v-else;中间不能够打断
- 适用于切换频率不高的场景
- 特点:不展示DOM元素(如果为false,页面没有)
- v-show
- 写法:v-show="“表达式”
- 适用于切换频率不高的场景
- 特点:不展示DOM元素,仅仅是使样式隐藏掉
react、vue、中的key什么用
-
虚拟DOM中key的作用
- key是DOM的对象标识,当数据发生改变时vue会根据【新数据】生成【新的虚拟DOM】
-
新虚拟DOM与旧虚拟DOM对比原则
- 旧的虚拟DOM找新虚拟DOM相同的key:
- 若虚拟DOM没有内容变化,直接使用之前的真实DOM
- 若虚拟DOM内容改变了,则生成新的真实DOM,随后替换页面中之前的真实DOM
- 旧的DOM未找到新虚拟DOM相同的key
- 创建新的真实DOM,让后渲染页面
-
用index和key可能引发的问题
-
开发中如何选用key?
- 最好使用每条数据的唯一标识作为key,如id,手机号,身份证号码,学号等唯一标识
列表排序
<div id="app">
<h1>开始测试</h1>
<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 in filPersons">
{{p.name}}--{{p.age}}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
keyWord: '',
sortType: 0,
persons: [
{id: '001',name: '周杰伦',age: 23},
{id: '002',name: '张望伦',age: 18},
{id: '003',name: '张三丰',age: 35},
{id: '003',name: '周找天',age: 19}
],
}
},
computed: {
filPersons() {
const arr = this.persons.filter((p) => {
return p.name.indexOf(this.keyWord) != -1
})
if (this.sortType) {
arr.sort((p1, p2) => {
return this.sortType == 2 ? p1.age - p2.age : p2.age - p1.age
})
}
return arr
}
},
})
</script>
Vue监测数据原理
数据更改==》set()调用,set里写了个调用重新解析模板==》生成新的虚拟DOM==》新旧虚拟DOM对比==》生成真实页面
Vue数据监视
-
vue会监视data中所有层次的数据 -
如何仅是对象中的数据
- 通过setter实现监视,要在 new Vue时加入监视的数据
- 对象中后追加的属性,Vue默认不做处理
- 如果给后添加的属性做响应式,使用API
- Vue.set(target, propertyName, value) Vue.set(this.student, ‘sex’, ‘男’)
- vm.
s
e
t
(
t
a
r
g
e
t
,
p
r
o
p
e
r
t
y
N
a
m
e
,
v
a
l
u
e
)
t
h
i
s
.
set(target, propertyName, value) this.
set(target,propertyName,value)this.set(this.student, ‘sex’, ‘男’)
-
如何检测数组中的数据 通过包裹数组更新元素的方式实现
- 调用原生对应的方法对数组进行更新
- 重新解析模板,进行更新页面
-
Vue中修改数组中某个元素一定用到如下方法: API:push(),pop(),shift(),unshift(),splice(),sort(),reverse() Vue.set()或者vm.$set()
收集表单数据
<div id="app">
<form @submit.prevent="demo">
<label for="account">账号</label><input type="text" id="account" v-model.trim="account">
<label for="ps">密码</label><input type="text" id="ps" v-model="password">
<label for="age">年龄</label><input type="number" id="age" v-model.number="age">
性别:
男<input type="radio" name="sex" value="male" v-model="sex">
女<input type="radio" name="sex" value="female" v-model="sex">
爱好:
学习<input type="checkbox" v-model="hobby" value="study">
打游戏<input type="checkbox" v-model="hobby" value="game">
吃饭<input type="checkbox" v-model="hobby" value="eat">
所属校区
<select v-model="city">
<option value="beijing" >北京</option>
<option value="shenzhen" >深圳</option>
<option value="wuhan" >武汉</option>
</select><br><br> 其他信息
<textarea v-model.lazy="other"></textarea>
<input type="checkbox" v-model="agree">
阅读并接受<a href="http://www.baidu.com">《用户协议》</a>
<button>提交</button>
</form>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
account: '',
password: '',
age: '',
sex: '',
hobby: [],
city: 'beijing',
other: '',
agree: ''
}
},
methods: {
demo() {
console.log(JSON.stringify(this._data));
}
},
})
</script>
-
若: , 则v-model收 集的是value值,用户输入的就是value值。 -
若: , 则v-model收 集的是value值,且要给标签配置value值。 -
若: 1.没有配置input的value属性,那么收集的就是checked (勾选or未勾选,是布尔值) 2.配置input的value属性:
备注: v-model的 三个修饰符:
-
lazy:失去焦点再收集数据 -
number:输入字符串转为有效的数字 -
trim:输入首尾空格过
v-指令
v-once
-
v-once在初次动态渲染后就视为静态内容了 -
以后数据的改变不会引起v-once所在结构的更新
v-pre
自定义指令
-
需求1:定义一个v-big指令, 和v-text功能类似,但会把绑定的数值放大10倍。 -
需求2:定义-一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。 -
自定义指令总结: 定义语法:
-
局部指令: new Vue({
directives:{指令名:配置对象}
})
new Vue({
directives:{指令名,回调函数}
})
2.全局指令: Vue.directive(指令名,配置对象)或Vue . directive(指令名,回调函数) -
配置对象中常用的3个回调:
- .bind:指令与元素成功绑定时调用。
- .inserted:指令所在元素被插入页面时调用。
- .update:指令所在模板结构被重新解析时调用。
-
备注:
- .指令定义时不加心,但使用时要)加Iv-;
- 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
Vue生命周期
div id="app">
<h1>当前数字是:{{n}}</h1>
<button @click="n++"></button>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
n: 1,
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted', this);
},
beforeUpdate() {
console.log('beforeUpdate');
},
updated() {
console.log('updated');
},
beforeDestroy() {
console.log('beforeDestroy');
},
destroyed() {
console.log('destroyed');
},
})
</script>
常用的生命周期函数
- mounted:发送ajax请求,启动定时器,绑定自定义事件,订阅消息等【初始化操作】
- beforeDestory:清除定时器,绑定自定义事件,取消订阅消息【收尾工作】
关于销毁Vue实例
- 销毁后借助Vue的开发工具不会有任何信息
- 销毁自定义事件会失效,但原生DOM事件依然有效
- 一般不会在beforeDestroy操作数据,但即使操作了,也不会触发更新流程
非单文件组件
基本使用
Vue中使用组件的三大步骤
-
如何定义一个组件
- 使用Vue.extend(options)创建,其中options和 new Vue(options)时传入的那个options几乎一样,但也有点不同:
- el不要写,为什么?最终所有的组件都要经过一个vm管理,有vm中的el决定哪一个服务器
- data必须写成函数,为什么?避免组件被复用时,数据存在引用的关系
- 使用tmplate可以配置组件结构
-
如何注册组件?
- 局部注册:靠new Vue的时候传入components选型
- 全局注册:靠Vue.component(‘组件名’,组件)
-
编写组件标签 <div id="app1">
<h1>{{msg}}</h1>
<hr>
<xuexiao></xuexiao>
<hr>
<div id="app2">
<hello></hello>
</div>
</div>
<script>
const school = Vue.extend({
template: `
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">惦记我提示学校名称</button>
</div>
`,
data() {
return {
schoolName: '科技学院',
address: '新乡',
}
},
})
Vue.component('hello', hello)
new Vue({
el: '#app1',
data() {
return {
msg: '你好啊'
}
},
components: {
xuexiao: school,
}
})
</script>
组件注意事项
- 关于组件名称
- 一个单词写法
- 第一种首字母小写:school
- 第二种首字母大写:School
- 多个单词组成
- 第一种写法(kebab-case命名):my-school
- 第二种写法(CameCase命名):MySchool(需要用Vue脚手架支持)
- 备注
- 组件名尽可能回避HTML中已有的元素名称:例如H1,H2
- 可以使用name配置项指定组件在开发者工具中呈现的名字
- 过于组件的标签
- 第一种写法:
- 第二种写法:
- 备注:不适用脚手架,会导致后续组件不能渲染
- 组件定义简写
组件的嵌套
<div id="app1">
<app></app>
</div>
<script>
const student = {
name: 'student',
template: `
<div>
<h2>学生姓名:{{studentName}}</h2>
</div>
`,
data() {
return {
studentName: '小明',
}
},
}
const school = Vue.extend({
template: `
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<hr>
<student></student>
</div>
`,
data() {
return {
schoolName: '科技学院',
address: '新乡',
}
},
components: {
student,
}
})
const app = Vue.extend({
template: `
<div>
<school></school>
</div>
`,
components: {
school
}
})
new Vue({
el: '#app1',
data() {
return {
msg: '你好啊'
}
},
components: {
app
}
})
</script>
VueComponnet
-
school组件的本质时一个名为VueComponent的构造函数,且不是程序员定义的,时Vue.extend生成的 -
我们只需要写或者,Vue解析时会帮助我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options) -
特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!! -
关于this的指向
-
组件配置中: data函数,methods中的函数,watch中的函数,computed中的函数 他们的this是VueComponent实例对象 -
new Vue()配置中 data函数,methods中的函数,watch中的函数,computed中的寒素,他们的this是Vue实例对象 -
vueComponent实例对象,简称vc
原型与原型链
class Student {
constructor(name, score) {
this.name = name;
this.score = score;
}
introduce() {
console.log(`我是${this.name},考了${this.score}分。`);
}
}
const student = new Student('张三', '99');
console.log(student.__proto__ === Student.prototype);
实例对象(student)的隐式原型对象 === 构造函数(Student)的显示原型对象
统统指向原型对象
一个重要的内置关系
vue.component.prototype.(proto)==Vue.prototype
结论:让VueComponent的实例对象(vc)可以使用Vue原型上的属性和方法
单文件组件
<template>
<div class="demo">
<!-- 组件的结构 -->
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">惦记我提示学校名称</button>
</div>
</template>
<script>
//组建的交互样式
//三种暴漏方式
/* 1,export--分别暴漏,前加 */
// const school = Vue.extend({
// data () {
// return {
// schoolName: '科技学院',
// address: '新乡',
// }
// },
// methods: {
// showName () {
// alert(this.schoolName)
// }
// },
// })
//export{}2,统一暴漏
/* 3,默认暴漏,多数使用 */
// export default school
export default {
name: 'School',
data () {
return {
schoolName: '科技学院',
address: '新乡',
}
},
methods: {
showName () {
alert(this.schoolName)
}
},
}
</script>
<style>
/* 样式的注释 */
.demo {
background-color: skyblue;
}
</style>
render函数
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App),
})
组件自定义事件
-
一种通信的方式:适用于子组件传给父组件 注意:父传子props最方便 -
使用场景:A是父组件,B是子组件,B想给A传数据那么需要在A中给B绑定自定义事件 -
绑定自定义事件:
-
第一种方式,父组件中:<Demo @haha=“test”> -
第二种方式,在父组件中 <School ref="school" />
mounted () {
this.$refs.school.$on('dizhi', this.sendSchoolAddress)
},
-
若想让自定义事件只触发一次可以用once修饰符,或者$once方法 -
出发绑定事件:this.$emit(‘haha’,数据) -
解除绑定自定义事件this.$off(‘haha’) -
组件想使用原生的DOM事件(指原有的事件例如@click)需要使用native修饰符
全局事件总线
-
安装全局事件总线
new Vue({
el: '#app',
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this;
},
})
-
使用全局时间总线
methods(){
this.$bus.$emit('changeTodo', id)
}
mounted(){
this.$bus.$on('changeTodo', this.demo)
}
消息订阅与发布
-
安装第三方库 npm i pubsub-js -
引入: import pubsub from ‘pubsub-js’
sendStudentAge () {
pubsub.publish('hello', 666)
},
mounted () {
pubsub.subscribe('hello', (a, b) => {
console.log('我是订阅函数,它的数据是' + a, b);
console.log(this);
})
},
Vue动画
配置代理
在vue.config.js中添加如下配置
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8081',
pathRewrite:{'^/api':''}
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
}
插槽
在标签内部放入内容(默认插槽)
<template>
<div class="contain">
<Category solt="center" title="美食" :listData="foods">
<input type="text" value="我是小李子" />
</Category>
</div>
</template>
<template>
<div class="card">
<h2>{{ title }}</h2>
<ul>
<li v-for="(item, index) in listData" :key="index">
{{ item }}
</li>
<slot name="center"></slot>
</ul>
</div>
</template>
作用域插槽
在components中
<template>
<div class="card">
<h2>{{ title }}</h2>
<ul>
<li v-for="(item, index) in listData" :key="index">
{{ item }}
</li>
<slot :games="games"></slot>
</ul>
</div>
</template>
<script>
export default {
name: 'Category',
data() {
return {
games:['游戏1','游戏2','游戏3']
}
},
props: ['title', 'listData']
}
</script>
调用插槽者
<template>
<div class="contain">
<Category title="美食" :listData="foods">
<template scope='data'>
<ul>
<li v-for=" (g,index) in data.games" :key="index"></li>
</ul>
</template>
</Category>
</div>
</template>
创建Vue脚手架
##窗口执行
npm install -g @vue/cli
Vue中的配置对象(以pages举例)
module.exports = {
pages: {
index: {
entry: 'src/index/main.js',
template: 'public/index.html',
filename: 'index.html',
title: 'Index Page',
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
subpage: 'src/subpage/main.js'
}
}
ref属性
-
别用来给元素或子组件注册引用的信息(id的替换者) -
应用在html标签上获取的真实DOM元素,应用在组件标签上的组件实例对象(vc) -
使用方式 打标识: …或者…**** 获取:this.$refs.xxx
<template>
<div>
<h1 ref="title">点我展示上方元素</h1>
<button @click="showDom">展示上方元素</button>
<Add ref="add"></Add>
</div>
</template>
<script>
import Add from './components/Add'
export default {
name: 'App',
components: { Add },
methods: {
showDom () {
console.log(this.$refs.title);
console.log(this.$refs);
console.log(this.$refs.add);
}
},
}
</script>
props属性
<template>
<div>
<!-- 组件的结构 -->
<h1>我的个人信息是</h1>
<h2>学生名称:{{ name }}</h2>
<h2>学生年龄:{{ age }}</h2>
<h2>学生学校:{{ school }}</h2>
·
</div>
</template>
<script>
export default {
name: 'student-name',
props: {
name: {
type: String,
required: true,
},
age: {
type: Number,
default: 99
},
school: {
type: String,
required: true,
}
},
}
</script>
<template>
<div>
<student-name name="李华" :age="15" school="科技学院"></student-name>
</div>
</template>
<script>
import StudentName from './components/Student.vue'
export default {
name: 'App',
components: {
'student-name': StudentName
}
}
</script>
功能:让组件接受外部传入的数据 备注:props是只读属性,Vue底层会检测你对props的修改,如果进行了修改,就会发出警报,若业务需要对数据的修改,那么请复制props的内容一份送到data中,让后去修改data中的数据
mixin(混入)
-
功能:可以把多个组件共有的配置提供成一个混入对象 -
使用方式: 第一步定义混合
{
data(){
},
methods:{
}
}
第二步使用混入
(1)全局的混入,Vue.mixin(xx)
(2)局部的混入,mixins:['xxx']
export const m = {
methods: {
showName() {
alert(this.name)
}
},
mounted() {
console.log('你好啊')
},
}
<script>
import { m,number } from "../mixin"
export default {
name: "xue-xiao",
data () {
return {
name: "科技学院",
address: "新乡市",
}
},
mixins: [m,number]
};
</script>
plugin(插件)
-
功能:用于增强Vue -
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传入的数据。 定义插件: export default {
install(Vue, x) {
console.log(x);
Vue.filter('mySlice', function(value) {
return value.slice(0, 5)
})
Vue.directive('fbind', {
})
Vue.mixin({
})
Vue.prototype.hello = () => {
}
}
}
使用插件
scoped样式
- 多个模块中样式,当渲染时会进行汇总,此时如果模块中出现重复的样式名称则会冲突,代码采用就近原则按照后带入的为主
- 作用:让样式是在局部生效,防止冲突
- 写法>
vuex
概念:专门在Vue中实现集中式状态管理的一个Vue插件,对vue应用中多个组件的共享进行集中式的管理(读与写),依旧是一种通信的方式,且适用于任意组件间的通信
什么时候用(共享)
- 多组件依赖于同一个状态
- 来自不同组件的行为需要变更为同意状态
路由
-
使用路由
import VueRouter from 'vue-router'
import router from './router/index'
Vue.use(VueRouter)
new Vue({
el: '#app',
render: (h) => h(App),
router: router,
beforeCreate() {
Vue.prototype.$bus = this;
}
})
-
配置路由(也可以用懒加载的方式) import VueRouter from 'vue-router'
export default new VueRouter({
routes: [
{
path: '/',
redirect: '/Login/User'
},
{
path: '/Login',
name: 'Login',
component: Login,
children: [{
path: 'User',
component: User
},
{
path: 'Register',
component: Register
},
]
},
{
path: '/Todo/:name',
name: 'Todo',
component: Todo,
},
]
})
-
路由标签 <router-link to="/Login/User" class="select" active-class="active">登录区</router-link\>
<router-view></router-view>
-
传递参数 Params传参
{
path: '/child/:id',
component: Child
}
<router-link :to="/child/123">进入Child路由</router-link>
{
path: '/child/:id',
component: Child
}
this.$router.push({
path:'/child/${id}',
})
<router-link :to="{name:'Child',params:{id:123}}">进入Child路由</router-link>
{{this.$route.params.id}}
query传参
{
path: '/child',
component: Child
}
<router-link :to="{path:'/child',query:{id:123}}">进入Child路由</router-link>
this.$router.push({
name:'Child',
query:{
id:123
}
})
{{this.$route.query.id}}
-
注意对象传参中path配query; name配params;!!!否则接收不到参数 -
即使用params参数时,若使用to对象写法,则不能使用path配置项,必须使用name配置 -
路由的两个钩子函数
activated(){}
deactivated(){}
路由器的两种工作模式
-
对于一个url来说什么是hash值?——#以及后必拿的内容时hash值 -
hash值不会包含在http请求中,即:hash值不会带给服务器 -
hash模式:
- 地址永远带着#号,不带美观
- 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
- 兼容性较好
-
history模式:
-
地址干净,美观 -
兼容性和hash模式相比略差 -
应用部署上线时需要后端人员支持,解决页面服务器404的问题 },
{
path: '/Todo/:name',
name: 'Todo',
component: Todo,
},
] })
-
路由标签 <router-link to="/Login/User" class="select" active-class="active">登录区</router-link\>
<router-view></router-view>
-
传递参数 Params传参
{
path: '/child/:id',
component: Child
}
<router-link :to="/child/123">进入Child路由</router-link>
{
path: '/child/:id',
component: Child
}
this.$router.push({
path:'/child/${id}',
})
<router-link :to="{name:'Child',params:{id:123}}">进入Child路由</router-link>
{{this.$route.params.id}}
query传参
{
path: '/child',
component: Child
}
<router-link :to="{path:'/child',query:{id:123}}">进入Child路由</router-link>
this.$router.push({
name:'Child',
query:{
id:123
}
})
{{this.$route.query.id}}
-
注意对象传参中path配query; name配params;!!!否则接收不到参数 -
即使用params参数时,若使用to对象写法,则不能使用path配置项,必须使用name配置 -
路由的两个钩子函数
activated(){}
deactivated(){}
路由器的两种工作模式
- 对于一个url来说什么是hash值?——#以及后必拿的内容时hash值
- hash值不会包含在http请求中,即:hash值不会带给服务器
- hash模式:
- 地址永远带着#号,不带美观
- 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
- 兼容性较好
- history模式:
- 地址干净,美观
- 兼容性和hash模式相比略差
- 应用部署上线时需要后端人员支持,解决页面服务器404的问题
|