脚本宝典收集整理的这篇文章主要介绍了Vue2学习笔记,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<div id="app">
{{ message }}
</div>
//第一种写法
var app = new Vue({
el: '#app', //el:挂载点
data: { // data:数据对象
message: 'Hello Vue!'
}
})
//第二种写法
var app = new Vue({
data: { // data:数据对象
message: 'Hello Vue!'
}
})
app.$mount('#app'); //挂载
挂载点 :选择HTML元素,Vue会管理该元素及其后代元素(不要挂载和标签)
注意:挂载只能一一对应,不能一对多,也不能多对一
可以嵌套对象,数组等复杂数据,语法与JS语法一致
//data对象写法
data:{
massage:'hello!'
}
//data函数写法
//注意!组件中必须用这种写法
data(){
return{
massage:'hello!'
}
}
//注意!凡是由Vue管理的函数只能定义为普通函数,不能是箭头函数!!!
let test={
name:'test'
}
let a=18;
//为对象添加属性,第三个参数为配置项对象
Object.defineProperty(test,'age',{
value:18,
enumerable:true, //控制属性是否可以枚举,默认为false
writable:true, //控制属性是否可以被修改,默认false
configurable:true, //控制属性是否可以被删除,默认false
//当有人读取test的age属性时,get函数(getter)会被调用,而且返回值就是age的值
get(){
console.log('有人读取了age属性');
return a;
},
//当有人修改test的age属性时,set函数(setter)会被调用,而且会收到修改的具体值
set(value){
console.log('有人修改了age属性,且值是'+value);
a=value;
}
})
数据代理:通过一个对象代理另一个对象中属性的操作(读/写)
v-text : 设置标签的文本值(textContent)
<div id="app">
<h1 v-text="massage+'!!!!'"></h1>
<h1 v-text="massage+inf"></h1>
<h1> {{massage}}啊!{{inf}}</h1>
</div>
var app=new Vue({
el:'#app',
data:{
massage:'你好',
inf:'世界'
}
})
v-html : 设置标签的innerHTML
<div id="app">
<h1 v-text="link"></h1>
<h1 v-html="link"></h1>
</div>
var app=new Vue({
el:'#app',
data:{
link:'<a href="https://www.baidu.com">百度</a>'
}
})
注意:v-html存在安全性问题!!!
//语法
<div id="app">
<input type="button" value="点我一下" v-on:事件="事件响应函数名">
<input type="button" value="点我一下" @事件="事件响应函数名"> <!--更简单的写法-->
</div>
//实例
<div id="app">
<input type="button" value="点我一下" @click="fun">
</div>
var app=new Vue({
el:'#app',
methods:{ //事件响应函数写这里
fun:function(){
alert('你好啊!');
}
}
})
<div id="app">
<input type="button" value="点我一下" @click="fun(name)">
<!-- $event占位,用于传递事件对象 -->
<input type="text" @keyup.enter="fun($event,'李四')"> <!-- Vue提供了键盘按键的便捷绑定方式 @keyup.按键名="事件响应函数" -->
</div>
var app=new Vue({
el:'#app',
data:{
name:'张三'
},
methods:{
fun:function(event,name){
console.log(event);
alert('你好啊!'+name);
}
}
})
注 :更多详细用法查看文档!官方文档
.test5,.test2{
width: 500px;
height: 100px;
padding: 20px;
background-color: skyblue;
}
.test41{
width: 500px;
height: 100px;
background-color: springgreen;
padding: 20px;
}
.test42{
width: 400px;
height: 50px;
background-color: skyblue;
}
.test6{
width: 300px;
height: 100px;
overflow: auto;
}
.test61{
width: 200px;
height: 1000px;
background-color: skyblue;
}
<div id="root">
<!-- prevent:阻止默认事件(常用) -->
<a href="https://www.baidu.com" @click.prevent='test1'>百度一下</a>
<!-- stop:阻止事件冒泡(常用) -->
<div class="test2" @click='test2'>
<button @click.stop='test2'>test2</button>
</div>
<!-- once:事件只触发一次(常用) -->
<button @click.once='test3'>test3</button>
<!-- capture:使用事件的捕获模式 -->
<div class="test41" @click.capture="test4('test41')">
test41
<div class="test42" @click="test4('test42')">
test42
</div>
</div>
<!-- self:只有event.target是当前操作元素时才触发事件 -->
<div class="test5" @click.self='test5'>
<button @click='test5'>test5</button>
</div>
<!-- passive:事件的默认行为立即执行,无需等待事件回调执行完毕 -->
<div class="test6" @wheel.passive="test6">
test6
<div class="test61"></div>
</div>
</div>
var vm=new Vue({
el:'#root',
data:{
},
methods:{
test1(){
alert('就不百度一下!');
},
test2(){
alert('不会冒泡哟!');
},
test3(){
alert('再点一次我就不会弹出来了!');
},
test4(i){
alert(i+'捕获到了点击事件!');
},
test5(e){
alert('你点的是'+e.target);
},
test6(){
for(var i=0;i<10000000;i++){
console.log('test6');
}
}
}
})
注:修饰符可以多个连着使用
Vue常用事件别名
Vue未提供别名的按键,可以使用按键原始的Key值去绑定,但是注意如果Key值为两个以上单词,转化为-连接命名(例如:CapsLock:caps-lock)
//获取键值,键码
//为某一元素绑定按键事件(keydown,keyup都行)
console.log(event.key,event.keyCode);
系统修饰键(用法特殊):ctrl,alt,shift,meta(win键)
可以使用kkeyCode去指定具体按键,但是不推荐!!!
Vue.config.keyCodes.自定义键名=键码,可以自定义键名,不推荐!!!
注:键指定可以连着写实现Ctrl+y等事件绑定
v-show : 根据表达式真假,切换元素的显示和隐藏(操作样式:display)
<div id="app">
<img src="" v-show="true"> <!-- 直接布尔值 -->
<img src="" v-show="isShow"> <!-- 变量 -->
<img src="" v-show="age>=18"> <!-- 表达式 -->
</div>
var app=new Vue({
el:'#app',
data:{
isShow:true,
age:20
}
})
v-if : 根据表达式真假,切换元素显示和隐藏(操作Dom元素,直接将Dom元素移除或添加)
<div id="app">
<img src="" v-if="true"> <!-- 直接布尔值 -->
<img src="" v-if="isShow"> <!-- 变量 -->
<img src="" v-if="age>=18"> <!-- 表达式 -->
<div v-if="n===1">a</div>
<div v-else-if="n===2">b</div>
<div v-else-if="n===3">c</div>
<div v-else>d</div>
<!-- 需求:条件相同,显示不同内容 -->
<div v-if="n===1">a</div>
<div v-if="n===1">b</div>
<div v-if="n===1">c</div>
<!-- 解决方案一 会破环原HTML结构,进而影响样式等生效,不推荐使用-->
<div v-if="n===1">
<div>a</div>
<div>b</div>
<div>c</div>
</div>
<!-- 解决方案二 -->
<template v-if="n===1">
<div>a</div>
<div>b</div>
<div>c</div>
</template>
<!-- template只能与v-if一起使用,不能和v-show一起使用 -->
</div>
var app=new Vue({
el:'#app',
data:{
isShow:true,
age:20,
n:2
}
})
v-bind : 设置元素属性(如:src,title,class等)
<div id="app">
<img v-bind:src="imgsrc"> <!-- v-bind:属性名="属性值" -->
<img :alt="ingalt+'!!!'"> <!-- 简写为 :属性名="属性值" -->
<img v-bind:class="isActive?'active':''">
<img v-bind:class="{active:isActive}">
</div>
var app=new Vue({
el:'#app',
data:{
imgsrc:'./01.jpg',
imgalt:'图片1',
isActive:false
}
})
<div id="root">
<!-- 字符串写法,适用于:样式的类名不确定,需要动态指定(只有一个样式(类)) -->
<div :class="test1" @click="change1">test1</div>
<!-- 数组写法,适用于:样式的个数不确定,名字不确定 -->
<div class="basic" :class="test2" @click="change2">test2</div>
<!-- 对象写法,适用于:样式个数确定,名字确定,但是用不用不确定 -->
<div class="basic" :class="test3" @click="change3">test3</div>
</div>
.class1{
width: 200px;
height: 200px;
background-color: skyblue;
}
.class2{
width: 200px;
height: 400px;
background-color: skyblue;
}
.class3{
width: 400px;
height: 200px;
background-color: skyblue;
}
.class4{
width: 200px;
height: 200px;
background-color: slateblue;
}
.basic{
width: 100px;
height: 100px;
background-color: skyblue;
}
.plus1{
border: black solid 3px;
}
.plus2{
border-radius: 10px;
}
.plus3{
color: blue;
}
var vm=new Vue({
el:'#root',
data:{
test1:'class1',
test2:[],
test3:{
plus1:false,
plus2:false,
plus3:false,
}
},
methods:{
change1(){
var classArr=['class1','class2','class3','class4'];
var index=Math.floor(Math.random()*4);
console.log(index);
this.test1=classArr[index];
},
change2(){
var classArr=['plus1','plus2','plus3'];
if(this.test2.length<3){
this.test2.push(classArr[this.test2.length]);
}else{
for(var i=0;i<3;++i){
this.test2.pop();
}
}
},
change3(){
var a,b,c;
a=Math.floor(Math.random()*2);
b=Math.floor(Math.random()*2);
c=Math.floor(Math.random()*2);
if(a)this.test3.plus1=!this.test3.plus1;
if(b)this.test3.plus2=!this.test3.plus2;
if(c)this.test3.plus3=!this.test3.plus3;
}
}
})
<div id="root">
<!-- 对象写法 -->
<div class="basic" :style="styleObj">test1</div>
<!-- 数组方法 -->
<div class="basic" :style="styleArr">test2</div>
</div>
.basic{
width: 100px;
height: 100px;
background-color: skyblue;
border-radius: ;
}
var vm=new Vue({
el:'#root',
data:{
styleObj:{
fontSize:'30px',
color:'red',
},
styleArr:[
{
fontSize:'30px',
color:'red'
},
{marginTop:'10px'},
{
border:'black solid 2px',
borderRadius:'10%'
}
]
},
})
<div id="root">
<!-- 遍历数组 -->
<h1>学生列表</h1>
<ul>
<li v-for="(item,index) in students" :key="index">
{{item.id}}:{{item.name}}-{{item.age}}
</li>
</ul>
<!-- 遍历对象 -->
<h1>学生信息</h1>
<ul>
<li v-for="(value,key) of student" :key="key">
{{key}}:{{value}}
</li>
</ul>
<!-- 遍历字符串 -->
<h1>hello</h1>
<ul>
<li v-for="(char,index) of str" :key="index">
{{index}}:{{char}}
</li>
</ul>
<!-- 遍历指定次数 -->
<h1>12345</h1>
<ul>
<li v-for="(v,index) in 5" :key="index">
{{index}}:{{v}}
</li>
</ul>
</div>
var vm=new Vue({
el:'#root',
data:{
students:[
{id:0,name:'张三',age:18},
{id:1,name:'李四',age:20},
{id:2,name:'王五',age:18},
{id:3,name:'赵六',age:19},
],
student:{
id:0,
name:'张三',
age:18
},
str:'hello'
},
})
面试题:react、vue中key有什么作用?(key的原理是什么?)
要点:就是为了提高效率
<div id="app">
<input type="text" v-model:value="massage"> <!-- 简写如下 -->
<input type="text" v-model="massage"> <!-- 文本框内容与massage双向绑定(输入值改变,massage值会相应改变) -->
<h1>{{massage}}</h1>
</div>
var app=new Vue({
el:'#app',
data:{
massage:'你好!'
}
})
如果是文本框,则v-model绑定的是value值,用户输入的就是value
如果是单选框,责v-model绑定的是value值,必须要给标签配置value
如果是多选框,则:
v-model修饰符
实例
<div id="root">
<form @submit.prevent="output">
<!-- v-model.trim 会自动去掉字符串前后空格 -->
用户名: <input type="text" v-model.trim="userinf.username"> <br><br>
密码: <input type="password" v-model="userinf.password" autocomplete="on"> <br><br>
<!-- type="number" 可以限制用户输入只能是数字 -->
<!-- v-model.number 可以自动将输入的内容转化为数值类型 -->
年龄: <input type="number" v-model.number="userinf.age"> <br><br>
性别:
男<input type="radio" name="gender" value="男" v-model="userinf.gender">
女<input type="radio" name="gender" value="女" v-model="userinf.gender"> <br><br>
班级:
<select v-model="userinf.class">
<option value="">请选择班级</option>
<option value="一班">一班</option>
<option value="二班">二班</option>
<option value="三班">三班</option>
</select> <br><br>
爱好:
学习<input type="checkbox" value="学习" v-model="userinf.hobby">
打游戏<input type="checkbox" value="打游戏" v-model="userinf.hobby">
开车<input type="checkbox" value="开车" v-model="userinf.hobby"> <br><br>
<!-- v-model.lazy 失去焦点才会收集更新信息 -->
其他信息:<textarea v-model.lazy="userinf.other"></textarea> <br><br>
<input type="checkbox" v-model="userinf.agree">是否同意<a href="#">用户协议</a> <br><br>
<button>提交</button>
</form>
</div>
var vm = new Vue({
el: '#root',
data: {
userinf:{
username:'',
password:'',
age:'',
class:'',
hobby:[],
other:'',
agree:''
}
},
methods: {
output(){
console.log(JSON.stringify(this.userinf));
}
},
})
<!DOCTYPE html>
<html lang="ch">
<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>
<style>
[v-clock]{
display: none;
}
</style>
</head>
<body>
<!-- 整个页面核心结构 -->
<div id="root">
<h1 v-cloak>{{name}}</h1>
</div>
</body>
<!-- 如果网络卡顿,Vue.js无法在打开页面时立即加载 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#root',
data: {
name:'Vue'
},
})
</script>
</html>
<div id="root">
<h1 v-once>初始n: {{n}}</h1>
<h1 >n: {{n}}</h1>
<button @click="n++">n+1</button>
</div>
var vm = new Vue({
el: '#root',
data: {
n:1
},
})
<div id="root">
<h1>欢迎访问该系统!!!!!</h1>
<h1 >n: {{n}}</h1>
<button @click="n++">n+1</button>
</div>
var vm = new Vue({
el: '#root',
data: {
n:1
},
})
计算属性:根据原有的属性经过加工处理计算出来的属性叫做计算属性(computed)
<div id="root">
性:<input type="text" v-model="firstname"> <br><br>
名:<input type="text" v-model="lastname"> <br><br>
性名: <span>{{name}}</span>
</div>
var vm=new Vue({
el:'#root',
data:{
firstname:'张',
lastname:'三'
},
computed:{
//这里得写成一个对象,但是Vue会把它解析处理为vm中的属性
name:{
//getter,setter中的this都已经被Vue预先处理为了vm,方便使用
get(){
return this.firstname+'-'+this.lastname;
},
set(value){
var values=value.split('-');
this.firstname=values[0];
this.lastname=values[1];
}
}
//当只需要读取,不需要修改时,可以简写为
// name(){
// return this.firstname+'-'+this.lastname;
// }
}
})
<div id="root">
<h1>你真是个大{{description}}</h1>
<button @click='change'>点我</button>
</div>
var vm=new Vue({
el:'#root',
data:{
isCool:true
},
methods:{
change(){
this.isCool=!this.isCool;
}
},
computed:{
description(){
return this.isCool? '帅哥':'聪明';
}
},
watch:{
isCool:{
immediate:true, //初始化时让handler调用一次
// 当被侦听(监视)的值变化时,handler被调用
handler(newvalue,oldvalue){
console.log('isCool被改变了,从'+oldvalue+'改成了'+newvalue);
}
},
//当侦听(监视)时配置项只有handler时,可以简写为
// isColl(){
// console.log('isCool被改变了,从'+oldvalue+'改成了'+newvalue);
// }
}
})
// 另一种写法
// vm.$watch('isCool',{
// immediate:true, //初始化时让handler调用一次
// // 当被侦听(监视)的值变化时,handler被调用
// handler(newvalue,oldvalue){
// console.log('isCool被改变了,从'+oldvalue+'改成了'+newvalue);
// }
// })
//当侦听(监视)时配置项只有handler时,可以简写为
// vm.$watch('isCool',function(){
// console.log('isCool被改变了,从'+oldvalue+'改成了'+newvalue);
// })
deep:true
可以侦听(监视)对象内部属性值的改变(多层)侦听(监视):包括Vue对于数据改变,动态更新页面中用到该数据的DOM,以及watch中侦听(监视)数据地秤实现(同样的逻辑)
Vue会侦听(监视)data中所有层级的数据
如何侦听(监视)对象中的数据?
通过setter实现侦听(监视),而且要是在创建Vue实例对象时就传入的数据才会被Vue侦听(监视)
对象中后追加的属性,Vue默认不侦听(监视),进而也不会做出响应式处理
如果想让后追加的属性也可以被Vue侦听(监视),并响应式处理,需要使用:
Vue.set()
vm.$set()
如何侦听(监视)数组中的数据?
通过包裹数组更新元素方法实现,本质上就是两个处理
在Vue中修改某数组中某元素一定要用如下几种方法:
//这些方法用起来和原生JS中Array对象的这些方法一样,但是实际上底层逻辑不一样,Vue对这些方法做了如上述的包裹处理
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
//Vue的set方法
//注意!! 这两个方法用起来一样,但是都有局限,
//不能为vm或者vm的根数据对象(即 data等)添加属性!!!
Vue.set()
vm.$set()
实例
<div id="root">
<button @click="student.age++">年龄加一岁</button> <br>
<button @click.once="addgender">添加性别属性,默认男</button> <br>
<button @click.once="addaf">在朋友们最前面加一个朋友</button> <br>
<button @click.once="updateff">修改第一个朋友的名字</button> <br>
<button @click.once="addh">添加一个爱好</button> <br>
<button @click.once="updatafh">修改第一个爱好</button> <br>
<h1>姓名 {{student.name}}</h1>
<h2>绰号 {{student.nickname}}</h2>
<h3>年龄 {{student.age}}</h3>
<h3 v-if="student.gender">性别 {{student.gender}}</h3>
<h3>朋友们</h3>
<ul>
<li v-for="(f,index) in student.friends" :key="index">
{{f.name}}--{{f.age}}
</li>
</ul>
<h3>爱好</h3>
<ul>
<li v-for="(h,index) in student.hobby" :key="index">
{{h}}
</li>
</ul>
</div>
var vm = new Vue({
el: '#root',
data: {
student: {
name: '张三',
nickname: '法外狂徒',
age: 20,
friends: [
{ name: '罗老师', age: 18 },
{ name: '李四', age: 22 },
],
hobby: ['抽烟', '赌博', '干坏事']
}
},
methods: {
addgender() {
// 第一种
// Vue.set(this.student,'gender','男');
// 第二种
this.$set(this.student, 'gender', '男');
},
addaf() {
this.student.friends.unshift({ name: '王五', age: 40 });
},
updateff() {
this.student.friends[0].name = '王大炮'
},
addh() {
this.student.hobby.push('开车');
},
updatafh() {
// 第一种
// this.student.hobby.splice(0,1,'学习');
// 第二种
// Vue.set(this.student.hobby, 0, '学习');
// 第三种
this.$set(this.student.hobby, 0, '学习');
}
}
})
过滤器:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑处理)
定义语法:
局部指令
new Vue({
directives:{
指令名:配置对象
//配置对象
bind() //指令与元素成功绑定的时候调用
inserted() //指令所在元素被插入页面时调用
update() //指令所在模板被重新解析时调用
} //对象形式
//简写
directives:{
指令名(){} //写成一个函数
//这个函数相对于定义了上述配置项的bind()和update()
}
})
全局指令
Vue.directive(指令名,配置对象)
Vue.directive(指令名,配置函数)
备注
常用的生命周期钩子:
销毁Vue实例:
模块:向外提供特定功能的JS文件
组件:用来实现局部(特定)功能效果的代码及依赖数据集合(html/css/js/img/mp3…)
定义组件
注册组件
使用组件
实例
<div id="root">
<h1>root</h1>
<heade></heade>
<hr>
<bodyer></bodyer>
<foote></foote>
</div>
<div id="root1">
<h1>root1</h1>
<foote></foote>
</div>
// 定义组件header
var heade=Vue.extend({
template:`
<div>
<h1>欢迎访问{{name}}系统!</h1>
</div>
`,
data(){
return {
name:'智慧张三'
}
}
})
// 定义组件bodyer
var bodyer=Vue.extend({
template:`
<div>
<h1>{{name}}列表</h1>
<ul>
<li v-for="(s,index) in students">
{{s.name}}---{{s.age}}
</li>
</ul>
</div>
`,
data(){
return {
name:'学生',
students:[
{name:'张三',age:18},
{name:'罗老师',age:30},
]
}
}
})
var foote=Vue.extend({
template:`
<div>
<h2>版本号{{num}}!</h2>
</div>
`,
data(){
return {
num:'v1.0.1'
}
}
})
// 注册组件(全局)
Vue.component('foote',foote)
var vm = new Vue({
el: '#root',
data: {
},
// 注册组件(局部)
components:{
heade,
bodyer
}
})
new Vue({
el: '#root1',
})
组件命名
组件标签
<bodyer></bodyer>
<bodyer/>
(需要Vue脚手架支持,否则其后的组件不能被渲染)定义简写
var heade=Vue.extend(options)
//简写
var heade=options;
new VueComponent(options);
VueComponent.prototype.__proto__ === Vue.prototype
npm install -g @vue/cli
全局安装@vue/cli (只需要安装一次)vue create xxxx
npm run serve
如果出现下载缓慢,请配置npm淘宝镜像: npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https: //npm.taobao.org/dist --global
Vue脚手架隐藏了所有的webpack相关的配置,如想要查看具体的wekpack配置,请执行: vue inspect > output.js
//单文件组件示例
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
import School from './components/Test1.vue';
import Student from './components/Test2.vue';
export default {
name:'App',
components:{
School,
Student
}
}
</script>
<style>
</style>
用来给元素或者子组件注册引用信息(相当于id)
应用在html标签上获取真实的DOM元素,应用在组件标签上是组件的实例对象(vc)
使用方式
<template>
<div>
<h1 ref="h1">你好</h1>
<School ref="sch"></School>
<button ref="but" @click="console">输出refs</button>
<Student></Student>
</div>
</template>
<script>
import School from './components/Test1.vue';
import Student from './components/Test2.vue';
export default {
name:'App',
components:{
School,
Student
},
methods: {
console(){
console.log(this.$refs);
}
},
}
</script>
功能:让组件接收外部传过来的数据
备注:props是只读的,Vue底层会监视你对props的修改,如果进行了修改,就会发出警告
export default {
name:'Student',
data(){
return {
mas:'你好,我是:'
}
},
// 第一种方式:(只是简单接收)
// props:['name','gender','age'],
// 第二种方式:(限制数据类型)
// props:{
// name:String,
// gender:String,
// age:Number
// }
// 第三种方式:(详细配置)
props:{
name:{
type:String, //类型
required:true //必要性
},
gender:{
type:String,
default:'男' //默认值
},
age:{
type:Number,
required:true
}
}
}
功能:把某些组件共用的配置提取出来,成为一个混合对象
使用方式
//定义并暴露混合
export const mixin={
data(){
return {
message:'你好啊!!'
}
},
methods: {
nihao(){
alert("Hello!");
}
},
mounted(){
console.log("挂载了组件");
},
}
//使用混合
//局部使用
import {mixin} from './mixin';
mixins:[mixin]
//全局使用(在main.js中引入注册混合)
import {mixin} from './mixin';
Vue.mixin(mixin);
功能:增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用所需要的数据
//定义插件
export default {
install(Vue){
Vue.prototype.test=()=>{
alert('你好!');
}
}
}
//引入及使用(在main.js中)
import plugin from './plugins';
Vue.use(plugin);
作用:让样式只在局部(当前组件生效)其他地方不生效,这样来避免组件间样式冲突
<style scopes></style>
setItem('key','value');
该方法接收一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则直接更新对应的值getItem('key');
该方法根据键获取存储中的值,如果没有,返回nullremoveItem('key');
该方法根据键删除存储中的相应的键值对clear();
清空存储的信息一种组件间通信方式,子组件===>父组件
绑定与触发事件
//父组件中
<!-- 为子组件绑定自定义事件,实现子给父传递数据(v-on/@)-->
<School @test="getName"></School> <!-- 普通事件绑定的修饰符仍然可用,如once等 -->
<!-- 为子组件绑定自定义事件,实现子给父传递数据(ref 更加灵活) -->
<School ref="school"></School>
//父组件中
methods: {
getName(name){
console.log(name+'拿到了');
}
},
mounted(){
setTimeout(()=>{
this.$refs.school.$on('test',this.getName); //使用$once方法,事件只触发一次
//注意:通过该方法绑定事件时,回调建议配置在methods中或者使用箭头函数,否则回调中(this.getName中)的this指向的是触发事件的子组件
},3000)
}
//子组件中触发事件
this.$emit('test',this.name);
解除事件绑定
//在子组件中
this.$off('test'); //解除事件test绑定
this.$off(['test1','test2']); //解除事件test1,test2的绑定
this.$off(); //解除所有事件绑定
组件绑定原生DOM事件,需要使用native修饰符
一种组件间通信的方式,任意组件间通信(基于组件自定义事件)
安装全局事件总线:(实际上就是造一个中转的组件实例对象,该VC可以被所有其他组件访问到)
//在main.js的root组件中
beforeCreate(){
Vue.prototype.$bus=this //$bus就是当前应用的vm,也就作为上述要造的vc
}
使用事件总线
接收数据的组件:给$bus绑定自定义事件,事件的回调在自身
methods:{
test(data){} //回调函数
}
mounted(){
this.$bus.$on('事件名',this.test); //绑定事件
}
发送数据的组件
this.$bus.$emit('事件名',data); //触发事件
最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。
一种组件间的通信方式,适用于任意组件间通信。
使用
安装第三方库:(这里用的是pubsub-js,也可以用其他的)npm i pubsub-js
引入:import pubsub from 'pubsub-js'
接收数据的组件中订阅消息,在自身编写回调函数
methods(){
test(data){}
}
mounted(){
this.pubid=pubsub.subscribe('消息名',this.test); //订阅消息
}
提供数据的组件发送消息
pubsub.publish('消息名',data);
最好在beforeDestroy钩子中,用pubsub.unsubscribe(this.pubid)去取消消息订阅
this.$nextTick(回调函数)
在插入、更新或者移除DOM元素时,会在合适的时候给元素添加样式类名
v-enter == v-enter-active ==> v-enter-to v-leave == v-leave-active ==> v-leave-to
使用方法
准备好样式:
使用<transition>
包裹要过度的元素,并配置name属性:
<transition name="test"> <!-- 指定了name属性,需要将类名对应为相应的(例如test-enter) -->
<h1 v-show="isShow">你好啊!</h1>
</transition>
备注:如果有多个元素需要动画效果,则需要使用:transition-group
,且每个元素都要指定key
值
实例一:
<button @click="change">显示/隐藏</button>
<transition name="test" appear>
<div v-show="isShow" class="a">
<h1>{{mes}}</h1>
</div>
</transition>
<button @click="change">显示/隐藏</button>
.test-enter-active{
animation: test 1s;
}
.test-leave-active{
animation: test 1s reverse;
}
@keyframes test{
from{
transform: translateX(-100%);
}
to{
transform: translateX(0);
}
}
实例二:
<transition name="test1" appear>
<div v-show="isShow" class="a">
<h1>{{mes}}</h1>
</div>
</transition>
<button @click="change">显示/隐藏</button>
.test1-enter, .test1-leave-to{
transform: translateX(-100%);
}
.test1-leave, .test1-enter-to{
transform: translateX(0);
}
.test1-leave-active, .test1-enter-active{
transition: 1s linear;
}
实例三:
<button @click="change">显示/隐藏</button>
<transition-group name="test2" appear>
<div v-show="isShow" class="a" key="1">
<h1>{{mes}}</h1>
</div>
<div v-show="!isShow" class="a" key="2">
<h1>{{mes}}</h1>
</div>
</transition-group>
.test2-enter, .test2-leave-to{
transform: translateX(-100%);
}
.test2-leave, .test2-enter-to{
transform: translateX(0);
}
.test2-leave-active, .test2-enter-active{
transition: 1s linear;
}
动画库推荐:animate.css
npm i animate.css
import 'animate.css';
<button @click="change">显示/隐藏</button>
<transition
appear
name="animate__animated animate__bounce"
enter-active-class="animate__rubberBand"
leave-active-class="animate__backOutDown"
>
<div v-show="isShow" class="a">
<h1>{{mes}}</h1>
</div>
</transition>
```javascript
import 'animate.css';
//记得配置这个methods
change(){
this.isShow=!this.isShow;
}
作用:让父组件可以向子组件中指定位置插入HTML结构,也是一种组件间通信方式 父组件===>子组件
使用
默认插槽
//父组件
<template>
<List title="汽车">
<img src="" alt="">
</List>
<List title="食物">
<ul>
<li v-for="(f,i) in foods" :key="i">{{f}}</li>
</ul>
</List>
<List title="游戏">
<!-- <ul>
<li v-for="(g,i) in games" :key="i">{{g}}</li>
</ul> -->
</List>
</template>
<script>
import List from "./components/Test1.vue";
export default {
name: "App",
components: { List },
data() {
return {
foods: ["海底捞", "烧烤"],
cars: ["劳斯莱斯", "兰博基尼"],
games: ["推箱子", "连连看"],
};
},
};
</script>
<style>
.lists,
.a {
display: flex;
justify-content: space-around;
}
img {
width: 100%;
}
</style>
//子组件
<template>
<div class="list">
<h1>{{title}} 列表</h1>
<slot>没有内容了。。。</slot>
</div>
</template>
具名插槽
//父组件
<template>
<div class="lists">
<List title="汽车">
<a slot="test" href="#">更多</a>
</List>
<List title="食物">
<div slot="test" class="a">
<a href="#">中餐</a>
<a href="#">西餐</a>
</div>
</List>
<List title="游戏">
<!-- 在用template标签时可以这样用,也可以slot="test" -->
<template v-slot:test>
<div class="a">
<a href="#">单机</a>
<a href="#">联机</a>
</div>
<h2>快来游玩吧!</h2>
</template>
</List>
</div>
</template>
//子组件
<template>
<div class="list">
<h1>{{title}} 列表</h1>
<slot name="test">没有内容了111。。。</slot>
</div>
</template>
作用域插槽
//父组件
<template>
<div class="lists">
<List title="手机">
<template slot="test2" scope="{phones}">
<ul>
<li v-for="(p,i) in phones" :key="i">{{p}}</li>
</ul>
</template>
</List>
<List title="手机">
<!-- vue2.6后新的写法 -->
<template v-slot:test2="{phones}">
<ol>
<li v-for="(p,i) in phones" :key="i">{{p}}</li>
</ol>
</template>
</List>
</div>
</template>
//子组件
<template>
<div class="list">
<h1>{{title}} 列表</h1>
<slot name="test2" :phones="phones">没有内容222</slot>
</div>
</template>
<script>
export default {
name:'List',
data(){
return {
phones:['小米','华为']
}
},
props:['title']
}
</script>
<style scoped>
.list{
background-color: skyblue;
width: 200px;
height: 300px;
}
h1{
text-align: center;
}
li{
background-color: orange;
font-size: 18px;
margin-bottom: 8px;
}
</style>
安装 :npm npm上axios地址,网上找都行,到处都是
<div id="app">
<button @click="get">get</button>
<br>
<button @click="post">post</button>
</div>
var app=new Vue({
el:'#app',
methods:{
get:function(){
axios.get("http://127.0.0.1:3000/get?num=4") //自己写的测试接口,下同
.then(
function(res){
console.log(res);
},function(err){
console.log(err);
}
)
},
post:function(){
axios.post("http://127.0.0.1:3000/post",{num:5})
.then(
function(res){
console.log(res);
},function(err){
console.log(err);
}
)
}
}
})
方法一
// 开启代理服务器(方式一)
devServer: {
proxy: 'http://localhost:5000'
},
students(){
axios.get("http://localhost:8081/students").then(
(res)=>{
console.log(res.data);
},
(err)=>{
console.log(err.massage);
}
)
}
方法二
// 开启代理服务器(方式二)
devServer: {
proxy: {
'/s': { //当请求前缀为/s时代理服务器转发请求到target
target: 'http://localhost:5000',
pathRewrite:{'^/s':''}, //代理服务器转发请求时,将前缀/s去掉
ws: true, //用于支持websocket
changeOrigin: true //用于控制请求头中的Host值(true: localhost:5000 false :localhost:8081)
},
'/c': { //当请求前缀为/s时代理服务器转发请求到target
target: 'http://localhost:5001',
pathRewrite:{'^/c':''}, //代理服务器转发请求时,将前缀/s去掉
ws: true, //用于支持websocket
changeOrigin: true //用于控制请求头中的Host值(true: localhost:5000 false :localhost:8081)
}
}
}
students(){
axios.get("http://localhost:8081/s/students").then(
(res)=>{
console.log(res.data);
},
(err)=>{
console.log(err.massage);
}
)
},
cars(){
axios.get("http://localhost:8081/c/cars").then(
(res)=>{
console.log(res.data);
},
(err)=>{
console.log(err.massage);
}
)
}
npm i vue-resource
import vueResource from 'vue-resource'
Vue.use(vueResource);
this.$http.get(...)
概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读写),也是组件间通信方式之一,适用于任意组件间通信
Github地址:vuex
原理:
安装:npm i vuex
创建文件:src/store/index.js
// 引入Vue
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用Vuex插件
Vue.use(Vuex);
// 创建并暴露store
export default new Vuex.Store({
actions:{},
mutations:{},
state:{}
})
在main.js中配置store
// 引入store
import store from './store'
import App from './App.vue'
Vue.config.productionTip = false
Vue.use(vuex);
new Vue({
render: h => h(App),
store
}).$mount('#app')
初始化数据state、配置actions,mutations
actions:{
//响应组件中的动作
fun(context,value){
//context:上下文,相当于一个minstore,在里面有所有这里可能需要用到的数据和方法
//context.dispatch('action中的方法名',value) 可以对数据做多步中间处理
//context.state.test可以直接访问到state中的数据,这里不要直接去修改数据,可以读取数据做条件判断等,
//如果直接修改数据,vue开发者工具无法捕捉到
//context.commit('mutations中的方法名',data) 提交操作
}
//业务逻辑全部写在这里
},
mutations:{
//执行操作
//这里的方法名约定全大写,方便与actions中的方法进行区分
FUN(state,value){
//state 就是state,这里就对数据进行基本操作(不关心业务逻辑,只关心基本增删改查操作)
}
},
state:{
//数据
test:0
}
组件中读取数据,发起操作
//读取数据
$store.state.test
//发起操作
$store.dispatch('action中的方法名',data)
//如果不需要action做中间处理,则直接提交操作
$store.commit('mutations中的方法名',data)
概念:当state中的数据需要经过加工后再共享使用的时候,可以用getters加工
用法:
getters:{
bigTest(state){
return state.test*10;
}
}
//用法形如组件中的computed计算属性,但是getters可以在组件间复用
引入import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
用于帮助我们映射state中的数据为computed计算属性
computed:{
//对象写法
...mapState({a:'test1',b:'test2',c:'test3'})
//数组写法(不能重新命名,生成的计算属性名与state对象中的属性名一致,传递的参数也得与state对象中的属性名一致)
...mapState(['test1','test2','test3'])
}
用于帮助我们映射getters中的数据为computed计算属性
computed:{
//对象写法
...mapGetters({a:'test1',b:'test2',c:'test3'})
//数组写法(不能重新命名,生成的计算属性名与Getters对象中的属性名一致,传递的参数也得与Getters对象中的属性名一致)
...mapGetters(['test1','test2','test3'])
}
用于帮助我们生成与actions对话的方法
methods:{
//对象写法
...mapActions({a:'test1',b:'test2',c:'test3'})
//生成的函数
//a(value){
// $store.dispatch('test1',value);
//}
//数组写法(不能重新命名,生成的函数名与actions对象中的方法名一致,传递的参数也得与actions对象中的方法名一致)
...mapActions(['test1','test2','test3'])
}
用于帮助我们生成与mutations对话的方法
methods:{
//对象写法
...mapMutations({a:'TEST1',b:'TEST2'})
//生成的函数
//a(value){
// $store.commit('TEST1',value);
//}
//数组写法(不能重新命名,生成的函数名与mutations对象中的方法名一致,传递的参数也得与mutations对象中的方法名一致)
...mapMutations(['TEST1','TEST2'])
}
目的:让代码更好的维护,让多种数据分类更加明确
使用方法
创建并暴露模块
//在model1.js中
export default model1={
//开启命名空间
namespaced:true,
state:{},
actions:{},
mutations:{},
getters:{}
}
//在model2.js中
export default model2={
//开启命名空间
namespaced:true,
state:{},
actions:{},
mutations:{},
getters:{}
}
在store模块中引入并使用其他模块
//在index.js中
// 引入Vue
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
//引入其他模块
import model1 from './model1'
import model2 from './model2'
// 应用Vuex插件
Vue.use(Vuex);
// 创建并暴露store
export default new Vuex.Store({
modules:{
model1,
model2
}
})
读取state中数据的方法(在读取时要以某一种形式指明数据所在的模块)
//直接读取
this.$store.state.model1.test1
//借助mapState读取
...mapState('model1',['test1','test2'])
读取getters中数据的方法
//直接读取
this.$store.getters['model2/test1']
//借助mapGetters
...mapGetters('model2',['test1','test2'])
调用dispatch与Actions对话的方法
//直接对话
this.$store.dispatch('model1/test1',data)
//借助mapActions
...mapActions('model1',['test1','test2'])
调用commit与Mutations对话的方法
//直接对话
this.$store.commit('model2/test1',data)
//借助mapMutations
...mapMutations('model2',['TEST1','TEST2'])
vue-router是vue的一个插件库,专门用来实现SPA(单页面)应用
安装vue-router npm i vue-router
引入 import VueRouter from 'vue-router'
应用插件 Vue.use(VueRouter);
创建并暴露一个router
//在src/router/index.js下
//引入vue-router
import VueRouter from 'vue-router'
//引入相关组件
import Component1 from '../component/Component1'
import Component2 from '../component/Component2'
//创建并暴露router
export default router= new VueRouter({
routes:[
{
path:'/component1',
component:Component1
},
{
path:'/component2',
component:Component2
}
]
})
实现切换
<router-link active-class="active" to="/component1">Component1</router-link>
<!-- active-class指定被选中时的样式,to指定跳转路径 -->
<!-- router-link 最终呈现出来是一个a标签 -->
指定显示位置
<router-view></router-view>
注意!
配置路由规则,在一级路由里使用children进行配置
export default router= new VueRouter({
routes:[
{
path:'/component1',
component:Component1,
//配置子级路由,可以无限套娃
children:[
{
path:'child1', //children中的路径不需要写/
component:Child1
},
{
path:'child2',
component:Child2
}
]
}
]
})
跳转(to中的路径需要写完整)
<router-link to="/component1/child1">Child1</router-link>
传递参数
<!-- 字符串写法 -->
<router-link :to="`/component1/child1/test1?a=${data.a}&b=${data.b}`">Test1</router-link>
<!-- 对象写法 -->
<router-link
:to="{
path:'/component1/child1/test1',
query:{
a:data.a,
b:data.b
}
}"
>Test1</router-link>
接收参数
this.$route.query.a
使用
export default router= new VueRouter({
routes:[
...
{
name:'c1', //配置名字
path:'xxxx',
component:xxxxx
},
]
})
简化跳转
<!-- 主要是在子级路由跳转时,即路径较长,或者需要传递参数,使用对象写法 -->
<router-link
:to="{
name:'c1',
query:{
...
}
}"
>Test1</router-link>
在配置中声明params参数
name:'c1'
path:'xxxx/:a/:b' //使用占位符声明params参数
传递参数
<!-- 字符串写法 -->
<router-link :to="`/xxxx/${data.a}/${data.b}`">Test1</router-link>
<!-- 对象写法 -->
<router-link
:to="{
name:'c1', //这里必须用name,不能用path!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
query:{
a:data.a,
b:data.b
}
}"
>Test1</router-link>
读取参数
this.$route.params.a
作用,让路由组件更方便接收到参数
{
...
//第一种写法:props值为对象,该对象中所有的key-value的组合最终会通过props传给对应组件
//props:{a:100,b:'hello'}
//这种写法不能动态赋值
//第二种写法:props值为true,路由收到的所有**params**参数通过props传给对应组件
//props:true
//这种方法有局限性,只能处理params参数
//第三种写法:props值为函数,函数返回一个对象,函数的第一个参数是$route,对象中所有的key-value的组合最终会通过props传给对应组件
props($route){
return {
a:$router.query.xxx
b:$router.params.xxx
}
}
}
<router-link>
的replace属性push
和replace
,push是追加记录(压栈),replace是替换,默认是push<router-link replace>.....</router-link>
作用:不需要再借助<router-link>
,路由跳转更加灵活
具体方法
//$router的两个API
this.$router.push({ //push模式跳转
name:'xxx',
query:{
...
}
})
//配置与to的对象写法一样
this.$router.replace({ //replace模式跳转
name:'xxx',
params:{
...
}
})
//历史记录操作方法,$router的三个API
this.$router.back() //后退一步
this.$router.forward() //前进一步
this.$router.go() //传递参数,正数前进,负数后退具体的步数
作用:让不展示的路由组件保持挂载,不被销毁
使用
<keep-alive include="xxx">
<router-view></router-view>
</keep-alive>
<!--
keep-alive标签中的内容将会被缓存
include是一个配置项,里面值为**组件名**,其中包含的组件才会被缓存,如果不配置include,则keep-alive中的组件都会被缓存
include中需要包含多个组件时 :include="['xxx1','xxx2']"
-->
activated
路由组件被激活时触发deactivated
路由组件失活时触发//在暴露router之前,使用router相应API设置
//全局前置守卫:初始化时执行、每次路由切换前执行(控制访问权限等)
router.beforeEach((to,from,next)=>{
//to是即将跳转的路由的相关信息
//from是跳转前的路由相关信息
//next是一个函数,调用该函数即跳转路由
})
//全局后置守卫:初始化时执行、每次路由切换后执行(控制页签名称document.title变化等)
router.afterEach((to,from)=>{
//to是即将跳转的路由的相关信息
//from是跳转前的路由相关信息
})
//补充:路由配置中提供程序员存放其他信息(标识信息等)的配置项meta
//配置在路由配置中
routes:[
...
{
...
beforeEnter(to,from,next){
...
//这里的三个参数与全局前置守卫一致
}
}
]
组件独享的守卫
//在组件配置中
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter(to,from,next){}
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave(to,from,next){}
//这里的三个参数与全局前置守卫一致
connect-history-api-fallback
npm上的connect-history-api-fallback
npm i connect-history-api-fallback
const history = require('connect-history-api-fallback');
app.use(history());
(注意要在配置静态资源前使用)以上是脚本宝典为你收集整理的Vue2学习笔记全部内容,希望文章能够帮你解决Vue2学习笔记所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。