vue框架及相关知识总结
vue框架及相关知识总结
一、vue框架
vue官网:https://cn.vuejs.org/guide/quick-start.html
vue是基于MVVM(Model-View-ViewModel)实现数据双向绑定的,当数据模型数据发生变化时,页面展示的会随之发生变化,而如果表单数据发生变化,绑定的模型数据也随之发生变化。
1、响应式基础
(1)声明属性
<template>
<div>
<span>{{ msg }}</span>
</div>
</template>
<script>
export default {
data() {
return {
//声明属性
msg: "hello world",
};
},
};
</script>
(2)声明方法
<template>
<div>
<div>{{ msg }}</div>
</div>
</template>
<script>
export default {
data() {
return {
msg: "hello world",
};
},
methods: {
//声明方法
updateMsg() {
this.msg = "123";
},
},
};
</script>
2、计算属性
模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护,如:
<template>
<div>
<div>
<span>是否有符合条件的书:</span>
<span>{{
books.length > 0 && books[0].price > 100
? "有"
: loaded
? "没有"
: "查询中..."
}}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loaded: false,
books: [],
};
},
mounted() {
setTimeout(() => {
this.books.push({
bookName: "js",
price: 132,
});
this.loaded = true;
}, 2000);
},
};
</script>
这个时候推荐用计算属性:
<template>
<div>
<div>
<span>是否有符合条件的书:</span>
<span>{{ getBooksInfo }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loaded: false,
books: [],
};
},
computed: {
getBooksInfo() {
return books.length > 0 && books[0].price > 100
? "有"
: loaded
? "没有"
: "查询中...";
},
},
mounted() {
setTimeout(() => {
this.books.push({
bookName: "js",
price: 132,
});
this.loaded = true;
}, 2000);
},
};
</script>
3、类与样式绑定
<template>
<div>
<div class="p20 A">A</div>
<div class="p20" :class="showB ? 'B' : ''">B</div>
<div class="p20" :class="{ C: showC }">C</div>
<div class="p20" :class="[d1, d2]">D</div>
<div style="padding: 20px; background: #ccc; color: #fff">E</div>
<div :style="{ background: black, padding: '20px', color: '#fff' }">F</div>
</div>
</template>
<script>
export default {
data() {
return {
showB: true,
showC: true,
d1: "D-1",
d2: "D-2",
black: "#000",
};
},
};
</script>
<style>
.p20 {
padding: 20px;
}
.A {
color: #fff;
background: red;
}
.B {
color: #fff;
background: blue;
}
.C {
color: #fff;
background: yellow;
}
.D-1 {
color: #fff;
}
.D-2 {
background: green;
}
</style>
4、条件渲染
(1)v-if
<template>
<div>
<div v-if="type == 1">A</div>
<div v-else-if="type == 2">B</div>
<div v-else>C</div>
</div>
</template>
<script>
export default {
data() {
return {
type: 1,
};
},
};
</script>
(2)v-show
<template>
<div>
<div v-show="type == 1">A</div>
</div>
</template>
<script>
export default {
data() {
return {
type: 1,
};
},
};
</script>
(3)v-if与v-show的区别
v-show 由false变为true的时候,不会触发组件的生命周期
v-if由false变为true的时候,会触发组件的生命周期
v-if有更高的切换消耗,v-show有更高的初始渲染消耗
可通过审查元素查看
5、列表渲染
<template>
<div>
<div v-for="(item, index) in list" :key="item.id">{{ item.title }}</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
};
},
created() {
for (let i = 0; i < 100; i++) {
this.list.push({
id: i,
title: "标题 - " + i,
});
}
},
};
</script>
注意: 同时使用 v-if
和 v-for
是不推荐的,因为这样二者的优先级不明显
6、事件处理
我们可以使用 v-on
指令 (简写为 @
) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript。
用法:v-on:click="methodName"
或 @click="handler"
。示例:
<template>
<div>
<div @click="clickTest">点击事件测试</div>
</div>
</template>
<script>
export default {
methods: {
clickTest() {
console.log("123");
},
},
};
</script>
阻止点击事件传递:
<template>
<div>
<div class="blue" @click="clickBlue">
<div class="red" @click.stop="clickRed"></div>
</div>
</div>
</template>
<script>
export default {
methods: {
clickBlue() {
console.log("blue");
},
clickRed() {
console.log("red");
},
},
};
</script>
<style lang="less" scoped>
.blue {
width: 100px;
height: 100px;
background: blue;
.red {
width: 50px;
height: 50px;
background: red;
}
}
</style>
7、生命周期
Vue 组件实例在创建到销毁过程中经历的生命周期如下:
<template>
<div id="root">
<h2>{{ msg }}</h2>
</div>
</template>
<script>
export default {
data() {
return {
msg: "hello world",
};
},
//vue实例被创建前,不能访问data、method,
beforeCreate() {
console.log("----------beforeCreate----------");
console.log(this.msg); //undefined
console.log(this.$el); //undefined
},
//vue实例已被创建,vue实例中的data、method已被初始化,可以调用data和method,
//一般在此对数据进行初始化
created() {
console.log("----------created----------");
console.log(this.msg); //hello world
console.log(this.$el); //undefined
},
//模板已经编译完成,但还没有被渲染至页面中(虚拟dom还未加载为真实dom)
//一般可以在这里做初始数据的获取
beforeMount() {
console.log("----------beforeMount----------");
console.log(this.msg); //hello world
console.log(this.$el); //undefined
},
//此时模板已经被渲染成真实DOM,用户已经可以看到渲染完成的页面
//这是实例创建的最后一个生命周期函数,执行完mounted代表实例被完全创建好了
//此时如果没有其它操作的话,这个实例就静静的躺在我们的内存中
mounted() {
console.log("----------mounted----------");
console.log(this.msg); //hello world
console.log(this.$el); //<div id="root"><h2>{{ msg }}</h2></div>
setTimeout(() => {
//触发beforeUpdate、updated生命周期
this.msg = "123";
}, 2000);
},
//view层的数据变化,重新渲染页面前触发
beforeUpdate() {
console.log("----------beforeUpdate----------");
},
//页面渲染完成
updated() {
console.log("----------updated----------");
},
//组件被销毁前执行,一般在这里清除计时器、绑定的事件等操作
beforeDestroy() {
console.log("----------beforeDestroy----------");
},
//组件销毁(Dom元素存在,只是不再受vue控制)
destroyed() {
console.log("----------destroyed----------");
},
};
</script>
8、侦听器
(1)普通监听
<template>
<div>
<div class="num">{{ num }}</div>
<div class="btn" @click="add">加</div>
</div>
</template>
<script>
export default {
data() {
return {
num: 0,
};
},
watch: {
//每一次num的值改变都会触发此方法
num(newVal, oldVal) {
console.log("newVal = " + newVal);
console.log("oldVal = " + oldVal);
},
},
methods: {
add() {
this.num++;
},
},
};
</script>
<style>
.num{
padding: 10px;
border: 1px solid #333;
}
.btn{
height: 44px;
line-height: 44px;
background: red;
color: #fff;
margin-top: 10px;
}
</style>
(2)即时回调监听
watch默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调,这时要添加:immediate: true
<script>
export default {
data() {
return {
num: 0,
};
},
watch: {
num: {
//每一次num的值改变都会触发此方法
handler(newVal, oldVal) {
console.log("newVal = " + newVal);//newVal=0
console.log("oldVal = " + oldVal);//oldVal=undefined
},
immediate: true, //刚创建监听时就会先执行一遍
},
}
};
</script>
(3)深层监听
当监听的属性为对象时,若对象里的某个属性值被修改,要触发回调需要添加深层监听
<script>
export default {
data() {
return {
person: {
name: "李白",
age: 18,
},
};
},
watch: {
//即使person中的某个属性值改变也会触发此方法
person: {
handler(newVal, oldVal) {
console.log(newVal);
console.log(oldVal);
},
deep: true,//深层监听
},
},
};
</script>
9、过滤器
<template>
<div>
<span>性别:</span>
<span>{{ sexCode | filterSex }}</span>
</div>
</template>
<script>
export default {
data() {
return {
sexCode: 1,
};
},
filters: {
filterSex(val) {
return val == 1 ? "男" : "女";
},
},
};
</script>
10、组件
实际项目开发中,我们会将重复的ui部分封装为组件,以达到每个页面简化代码的目的。
(1)自定义组件
这里以定义一个名字为MyComponent的组件为例:
<template>
<div>我是自定义组件</div>
</template>
<script>
export default {};
</script>
(2)引用组件
引用MyComponent组件的父组件的代码:
<template>
<div>
<MyComponent></MyComponent>
</div>
</template>
<script>
import MyComponent from "@/components/MyComponent.vue";
export default {
components: {
MyComponent,
}
};
</script>
(3)props传值
MyComponent代码:
<template>
<div>{{msg}}</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: "",
},
person: {
type: Object,
default: {},
}
},
};
</script>
引用MyComponent组件的父组件的代码:
<template>
<div>
<MyComponent msg="hello world"></MyComponent>
</div>
</template>
<script>
import MyComponent from "@/components/MyComponent.vue";
export default {
components: {
MyComponent,
}
};
</script>
(4)事件
MyComponent代码:
<template>
<div @click="handleClick">{{msg}}</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: "",
},
},
methods:{
handleClick(){
this.$emit("clickme","123")
}
}
};
</script>
引用MyComponent组件的父组件的代码:
<template>
<div>
<MyComponent msg="hello world" @clickme="handleClick"></MyComponent>
</div>
</template>
<script>
import MyComponent from "@/components/MyComponent.vue";
export default {
components: {
MyComponent,
},
methods:{
handleClick(data){
console.log(data);
}
}
};
</script>
(5)模版引用ref
现在给MyComponent组件添加一个属性num和方法test,便于其父组件通过模板引用访问:
<template>
<div @click="handleClick">{{msg}}</div>
</template>
<script>
export default {
data(){
return {
num: 100
}
},
props: {
msg: {
type: String,
default: "",
},
},
methods:{
test(){
console.log("test");
},
handleClick(){
this.$emit("clickme","123")
}
}
};
</script>
引用MyComponent组件的父组件的代码:
<template>
<div>
<MyComponent ref="myComponent" msg="hello world" @clickme="handleClick">
</MyComponent>
</div>
</template>
<script>
import MyComponent from "@/components/MyComponent.vue";
export default {
components: {
MyComponent,
},
mounted(){
console.log(this.$refs.myComponent.num)
this.$refs.myComponent.test();
},
methods:{
handleClick(data){
console.log(data);
}
}
};
</script>
二、vue-router
vue-router官网:https://router.vuejs.org/zh/introduction.html
1、安装
npm:
npm install vue-router@4
yarn:
yarn add vue-router@4
一般在创建项目的过程中就会安装好vue-router,以上命令用于创建项目时没有安装vue-router,而是在项目创建好后安装的
2、路径配置
示例:
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
const routes = [
{
path: "/",
redirect: "/index",
},
{
path: "/index",
component: () => import("@/views/index.vue"),
},
];
const router = new VueRouter({
mode: "hash",
// mode: "history",
base: process.env.BASE_URL,
routes,
});
export default router;
3、页面跳转
使用router-link标签跳转:
<div>
<router-link to="/about">About</router-link>
</div>
使用router的API跳转:
this.$router.push({
path: "/about"
});
4、页面传参
方式1:
this.$router.push({
path: "/xxx/xxx?a=1"
});
方式2:
this.$router.push({
path: "/xxx/xxx",
query: {
a: "1",
}
});
接收参数:
mounted() {
let a = this.$route.query.a;
},
5、路由守卫
import router from "@/router";
router.beforeEach((to, from, next) => {
...
});
路由守卫一般用于页面跳转前的拦截处理,如:跳转前判断是否登录,没有登录就跳到登录页面,已登录则放行,让其继续跳转
import router from "@/router";
router.beforeEach((to, from, next) => {
if(hasLogin){
//已登录,正常跳转
next();
}else{
//未登录,改跳登录页面
next({
path: "/login",
query: param
});
}
});
6、公众号登录
三、接口请求
vue项目接口请求方式有多种,如:jquery、vue-resource、fetch.js、axios.js等,考虑到jquery用起来比较麻烦,vue-resource已不再维护,官方推荐使用fetch和axios。因为实际项目中都在用axios,所以这里只介绍axios
1、安装axios
npm:
npm install axios
yarn:
yarn add axios
2、get请求
import axios from "axios";
axios
.get("https://autumnfish.cn/search?keywords=演员")
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
3、post请求
import axios from "axios";
axios
.post(url, params)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
4、请求头配置
import axios from "axios";
const instance = axios.create({
headers: {
"Content-Type": "application/json",
}
});
instance
.post(url, params)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
5、代理配置
(1)、vue cli 2.0项目
只需在config路径下的index.js文件内的proxyTable内添加代理配置即可:
(2)、vue cli 3.0项目
在项目根目录下vue.config.js文件下加如下配置:
代理配置:
//代理配置
devServer: {
port: "8090", //修改端口
open: true, //项目启动时自动打开浏览器
proxy: {
"/epi-web": {
target: "https://wx.whsdxhqwjj.com/epi-web/",
changeOrigin: true,
pathRewrite: {
"/epi-web": "",
},
},
},
},
vue cli 配置 devServer.proxy 官方文档:https://cli.vuejs.org/zh/config/#devserver-proxy
更多推荐
所有评论(0)