vue2总结

前言:大家好,这次给大家带来一门vue2的基础教程,内容是vued的基本指令,侦听器,过滤器,计算属性,组件的注册,通信,插槽,生命周期,vue-cli快速搭建项目,axios,Vue Router ,Vuex。配套视频一起讲解。

1.vue是什么,这门课可以收获什么?

Vue目前是前端非常火的一个框架,本课程带大家快速掌握vue2的知识点,可以快速上手项目开发。

2.环境搭建

Nodejs下载:https://nodejs.org/en/download,不建议使用最新的,不太稳定,安装好以后,win + r,输入cmd,在黑窗口输入node -v,看到对应的版本信息就是安装成功了。其中npm是nodejs的包管理工具。

在黑窗口输入该命令,提高获取速度:npm config set registry https://registry.npm.taobao.org

查看是否成功:npm config get registry

vscode软件作为开发软件,下载很简单,一路默认就好了,安装完成需要下载一些插件方便开发,如图:

还有一个webpack构建工具,就是快速构建项目的,这里大家做一个了解就好。

3.vue-cli搭建项目

npm install -g @vue/cli

vue create my-project

4.基本指令的讲解

模板语法,v-text和v-html,v-if和v-show,v-bind,v-on,v-for,v-model

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
      <h1>{{ message }}</h1>
      <h1 v-text="title"></h1>
      <h1 v-html="title"></h1>
      <h1 :class="meaage"></h1>
      <input type='text' v-model="count"/>
      <button @click="add">加1</button>
      <h1 v-ifshow="flag">成功</h1>
      <h1 v-if="flag">成功</h1>
      <h1 v-else>失败</h1>
      <ul v-for="(item,index) in books" :key="index">
        <li>{{ item }}  {{ index }}</li>
      </ul>
  </div>
</template>

<script>
// @ is an alias to /src

export default {
  name: 'HomeView',
  components: {
  },
  data(){
    return{
      count:100,
      name:'helloworld',
      title:"<h1>helloworld</h1>",
      flag:true,
      books:['java','vue','python']
    }
  },
  methods:{
    add(){
      this.count++;
    }
  },
  watch:{
    
  },
  computed:{

  },
  filters:{
        //处理函数
        addPriceIcon(value){
            console.log(value)
            return '¥' + value
        }
    }

}
</script>

<style scoped>

</style>

5.侦听器,过滤器,计算属性

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
     
    <div style="border:1px solid red">
      <h1>侦听器:侦听器本质上是一个函数,如果要监听哪一个数据的变化,就把那个数据作为函数名</h1>
      <input type="text" v-model="message" />
      <h1>{{ message }}</h1>
    </div>

    <div style="border:1px solid red">
      <h1>过滤器:处理数据</h1>
      <input type="text" v-model="message" />
      <h1>{{ count | addPriceIcon }}</h1>
    </div>

    <div style="border:1px solid red">
      <h1>计算属性:数据变化才会重新执行函数,没有变化就返回之前的结果</h1>
      <h1>{{ getMessage }}</h1>
    </div>
  </div>
</template>

<script>
// @ is an alias to /src

export default {
  name: 'HomeView',
  components: {
  },
  data(){
    return{
      count:100,
      message:'hello'
    }
  },
  // 侦听器
  watch:{
    message:function(newValue,oldValue){
     console.log('新值' + newValue);
     console.log('新值' + oldValue);
     }
  },
  // 计算属性
  computed:{
      getMessage(){
        return this.message.split("").reverse().join("")
      }
  },
  // 过滤器
  filters:{
        //处理函数
        addPriceIcon(value){
            console.log(value)
            return '¥' + value
        }
    }

}
</script>

<style scoped>

</style>

6.组件的概念,组件通信

ParentNode代码

<template>
  <div>
    <h1>组件的使用</h1>
    <h1>{{ message }}</h1>
    <Node num="1" message = "message" @alter="alterMessage"></Node>
  </div>
</template>

<script>
import Node from "../components/Node.vue"
export default {
  name:'ParentNode',
  components:{
    Node
  },
  data(){
    return{
      message:"hello"
    }
  },
  methods:{
    alterMessage(data){
      this.message = data;
    }
  }
}
</script>

<style>

</style>

Node代码

<template>
  <div>
    <h1>node组件</h1>
    <h1>{{ num }}</h1>
    <h1>{{ message }}</h1>
    <button @click="add">加1</button>
    <button @click="minus">-1</button>
    <button @click="alterParentNode">-1</button>
  </div>
</template>

<script>
export default {
  name:'Node',
  props:{
    num:{
      type:Number,
      default:0
    },
    message:{
      type:String,
      default:"h"
    }
  },
  data(){
    return{
      name:'test'
    }
  },
  methods:{
    add(){
      this.num++;
    },
    minus(){
      this.num--;
    },
    alterParentNode(){
      this.$emit('alter',this.name);
    }
  }
}
</script>

<style>

</style>

7.插槽,动态组件,异步组件

插槽

