一、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-ifv-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

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