Vue
(2.6版本)
- 渐进式框架(主张最少)
- 安装
- 官网:https://cn.vuejs.org/
- 开发版:
Vue组件特点
- 组件式开发【组件相当于零件,页面功能由多个零件开发】
- SPA单页面应用程序
- 渐进式开发【主张最少】(用多少功能就安装多少模块,所以很轻量化)
- 声明式编码,让编码人员无序操作DOM,提高开发效率
Vue的缺点
- 不利于SEO【页面上的所有内容都是通过JS动态渲染的,页面查看源代码看不到HTML代码】
如何解决Vue不利于SEO的问题
SSR【服务端渲染】:在服务端提前生成好要展示的HTML结构,首次加载页面的时候就展示出来。
声明式渲染
<body>
// 1.创建一个Vue实例挂载的容器
<div id='app'>
{{name}}-{{age}}
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
// 2. 创建Vue实例对象
let vm = new Vue({
el:'#app', // 实例要挂载到哪里
data:{ // 要挂载的多种数据
name:'frank',
age:20,
sex:'男'
}
})
</script>
在浏览器修改:vm.name = '王五'
属性绑定
bind:绑定
<body>
<!-- 创建一个Vue实例的挂载容器 -->
<div id="my_vue">
<!-- v-dind: 使元素的属性值为js后端传递来的-->
<a href="#" v-bind:title="value">lalala</a>
<!-- v-dind:简写形式--直接在属性名称前加冒号 -->
<img src="#" :alt="value" />
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
el: "#my_vue",
data: {
value: "欢迎你",
},
});
</script>
条件渲染
v-if与v-show不同之处?
- v-show是通过display属性去切换效果的,v-if是通过删除和创建标签实现的
- 初始加载时,如果同样是false,v-if根本不创建标签,v-show仍然要创建标签,然后再把它隐藏
- 场景:频繁切换用v-show,否则用v-if
v-if指令:如果为true则当前元素显示
<body>
<!-- 创建一个Vue实例的挂载容器 -->
<div id="my_vue">
<!-- v-if指令:如果isShow为true则显示,否则不显示 -->
<h1 v-if="isShow">111</h1>
<h1 v-if="!isShow">222</h1>
<!-- v-else指令:不能独立显示,与上一个同级v-if指令对应 -->
<h1 v-else>333</h1>
<!-- 复杂的if-else结构 -->
<h1 v-if='leval=="A"'>优</h1>
<h1 v-else-if='leval=="B"'>良</h1>
<h1 v-else>差</h1>
<!-- v-show指令:效果与v-if效果相同,只是实现效果的方式不同 -->
<h1 v-show="isShow">777</h1>
<h1 v-show="!isShow">888</h1>
</div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#my_vue",
data: {
isShow: true, // 111,333,777显示
leval: "A", // 优
},
});
</script>
事件触发
<body>
<div id="add">
<div v-show="isShow">{{name}}</div>
<!-- v-on指令:事件触发 -->
<button v-on:click="isShow=!isShow">切换</button><br />
<!-- v-on简写形式 -->
<button @click="reverseTitle()">翻转</button>
</div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#add",
data: {
name: "我叫张三",
isShow: true,
},
methods: {
reverseTitle(title, isShow) {
// 在函数中获取数据(title,isShow)
// this指向Vue的实例对象vm
this.name = this.name.split("").reverse().join("");
},
},
});
</script>
Vue实例对象
- Vue实例代理了data属性下的所有子属性,用起来更方便(vm.data.XXX == vm.XXX)
Watch监听
<body>
<div id='app'>
<h1>
{{count}}
</h1>
<button @click='add'>
点击Count + 1
</button>
</div>
</body>
<script>
new Vue({
el:'#app',
data:{
count:1
},
methods:{
add(){
this.count++
}
}
watch:{
// 监听count,watch的函数名就叫count
count(new,old){
console.log(new);
console.log(old);
}
}
})
</script>
v-model(双向数据绑定)
一般和表单一起使用
v-model是v-model:value的简写形式
v-model只能用于表单标签
<body>
<div id="app">
<h1>{{name}}*{{num}}</h1>
<button @click="gogo">+++</button><br />
<input type="text" v-model="role" />
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
name: "斩尽牛杂",
num: 1,
role: "刻晴",
},
methods: {
gogo() {
this.num++;
},
},
watch: {
// 浅监听,只能监听一层数据,如果对象内部的属性发生变化,他是无法监听的
num(newValue, oldValue) {
console.log(newValue);
console.log(oldValue);
},
// 深监听,可以监听对象内部的属性变化
role: {
deep: true,
handler(newValue) {
console.log(newValue);
},
},
},
});
</script>
数组响应式
- 数组操作不要用[]形式
- 只能用数组的几种方法啦操作数据:pop(),push(),unshift(),shift(),splice()
<body>
<div id="app">
<h1>{{name}}</h1>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
name: ["张三", "李四", "王五"],
},
});
// 数组的操作不要使用[]
vm.name[0] = "冯八";
// 只能用数组的几种方法啦操作数据:pop(),push(),unshift(),shift(),splice()
// vm.name.splice(0, 2, "马六", "赵七");
</script>
Set
- 响应式:在JS对数据做的操任何作,页面会即使响应
- 给data里面的对象添加一个响应式的新属性要用$set才可以
<body>
<div id="app">
<h1>{{ys.name}}-{{ys.sex}}-{{ys.age}}</h1>
<button @click="addAge">添加年龄</button>
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
ys: {
name: "刻晴",
sex: "女",
},
},
methods: {
addAge() {
// 只能给data里的对象添加新属性,不能直接给data添加新属性
this.$set(this.ys, "age", 17);
},
},
});
</script>
$mount
- 延时挂载
- el与 m o u n t 挂载相同, e l 最终还是调用 mount挂载相同,el最终还是调用 mount挂载相同,el最终还是调用mount进行挂载的
<body>
<div id="app"><h1>{{name}}</h1></div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
data: {
name: "李四",
},
}).$mount("#app");
v-text / v-html
<body>
<!-- v-html:类似于innerHtml;v-text:类似于innerText -->
<div id="app">
<!-- 李四 -->
<p v-text="name"></p>
<!-- 李四 -->
<p v-html="name"></p>
<!-- <b>王五</b> -->
<p v-text="name1"></p>
<!-- 加粗的'王五'-->
<p v-html="name1"></p>
<!-- 李四 -->
<p>{{name}}</p>
<!-- <b>王五</b> -->
<p>{{name1}}</p>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
data: {
name: "李四",
name1: "<b>王五</b>",
},
}).$mount("#app");
</script>
计算属性
- 意义不同;watch是一系列操作,计算属性目的是做一些简单的计算
- 异步请求:watch可以,计算属性不可以
- 缓存效果:计算属性有,watch没有
<body>
<div id="app">
<p>原名:{{name}}</p>
<p>翻转:{{reversename}}</p>
<p>原数组:{{arr}}</p>
<p>偶数:{{everArr}}</p>
<p>小于3的数:{{x_Arr}}</p>
<button @click="getNum">原数</button>
<button @click="setNum">变化</button>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
data: {
name: "ok gogo",
arr: ["1", "2", "3", "4", "5", "6"],
a: 4,
},
computed: {
// 单纯获取计算属性的值
reversename() {
return this.name.split("").reverse().join("");
},
everArr() {
return this.arr.filter((item) => item % 2 == 0);
},
x_Arr() {
return this.arr.filter((item) => item < 3);
},
// 可以设置计算属性的值,也可以获取
my_Num: {
set(newValue) {
this.a = newValue;
},
get() {
return this.a * 10;
},
},
},
methods: {
getNum() {
// 读取计算属性
console.log(this.my_Num);
},
setNum() {
// 修改计算属性
this.my_Num = 5;
},
},
}).$mount("#app");
</script>
类样式(绑定样式)
<style>
.classA {
background-color: pink;
}
.classB {
font-weight: bold;
}
.classC {
color: blue;
}
.classD {
color: yellowgreen;
}
</style>
</head>
<body>
<div id="app">
<!-- 对象形式 -->
<p :class="name">大家好,才是真的好。</p>
<!-- 数组形式 -->
<p :class="name1">风驰天下,大运摩托。</p>
<button @click="reverse">交换</button>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
data: {
name: {
classA: true,
classB: true,
classC: true,
},
name1: ["classA", "classB", "classD"],
},
methods: {
reverse(){
this.name.classC == this.$set(this.name,'classD',true)
}
},
}).$mount("#app");
</script>
行内样式
<body>
<div id="app">
<p :style="{color:'red'}">啦啦啦</p>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue().$mount("#app");
</script>
列表渲染
mounted:开局自执行
<body>
<div id="app">
<!-- 无序列表 -->
<ul>
<!-- v-dind:key 作用:确定元素唯一性,提高更新虚拟DOM的效率,提高性能 -->
<!-- v-for:遍历数组 -->
<li v-for="(value,index) in name" :key="index">{{index}}-{{value}}</li>
</ul>
<ul>
<li v-for="(value,index) of name" :key="index">{{index}}-{{value}}--</li>
</ul>
<ul>
<li v-for="(value,index) in name1" :key="index">{{index}}-{{value}}</li>
</ul>
<!-- 有序列表 -->
<ol>
<li v-for="i in 10">{{i}}</li>
</ol>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
data: {
name: ["张三", "李四", "王五"],
name1: [],
},
mounted() {
// 模拟ajax
setTimeout(() => {
this.name1 = [1, 2, 3, 4, 5];
}, 1000);
},
}).$mount("#app");
</script>
$refs
<body>
<div id="app">
<input type="text" ref="name" />
<button @click="gogo">提交</button>
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
data: {},
methods: {
gogo() {
console.log(this.$refs.name.value);
},
},
}).$mount("#app");
</script>
常用的几个事件修饰符
- .stop:阻止事件冒泡
- .prevent:组织元素的默认行为
- .self:只对元素事件本身触发有效,对子节点触发无效
- once:只触发一次
- capture:采用事件捕获模式
<body>
<div id="app">
<!-- .stop阻止事件冒泡 -->
<div @click="a1" style="background-color: yellowgreen">
<div @click.stop="a2" style="background-color: pink; width: 100px">
123
</div>
</div>
<!-- .prevent:阻止事件的默认行为 -->
<form action="app.html" @submit.prevent>
<button>提交</button>
</form>
<div @click.self="b1">
<div @click="b2" style="background-color: pink; width: 100px">拉卡打开</div>
</div>
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
el: "#app",
data: {},
methods: {
a1() {
console.log("parent");
},
a2() {
console.log("student");
},
b1() {
console.log('BB');
},
b2() {
console.log('bb');
},
},
});
</script>
vue提供的几个键盘修饰符
.enter 回车键
.esc 退出键
.space 空格键
.up 上
.down 下
.right 右
.left 左
.delete 删除键+退格键
.tab 制表符键
<body>
<div id="app">
<input type="text" @keyup.once.enter="gogo" />
<input type="text" @keydown.enter="gogo" />
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
el: "#app",
data: {},
methods: {
gogo() {
console.log("粗发");
},
},
});
</script>
v-modol(双向数据绑定)
<body>
<div id="app">
<input
type="text"
v-model="look"
placeholder="最基础的数据双向绑定"
/>{{look}}
<hr />
性别
<label><input type="radio" value="男" v-model="message.sex" />男</label>
<label><input type="radio" value="女" v-model="message.sex" />女</label>
<hr />
爱好
<label><input type="checkbox" value="羽毛球" v-model="message.love" id="" />羽毛球</label>
<label><input type="checkbox" value="乒乓球" v-model="message.love" id="" />乒乓球</label>
<label><input type="checkbox" value="排球" v-model="message.love" id="" />排球</label>
<br>
<button @click='gogo'>提交</button>
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
data: {
look: "",
message: {
sex: "男",
love:['羽毛球']
},
},
methods:{
gogo(){
console.log(this.message);
}
}
}).$mount("#app");
</script>
修饰符
- .lazy修饰符:让v-model从原来的oninput事件变成onchange事件(change:改变)(变懒)
- .number修饰符:将内容自动转换为数字类型
- .trim修饰符:去掉字符串亮两边的空格
<body>
<div id="app">
<!-- lazy(懒):v-model只在失去焦点后执行 -->
<input type="text" v-model.lazy="my_lazy" />{{my_lazy}}
<br>
<!-- .number:将v-model输入的值转化为数字类型 -->
<input type="number" v-model.number='my_number' @change='gogo'>{{my_number}}
<br>
<input type="text" v-model.trim='my_trim'>{{my_trim}}
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
my_lazy: "",
my_number:null,
my_trim:''
},
methods:{
gogo(){
console.log(this.my_number);
}
}
});
</script>
组件的创建
- 全局组件:在任何一个vue实例挂载的容器中使用(一次写一个)
- 局部组件:只能在当前vue实例挂载的容器中使用(可以创建多个)
- 组件中任然可以使用之前的data,methods,computed,watch,但是data这里要改成一个函数,并且必须要return一个{}出来
- components:组件
<body>
<div id="app">
<go></go>
<login></login>
</div>
<div id="ppa">
<gogo></gogo>
<login></login>
</div>
</body>
<script src="../vue.js"></script>
<script>
// 全局组件可以在全部的Vue实例中使用
Vue.component("login", { template: "<p>这是全局的</p>" });
new Vue({
el: "#app",
// 局部组件
components: {
go: {
template: '<a href="#">这是app局部的</a>',
},
},
});
new Vue({
el: "#ppa",
components: {
gogo: {
template: '<a href="#">这是ppa局部的</a>',
},
},
});
</script>
脚手架工具@vue/cli3
- 全局安装:npm install -g @vue/cli
- 版本检查:vue -V
- 装: vue create 名字
- 启动:npm run serve
组件之间信息的传递?
- 给子组件传递数据
- 如果是变量,记得给属性名前加v-bind指令
- 如果是字符串,直接传递即可
子组件:
<template>
<div>
<!-- 5. 将获得的内容展示在页面上 -->
<h1>{{ title }}</h1>
<p v-for="(index, value) in list" :key="index">{{ value }}</p>
</div>
</template>
<script>
export default {
name: "Main",
// 子组件接受父组件给的数据
// props: ["list", "title"], // 方法一
// 方法二:带有验证性质的
props: { // 4. 从父组件获得内容
list: {
type: Array,
// 必须传入
required: true,
// 自定义验证器
validator(value) {
return value.length >= 3;
},
},
title: {
type: String,
// 默认值
default:'Hello LSH'
},
},
};
</script>
父组件:
<template>
<div>
<Header></Header>
<Main :list="list" title="hello"></Main> <!-- 3. 将获得的值放入转化后的组件中 -->
<Footer></Footer>
</div>
</template>
<script>
import Main from "../components/Main.vue"; // 1. 引入子组件
export default {
name: "home",
data() {
return {
list: ["面条", "米饭", "肉"],
};
},
components: {
Main, // 2. 将子页面转换为父页面的组件
},
};
</script>
组件之间的通信
父传子
1.在父组件中嵌套子组件
2.在父组件的template中使用子组件标签
3.在子组件中使用props接收数据
4.接收之后,可以在子组件中自由的使用,但是不能修改
子传父
父元素
<template>
<div>
<Show :myText="list"></Show>
<!-- 3. 设置自定义事件,获得参数 -->
<Index @newTodo="addTodo($event)"></Index>
</div>
</template>
<script>
import Index from "./components/Input.vue";
import Show from "./components/Show.vue";
export default {
name: "todos",
data() {
return {
// 1. 声明接收变量
list: [],
};
},
methods: {
// 2. 给父元素创建一个函数,获得的数据来自子元素
addTodo(title) {
this.list.push({ title, done: false });
},
},
components: {
Index,
Show,
},
};
</script>
<style scoped lang="scss"></style>
子元素
<template>
<div>
<input type="text" v-model="text" /><br />
<button @click="gogo">上传</button>
</div>
</template>
<script>
export default {
name: "Input",
data() {
return {
text: null,
};
},
methods: {
gogo() {
// 4. 触发自定义事件,并且传参
this.$emit("newTodo", this.text);
console.log(this.text);
this.text = "";
},
},
};
</script>
<style scoped lang="scss"></style>
sync
父组件
<template>
<div>
{{ bar }}
<!-- 1. 在自定义事件后加 .sync,他就会自动添加一个自定义事件:updata:aaa (aaa指:自定义事件名) -->
<Children :aaa.sync="bar"></Children>
</div>
</template>
<script>
import Children from "./components/add.vue";
export default {
name: "Index",
data() {
return {
bar: "父组件",
};
},
components: {
Children,
},
};
</script>
<style scoped lang="scss"></style>
子组件
<template>
<div>
<button @click="gogo">改变</button>
</div>
</template>
<script>
export default {
name: "add",
methods: {
gogo() {
// 调用updata:aaa事件,并且可以直接传参,这里参数用于修改bar的值
this.$emit("update:aaa", "大家好");
},
},
};
</script>
<style scoped lang="scss"></style>
事件总线
- 创建一个独立的Vue实例XXX,并且导出
- 通过XXX.$on(‘自定义事件名’,回调函数)
- 在另一个组中,XXX.emit(‘自定义事件名’,‘参数’)
声明一个js文件,传出一个独立的Vue实例
// 事件总线
import Vue from 'vue'
export default new Vue()
父组件,作用:引入子组件
<template>
<div>
<A></A>
<B></B>
</div>
</template>
<script>
import A from "./components/A.vue";
import B from "./components/B.vue";
export default {
name: "Index",
components: {
A,
B,
},
};
</script>
<style scoped lang="scss"></style>
子组件A :监听,绑定事件
<template>
<div>{{ eat }}</div>
</template>
<script>
import event from "../../../assets/eventBus";
export default {
data() {
return {
eat: "下午吃啥?",
};
},
mounted() {
// let aaa = this; // 如果不使用箭头函数,可以将this交给一个变量
event.$on("eat", (need) => {
console.log(need);
this.eat = need;
});
},
};
</script>
<style scoped lang="scss"></style>
组件B :触发事件
<template>
<div>
<button @click="gogo">下午吃啥</button>
</div>
</template>
<script>
import event from "../../../assets/eventBus";
export default {
methods: {
gogo() {
event.$emit("eat",'超级肉夹馍');
},
},
};
</script>
<style scoped lang="scss"></style>
provide/inject(后代之间数据传递)
- provide:提供
- inject:注入
爷爷组件 :用于暴露数据
<template>
<div>
爷爷组件
<two></two>
</div>
</template>
<script>
import two from "./two.vue";
export default {
name: "one",
// 将定义的值暴露给后代组件
data() {
return {};
},
provide: {
name1: "父亲组件",
name2: "儿子组件",
},
mounted() {
this.name1 = "123";
console.log(this.name1);
},
components: {
two,
},
};
</script>
<style scoped lang="scss"></style>
父亲组件 :获取爷爷组件暴露的内容
<template>
<div>
{{name1}}
<three></three>
</div>
</template>
<script>
import three from './three.vue'
export default {
name:'two',
// 获得祖先暴露的值
inject:['name1'],
components:{
three
}
}
</script>
<style scoped lang='scss'>
</style>
儿子组件 :获取爷爷组件暴露的内容
<template>
<div>{{ name2 }}</div>
</template>
<script>
export default {
name: "three",
// 获得祖先暴露的值
inject: ["name2"],
};
</script>
<style scoped lang="scss"></style>
内容分发(插槽)
- 有名字的与具名插槽相互匹配
- 没名字的都进入默认插槽
- 在子组件中,定义一些数据給父组件使用的叫做作用于插槽
- slot:插槽
父组件
<template>
<div>
父组件
<Children>
<a href="http://www.baidu.com">百度</a>
<!-- 根据slot值,插入到对应名称的插槽中 -->
<a href="#" slot="yh">雅虎</a>
<a href="#" slot="zh">知乎</a>
<a href="#" slot="tb">淘宝</a>
<a href="#" slot="jd">京东</a>
<template slot="zyy" slot-scope="props">{{props.text}}</template>
</Children>
</div>
</template>
<script>
import Children from "./children.vue";
export default {
name: "parent",
components: {
Children,
},
};
</script>
<style scoped lang="scss"></style>
子组件
<template>
<div>
子组件<br />
<!-- 默认插槽 -->
<!-- 没有名字的进入默认插槽 -->
<slot></slot>
<hr />
<!-- 有名字的进入各自对应的插槽 -->
<!-- 具名插槽 -->
<slot name="tb"></slot><br />
<slot name="jd"></slot><br />
<slot name="zh"></slot><br />
<slot name="yh"></slot>
<hr />
<!-- 作用域插槽 -->
<!-- 在子组件中,定义一些数据給父组件使用 -->
<slot name="zyy" text="作用域插槽"></slot>
</div>
</template>
<script>
export default {};
</script>
<style scoped lang="scss"></style>
:is指令
- :is=‘XXX’,这里的XXX一定是组建的名称,来自于components{}
- 作用:根据XXX的值来渲染某个组件,当我们切换XXX的值,:is组件就会切换成不同的组件
- v-once:对低开销的静态组件使用
父组件
<template>
<div>
<select v-model="tab">
<option value="Tab1">Tab1</option>
<option value="Tab2">Tab2</option>
<option value="Tab3">Tab3</option>
</select>
<!-- :is='XXX',这里的XXX一定是组建的名称,来自于components{} -->
<!-- 作用:根据XXX的值来渲染某个组件,当我们切换XXX的值,:is组件就会切换成不同的组件 -->
<div :is='tab'></div>
</div>
</template>
<script>
import Tab1 from "./tab1.vue";
import Tab2 from "./tab2.vue";
import Tab3 from "./tab3.vue";
export default {
name: "tabs",
data(){
return{
tab:'Tab1'
}
},
components: {
Tab1,
Tab2,
Tab3,
},
};
</script>
<style scoped lang="scss"></style>
子组件1
<template>
<div><span style="background:pink;">Tab1</span></div>
</template>
<script>
export default {};
</script>
<style scoped lang="scss"></style>
子组件2
<template>
<div>Tab2</div>
</template>
<script>
export default {
}
</script>
<style scoped lang='scss'>
</style>
子组件3
<template>
<div>Tab3</div>
</template>
<script>
export default {
}
</script>
<style scoped lang='scss'>
</style>
keep-alive
- 可以对失活的组件进行缓存,可以通过$childer查看当前子组件的列表
- inclode:要缓存的是哪些组件
- exclode:不要缓存的是那些组件
- keep:保持
- alive:或者
<keep-alive exclude="Tab2">
<div :is="tab"></div>
</keep-alive>
$nextTick
- $nextTick:在上一轮的所有的异步操作都完成了,再执行
- next:下一个
- tick:标记;刻点
// $nextTick:在上一轮的所有的异步操作都完成了,再执行
this.$nextTick(() => {
console.log(newValue);
console.log(this.$children);
});
filter(过滤器)
- 对数据进行格式化处理
- {{ 变量 | 处理规则 }}
{{ 3120314(变量) | rmb }} ==> $3,120,314
······
filters:{
rmb: function(value) {
let i = String(value)
.split("")
.reverse();
for (let b = 1; b < i.length; b++) {
if (b % 3 == 0) {
i[b] = i[b]+",";
}
}
i='$'+i.reverse().join('')
// console.log(i);
// let c=null
// for(let b=0;b<i.length;b++){
// c+=i[b]
// }
// console.log(value);
return i;
},
}
钩子函数
beforeCreate | 组件实例加载前 |
---|---|
created | 组件实例加载完成 |
beforeMount | 模板挂载前 |
mounted | 模板挂载完成后 |
beforeUpdate | 数据更新前 |
update | 数据更新后 |
beforeDestroy | 数据销毁前 |
destroyed | 数据销毁完成 |
activated | 激活 |
deactivated | 失活 |
beforeCreate() {
console.log("组件实例创建之前");
},
created() {
console.log("组件实例挂载完成");
},
beforeMount() {
console.log("模板挂载之前");
},
mounted() {
console.log("模板挂载之后");
},
beforeUpdate() {
console.log("数据更新之前");
},
updated() {
console.log("数据更新完成");
},
beforeDestroy() {
console.log("数据销毁之前");
},
destroyed() {
console.log("数据销毁");
},
activated(){
console.log('激活');
},
deactivated(){
console.log('失活');
}
自定义指令
全局样式
less预处理器
cnpm i less@4.1.2 less-loader@5.0.0 --save-dev
防抖
思考:
<template>
<el-input v-model="text" @input="debounceInput" />
</template>
<script>
export default {
mounted () {
this.debounceInput = this.debounce(this.handle, 1000,false)
},
data () {
return {
text: '',
debounceInput: () => {},
}
},
methods: {
handle (value) {
console.log(value)
},
debounce (func, delay = 1000, immediate = false) {
let timer = null
//不能用箭头函数
return function () {
//在时间内重复调用的时候需要清空之前的定时任务
if (timer) {
clearTimeout(timer)
}
//适用于首次需要立刻执行的
if (immediate && !timer) {
func.apply(this,arguments)
}
timer = setTimeout(() => {
func.apply(this,arguments)
}, delay)
}
},
}
}
</script>