<template>
  <div>
    <h1>插槽的使用</h1>
    <!-- <Node>
      <div>
        <h1>插槽内容</h1>
      </div>
    </Node> -->

    <Node>
      <template v-slot:header>
        <div>helloworld</div>
      </template>
      <template v-slot:center>
        <div>{{ message }}</div>
      </template>
    </Node>
  </div>
</template>

<script>
import Node from "../components/Node.vue"
export default {
  name:'ParentNode',
  components:{
    Node
  },
  data(){
    return{
      message:"hello"
    }
  },
  methods:{
    alterMessage(data){
      this.message = data;
    }
  }
}
</script>

<style>

</style>
<template>
  <div>
    <h1>插槽</h1>
    <div>
      <!-- slot标签承载数据 -->
       <slot name="header">默认值 </slot>  
       <slot name="center">默认值 </slot>  
    </div>
  </div>
</template>

<script>
export default {
  name:'Node',
  data(){
    return{
      name:'test'
    }
  },
  methods:{
  
    
  }
}
</script>

<style>

</style>

动态组件

<template>
  <div>
    <h1>{{ msg }}</h1>
    <button @click="update">修改</button>
  </div>
</template>

<script>
export default {
  name:"D",
  data(){
    return{
      msg:'hello'
    }
  },
  methods:{
    update(){
      this.msg = 'world';
    }
  }
}
</script>

<style>

</style>

<template>
  <div class="about">
   
    <h1>动态组件:切换组件的时候需要返回,可能我们操作了数据,需要数据不变、异步组件</h1>
    <keep-alive>
      <component :is="currentComponent"></component>
    </keep-alive>
    <button @click="update">切换组件</button>



  </div>
</template>
<script>
// import D from '../components/D.vue'
import HomeView from './HomeView.vue'
异步组件加载
const D = () => import("../components/D.vue")
export default {
  name:"AboutView",
  data(){
    return{
      price:10,
      message:"helloworld",
      currentComponent:D
    }
  },
  components:{
    D,HomeView
  },
  methods:{
    update(){
      if(this.currentComponent === D){
        this.currentComponent = HomeView;
      }else{
        this.currentComponent = D
      }
    }
  },
  watch:{
    message:function(newValue,oldValue){
        console.log('新值' + newValue);
        console.log('旧值' + oldValue);
    }
  },
  computed:{
    getMessage(){
      console.log(this.message);
      return this.message.split("").reverse().join("")
    }
  },
  //过滤器
  filters:{
    addPriceIcon(value){
      return '¥' + value;
    }
  }
}
</script>

<template>
  <div class="home">
     <h1>HomeView</h1>

  </div>
</template>
 
<script>
// @ is an alias to /src
 
export default {
  name: 'HomeView',
  components: {
  },
  data(){
    return{
      count:100,
      message:'hello'
    }
  },
  // 侦听器
  watch:{
    message:function(newValue,oldValue){
     console.log('新值' + newValue);
     console.log('新值' + oldValue);
     }
  },
  // 计算属性
  computed:{
      getMessage(){
        return this.message.split("").reverse().join("")
      }
  },
  // 过滤器
  filters:{
        //处理函数
        addPriceIcon(value){
            console.log(value)
            return '¥' + value
        }
    }
 
}
</script>
 
<style scoped>
 
</style>

8.生命周期,路由Vue-Router

Vue的生命周期就是vue实例从创建到销毁的全过程,也就是new Vue() 开始就是vue生命周期的开始。

vue生命周期可以分为八个阶段,分别是:

beforeCreate(创建前)、created(创建后)、beforeMount(载入前)、mounted(载入后)、beforeUpdate(更新前)、updated(更新后)、beforeDestroy(销毁前)、destroyed(销毁后)

1、创建前(beforeCreate)

对应的钩子函数为beforeCreate。此阶段为实例初始化之后,此时的数据观察和事件机制都未形成,不能获得DOM节点。

2、创建后(created)

对应的钩子函数为created。在这个阶段vue实例已经创建,仍然不能获取DOM元素。

一般来说,如果组件在加载的时候需要和后端有交互,放在这俩个钩子函数执行都可以,如果是需要访问props、data等数据的话,就需要使用created钩子函数

3、载入前(beforeMount)

对应的钩子函数是beforemount,在这一阶段,我们虽然依然得不到具体的DOM元素,但vue挂载的根节点已经创建,下面vue对DOM的操作将围绕这个根元素继续进行;beforeMount这个阶段是过渡性的,一般一个项目只能用到一两次。

4、载入后(mounted)

对应的钩子函数是mounted。mounted是平时我们使用最多的函数了,一般我们的异步请求都写在这里。在这个阶段,数据和DOM都已被渲染出来。

5、更新前(beforeUpdate)

对应的钩子函数是beforeUpdate。在这一阶段,vue遵循数据驱动DOM的原则;beforeUpdate函数在数据更新后虽然没立即更新数据,但是DOM中的数据会改变,这是Vue双向数据绑定的作用。

6、更新后(updated)

对应的钩子函数是updated。在这一阶段DOM会和更改过的内容同步。

##beforeUpdate和updated的钩子函数执行时机都是在数据更新的时候,beforeUpdate的执行时机是在 渲染Watcher 的before函数中,update的执行时机是在flushSchedulerQueue函数调用的时候

7、销毁前(beforeDestroy)

对应的钩子函数是beforeDestroy。在上一阶段vue已经成功的通过数据驱动DOM更新,当我们不在需要vue操纵DOM时,就需要销毁Vue,也就是清除vue实例与DOM的关联,调用destroy方法可以销毁当前组件。在销毁前,会触发beforeDestroy钩子函数。

8、销毁后(destroyed)

对应的钩子函数是destroyed。在销毁后,会触发destroyed钩子函数。

vue的生命周期的思想贯穿在组件开发的始终,通过熟悉其生命周期调用不同的钩子函数,我们可以准确地控制数据流和其对DOM的影响;vue生命周期的思想是Vnode和MVVM的生动体现和继承。

vue路由:类似于html的a标签,跳转页面的

路由的基础使用

index.js的配置文件

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
import NextTick from '../views/NextTick.vue'
import Parent from '../views/Parent.vue'
import ParentNode from '../views/ParentNode.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/parent',
    name: 'parent',
    component: Parent
  },
  {
    path: '/parentNode',
    name: 'parentNode',
    component: ParentNode
  },
  {
    path: '/nextTick',
    name: 'nextTick',
    component: NextTick
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

9.Axios

介绍网站:https://www.oschina.net/p/axios?hmsr=aladdin1e1

vue项目安装axios:

npm install axios --save

axios获取数据

<template>
	<div v-if="weather" style="text-align: center;">
		<img alt="Vue logo" class="logo" src="/src/assets/logo.svg" width="125" height="125" />
		<h3>{{weather.city}} 今日天气</h3>
		<h3>{{weather.month[0].night.temperature}}℃ ~ {{weather.month[0].day.temperature}}℃ 
			<img v-bind:src="img" width="20" style="vertical-align: sub;" /> {{weather.day.phrase}}
		</h3>
		<p>空气质量:<a>{{weather.day.air_level}}</a> &nbsp;&nbsp;气压:<a>{{weather.day.altimeter}}mb</a> &nbsp;&nbsp;湿度:<a>{{weather.day.humidity}}%</a></p>
		<p>白天:{{weather.month[0].day.narrative}}</p>
		<p>夜间:{{weather.month[0].night.narrative}}</p>
		<p style="padding: 30px 0; color:#999999;">数据来源:<a href="https://tianqiapi.com/index/doc?version=worldchina" target="_blank">Tianqiapi.com</a></p>
	</div>
</template>

<script>
	import axios from 'axios';
	export default {
		data() {
			return {
				img: '',
				weather: ''
			}
		},
		mounted() {
			let appid = '43656176';//43656176
			let appsecret = 'I42og6Lm';//I42og6Lm
			console.log('mounted')
			axios({
				method: 'get',
				url: 'https://v0.yiketianqi.com/api/worldchina?appid=' + appid + '&appsecret=' + appsecret
			}).then(res => {
				console.log(res.data);
				this.weather = res.data
				this.img = 'https://xintai.xianguomall.com/skin/peach/' + res.data.day.phrase_img + '.png';
			});
		},
	}
</script>

封装axios请求,在utils下创建一个request.js文件

import axios from 'axios'
import router from "@/router";

const request = axios.create({
    baseURL: 'http://localhost:9090',
    timeout: 5000
})

// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null
    if (user) {
        config.headers['token'] = user.token;  // 设置请求头
    }

    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        // 当权限验证不通过的时候给出提示
        if (res.code === '401') {
            // ElementUI.Message({
            //     message: res.msg,
            //     type: 'error'
            // });
            router.push("/login")
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)


export default request

10.Vuex

概念:状态管理模式,集中管理共享状态

vuex的js文件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {          //存储数据
    count:100,
    name:'helllo'
  },
  getters: {
  },
  mutations: {       //操作方法
    setCount(state){
      state.count++;
    },
    minusCount(state,num){
      state.count -= num;
    }
  },
  actions: {
    asyncIncrement(context,num){  //异步操作
      setTimeout(() => {
        context.commit('setCount',num)
      },1000)
    }
  },
  modules: {
  }
})

基本使用

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <h1>VueX的数据:{{ $store.state.count}}</h1>
    <h1>VueX的数据:{{ count}}</h1>
    <h1>VueX的数据:{{ name}}</h1>
    <button @click="changeCount">增加</button>
    <button @click="minusCount1">减少10</button>
  </div>
</template>

<script>
  import {mapState,mapMutations,mapActions} from 'vuex'

  export default {
		data() {
			return {
				img: '',
				weather: ''
			}
		},
    computed:{
      ...mapState(['count','name'])   //读取vuex的数据c'c
    },
		methods:{
      ...mapMutations(["minusCount","setCount"]),
      ...mapActions(["asyncIncrement"]),
      minusCount1(){
        // this.$store.commit('minusCount',10);
        this.minusCount(10)
      },
      changeCount(){
        // this.$store.commit('setCount')
         this.setCount();
        //this.$store.dispatch("asyncIncrement");//异步
      }
    }
  }
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值