01. vue基础

一:各个文件夹的作用

1. build:构建脚本目录,这个基本上不用管

  1. build.js ==> 生产环境构建脚本
  2. check-versions.js ==> 检查npm,node.js版本
  3. utils.js ==> 构建相关工具方法
  4. vue-loader.conf.js ==> 配置了css加载器以及编译css之后自动添加前缀
  5. webpack.base.conf.js ==> webpack基本配置
  6. webpack.dev.conf.js ==> webpack开发环境配置
  7. webpack.prod.conf.js ==> webpack生产环境配置

2. config:项目配置

  1. dev.env.js ==> 开发环境变量
  2. index.js ==> 项目配置文件:端口号等在这里修改
  3. prod.env.js ==> 生产环境变量

3. node_modules:npm 加载的项目依赖模块

4. src:这里是我们要开发的目录

基本上要做的事情都在这个目录里。里面包含了几个目录及文件

  1. assets:资源目录,放置一些图片或者公共js、公共css。这里的资源会被webpack构建
  2. components:组件目录,我们写的组件就放在这个目录里面
  3. router:前端路由,我们需要配置的路由路径写在index.js里面
  4. App.vue:根组件
  5. main.js:入口js文件

5. static:静态资源目录,如图片、字体等。不会被webpack构建

6. index.html:首页入口文件,可以添加一些 meta 信息等

7. package.json:npm包配置文件,定义了项目的npm脚本,依赖包等信息

8. README.md:项目的说明文档,markdown 格式

9. .xxxx文件:这些是一些配置文件,包括语法配置,git配置等

二:新加一个页面的操作

  1. 先在components文件夹下增加.vue文件
  2. 为这个页面创建路由,可以在index.js文件夹下
  3. 编辑vue文件,在中写html;在中写js;在中写样式

三: 基本语法

1. v-if、v-show

<html>
	<head>
		<meta charset="utf-8">
		<title>title>
	head>
	<body>
		<div id="app">
			<p v-if="flag">
				今天天气很舒服!
			p>
			<p v-else-if="rich">
				今天天气很燥热!晚上要去放松一下!
			p>
			<p v-else="rich">
				晚上只能自嗨!
			p>
            <p v-show="rich">
				有钱!
			p>
		div>
		
	body>
	<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
	<script>
		new Vue({
			el:'#app',
			data:{
				flag:false,
				rich:false
			},
			methods:{	
			}
		});
	script>
html>

v-if是创建或者删除p,而v-show实际会将p标签的css样式的display属性设为none来达到隐藏的效果;所以在频繁变动的情况下,使用v-show的效率更高

2. v-for

普通for

<body>
<div id="app">

    <ul>
        <li v-for="a in args">{{a}}li>
    ul>

div>
body>

<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
<script>

    new Vue({
        el:'#app',
        data:{
            args:[1,2,3,4,5,6]
        }
    });
script>

带着索引的for

<body>

<div id="app">

    <ul>
        <li v-for=" (a,i)  in  args" :key='i'>{{i}}{{a}}li>
    ul>

div>
body>

<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
<script>

    new Vue({
        el:'#app',
        data:{
            args:[1,2,3,4,5,6]
        }
    });

script>

遍历一个对象中的信息: v、k、i

<body>

<div id="app">

    <ul>
        <li v-for="(v,k,i) in student">{{i+1}}--{{k}}--{{v}}li>
    ul>

div>
body>

<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
<script>

    new Vue({
    	el:'#app',
    	data:{
       	 	student:{
            	username:'小鱼',
				age:20,
				girl:'如花'
        	}
    	}
	});

script>

v、k、i 这几个字符可以自己定义,分别表示每次循环内容的值、键、序号。

  • v: 循环中每条数据的值 小鱼、20、如花
  • k: 循环中每天数据的键 username、age、girl
  • i: 循环的序号,从0开始

遍历一个对象数组:嵌套for

<body>
<div id="app">
    <ul>
        <li v-for=" student in students">
        	<span v-for="(v,k,i) in student">{{i+1}}--{{k}}--{{v}}span>
    	li>
    ul>
div>
body>

<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>

<script>
    new Vue({
    	el:'#app',
    	data:{
       	 	students:[
            	{
                	name:'xiaoming',
                	age:20
            	},
            	{
                	name:'xiaowang',
                	age:21
            	}
        	]
    	}
	});
script>

3. 属性绑定

1. 双向绑定 v-model

通过v-model将标签的value值与vue对象中的data属性值进行绑定

{{title}}

<html>
	<head>
		<meta charset="utf-8" />
		<title>title>
	head>
	<body>
		<div id="app">
			<input type="text" v-model="title">
			{{title}}
		div>
	body>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
	<script type="text/javascript">
		new Vue({
			el:'#app',
			data:{
				title:"hello vue"
			}
			
		})
	script>
html>

通过这种方式,vue中的数据和输入框中的数据就能保持一致,互相变化

2. 单向绑定 v-bind

插值表达式是不能用在html的标签的属性内,如果一定要用vue的值作为html的标签的属性的内容,可以使用v-bind

<html>
	<head>
		<meta charset="utf-8" />
		<title>title>
	head>
	<body>
		<div id="app">
			<a v-bind:href="link">a>
		div>
	body>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
	<script type="text/javascript">
		new Vue({
			el:'#app',
			data:{
				link:'http://www.baidu.com'
			}
		})
	script>
html>

这样,a标签内的href属性就可以使用vue对象中的属性值。

注意: v-bind也可以简写,使用冒号“:”来代替

<a v-bind:href='link'>a>  ==>  <a :href='link'>

4. el和render

el用来指明vue挂载的元素,可以实String或者element

render方法的实质就是生成template模板

cli2中

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

cli3中

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

5. new Vue()和export default{}的区别

new Vue()就是一个构造函数,用来生成一个Vue实例

export default{}是用来将实例导出,可以在别的文件中,通过import被引用

四:Vue的事件绑定

关于事件,要把握好三个步骤

  1. 设参
  2. 传参
  3. 接参

例如

  1. 设参:
  2. 传参:increase:function(s)
  3. 接参:this.sum+=s
<html>
	<head>
		<meta charset="utf-8" />
		<title>title>
	head>
	<body>
		<div id="app">
			sum={{sum}}<br/>
			{{sum>10?'总数大于10':'总数不大于10'}}<br/>
			<button type="button" @click="increase(2)">增加button>
		div>
	body>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
	<script type="text/javascript">
		new Vue({
			el:'#app',
			data:{
				sum:0
			},
			methods:{
				increase:function(s){
					this.sum+=s
				}
			}
		})
	script>
html>

1. v-on

通过具体的事件名,绑定vue中定义的函数

<html>
	<head>
		<meta charset="utf-8" />
		<title>title>
	head>
	<body>
		<div id="app">
			<input type="text" v-on:click="changeMajor"  />
		div>
	body>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
	<script type="text/javascript">
		new Vue({
    		el:'#app',
    		data:{
        		major:'java'
    		},
    		methods:{
        		sayHi:function(){
            		alert("HELLO VUE!");
        		},
        		changeMajor:function(){
            		console.log("change Title")
        		}
    		}
	script>
html>

此时,该按钮,在点击时将会调用Vue对象中定义的changeMajor方法。

注意: v-on也可以简写,使用"@"替代

<input type="text" @click="changeMajor"  />

2. 事件修饰符

vue中将JavaScript中一些原生的Dom事件进行了封装,更加便于操作

.stop:等同于event.stopPropagation(),防止事件冒泡

.prevent:等同于event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)

.capture:与事件冒泡的方向相反,事件捕获由外到内

.self:只会触发自己范围内的事件,不包含子元素

.once:只会触发一次

可参考:

https://www.cnblogs.com/xuqp/p/9406971.htm

3. 计算属性 computed

说明

  • methods:定义方法,调用方法使用 currentTime1(),需要带括号
  • computed:定义计算属性,调用属性使用 currentTime2,不需要带括号;this.message 是为了能够让 currentTime2 观察到数据变化而变化

注意:methods 和 computed 里不能重名

调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点;计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销


<html>
<head>
    <meta charset="UTF-8">
    <title>布局篇 计算属性title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
head>
<body>

<div id="vue">
    <p>调用当前时间的方法:{{currentTime1()}}p>
    <p>当前时间的计算属性:{{currentTime2}}p>
div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#vue',
        data: {
            message: 'Hello Vue'
        },
        methods: {
            currentTime1: function () {
                return Date.now();
            }
        },
        computed: {
            currentTime2: function () {
                this.message;
                return Date.now();
            }
        }
    });
script>
body>
html>

五 Vue的组件

1. 什么是组件化

要想实现组件化,需要在页面中注册组件:关于注册的方式有两种,分别是全局注册和本地注册。

组件包含了三个部分:template(html视图层内容)、script(Model层)、style(CSS样式)

1.1 全局注册

使用Vue.compent()实现组件的全局注册,全局注册后可以重复使用

vue的全局注册,也就意味着在页面的任意一个被vue绑定过的div中,都可以使用全局注册了的vue组件。


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue组件的全局注册title>
head>
<body>

    <div id="app">

        <model1>model1>
        <model1>model1>
        <model1>model1>

    div>
        <hr/>
    <div id="app1">

        <model1>model1>
        <model1>model1>
        <model1>model1>

    div>


body>

<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
<script>
	//通过Vue.component实现组件的全局注册,全局注册后的组件可以被重复使用。
    Vue.component("model1",{

        template:"

{{title}}

"
, data:function(){ return { title:"hello vue" } }, methods:{ btnfn:function(){ alert("hello !!!"); } } }); new Vue({ el:'#app' }) new Vue({ el:'#app1' })
script> html>

1.2 本地注册

**使用new Vue();的方式进行本地注册

但是,如果是对vue组件进行本地注册,那么在其他被vue绑定的div中,不能使用该组件


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue组件的本地(局部)注册title>
head>
<body>

    <div id="app">

        <model11>model11>
    div>
	<hr/>
    
    <div id="app1">
        <model11>model11>
    div>


body>

<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
<script>

    new Vue({
        el:'#app',
        components:{
            "model11":{

                template:"

{{title}}

"
, data:function(){ return { title:"hello vue" } }, methods:{ btnfn:function(){ alert("hello !!!"); } } } } }) new Vue({ el:'#app1' })
script>

2. 组件的生命周期

Vue中的组件也是有生命周期的。一个Vue组件会经历:初始化、创建、绑定、更新、销毁等阶段,不同的阶段,都会有相应的生命周期钩子函数被调用

<html>
	<head>
		<meta charset="UTF-8">
		<title>生命周期title>
	head>
	<body>
		<div id="app1">
			{{title}}
			<button type="button" @click="changeTitle">change titlebutton>
			<button type="button" @click="destroy">destroybutton>
		div>
	body>
	<script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.min.js">script>
	<script>
		new Vue({
			el:"#app1",
			data:{
				title:"this is title"
			},
			methods:{
				changeTitle:function(){
					this.title= "new title";
				},
				destroy:function(){
					this.$destroy();
				}
			},
			beforeCreate(){
				console.log("beforeCreate")
			},
			created(){
				console.log("created")
			},
			beforeMount(){
				console.log("beforeMount")
			},
			mounted(){
				console.log("mounted")
			},
			beforeUpdate(){
				console.log("beforeUpdate")
			},
			updated(){
				console.log("updated")
			},
			beforeDestroy(){
				console.log("beforeDestory")
			},
			destroyed(){
				console.log("destory")
			}
		})
	script>
html>

3. 组件的参数传递

1. 父传子

通过子组件的props部分,来指明可以接收的参数,父组件通过在标签中写明参数的键值对来传递参数。

​ props是表示一个组件的参数部分,那么props的写法有两种:

​ 1)props:[参数列表]

​ 比如: props:[‘MyProp1’,‘MyProp2’,…]

​ 2)props:{参数名1:{type:String,required:true,default:‘XX’},参数名2:{…}}

创建子组件

<template>
    <div>
      商品列表...
      {{MyTitle}}
      <button type="button" @click="btnfn('hello java')">点我button>
    div>
template>

<script>
    export default {
        name: "Content.vue",
        props:{
          'MyTitle':{
            type:String,
            required:true,
            default:'XX'
          },
          'btnfn':{
            type:Function
          }
        }
    }
script>

<style scoped>

style>

注册子组件:在main.js中注册子组件

import Vue from 'vue'
import App from './App.vue'
//引入Content
import Content from './components/Content'


//全局注册组件
Vue.component('MyContent',Content);

new Vue({
  el: '#app',
  render: h => h(App)
})

创建父组件

<template>
  <div id="app">
		<MyContent :MyTitle="msg"  :btnfn="FCfn" >MyContent>
  div>
template>

<script>
  import MHeader from './components/Header'
export default {
  name: 'app',
  data(){
    return {
      msg:'hello vue!!'
    }
  },
  components:{
    "MHeader":MHeader
  },
  methods:{
    FCfn:function(m){//hello java
      this.msg = m;
    }
  }

}
script>
<style>

style>

2. 子传父

六:路由

通过使用路由,可以实现页面的跳转

使用路由的方式有两种:

  1. 通过
  2. 通过程序式路由

安装路由模块

npm install vue-router -s

在main.js中引入路由并使用

import Vue from 'vue'
import App from './App'
import router from './router'  //引入路由模块

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router, //使用路由模块
  components: { App },
  template: ''
})

1. 创建App.vue

<template>
  <div id="app">
    <ul class="nav nav-tabs">
      <li role="presentation" class="active"><router-link to="/Home">首页router-link>li>
      <li role="presentation"><router-link to="/Product">商品列表router-link>li>
    ul>
    <router-view/>
  div>
template>

<script>
export default {
  name: 'App'
}
script>

2. 创建Home.vue

<template>
    <div>首页div>
template>

<script>
export default {
    name: "Home"
}
script>

<style scoped>

style>

3. 创建Product.vue

<template>
    <div>商品列表 商品的id:{{id}}div>
template>

<script>
export default {
    name: "Product",
    data(){
      return{
        id:this.$route.params.id //接参
      }
    }
}
script>

<style scoped>

style>

4. 增加路由列表:修改路由表src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from "../components/Home";
import Product from "../components/Product";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path:'/Home',
      component: Home
    },
    {
      path:'/Product/:id', //设参
      component:Product
    }
  ]
})

5. 参数的传递

在路由表中设参

export default new Router({
  routes: [
	...
    {
      path:'/Product/:id', //设参
      component:Product
    }
  ]
})

在App.vue中传参

<template>
  <div id="app">
    <ul class="nav nav-tabs">
      ...
      <li role="presentation"><router-link to="/Product/1">商品列表router-link>li>
      ...
    ul>
    <router-view/>
  div>
template>

在Product.vue中接参

<template>
    <div>商品列表 商品的id:{{id}}div>
template>

<script>
export default {
    name: "Product",
    data(){
      return{
        id:this.$route.params.id //接参
      }
    }
}
script>

<style scoped>

style>

6. 程序式路由的实现

使用进行路由跳转是有局限性的,可以通过**this.$router.push(’/Product/1’)**的js方式实现路由跳转,更加灵活。

<template>
  <div id="app">
    <ul class="nav nav-tabs">
      <li role="presentation" class="active"><router-link to="/Home">首页router-link>li>
      <li role="presentation"><router-link to="/Product">商品列表router-link>li>
      <button type="button" @click="btnfn">点我button>
    ul>
    <router-view/>
  div>
template>

<script>
export default {
  name: 'App',
  methods:{
    btnfn(){
      //代替router-link实现路由跳转
      this.$router.push("/Product/1");
    }
  }

}
script>

七:使用Axios发送请求

安装vue axios

npm install --save axios vue-axios

在main.js中引入

import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

1. 发送Ajax请求

在function中这样写

his.axios({
        method:'get',
        url:'http://localhost:8090/regist?mail='+this.mail+'&password='+this.password,

      }).then(function (response) {
        console.log(response.data)
      });
<template>
  <div id="app">
    <div style="width:50%" class="container">
      <div>
        <h3>Registh3>
        <h5>Emailh5>
        <input type="text" class="form-control" v-model="mail" /><br />
        {{mail}}
        <h5>Passwordh5>
        <input type="password" class="form-control" v-model="password" /><br />
        {{password}}
        <h5>Genderh5>
        <input type="radio" name="gender" v-model="gender" value="female" /><input type="radio" name="gender" v-model="gender" value="male" /><br />
        <h5>Hobbyh5>
        <input type="checkbox" name="hobby" v-model="hobby" value="music">音乐
        <input type="checkbox" name="hobby" v-model="hobby" value="movie">电影
        <input type="checkbox" name="hobby" v-model="hobby" value="sport">运动
        <br/>
        <button type="button" class="btn btn-success" @click="registfn">注册button>
      div>
    div>
  div>
template>

<script>
  import MHeader from './components/Header'
export default {
  name: 'app',
  data(){
    return {
      mail:'',
      password:'',
      gender:'',
      hobby:''
    }

  },
  methods:{
    registfn:function(){

      this.axios({
        method:'get',
        url:'http://localhost:8090/regist?mail='+this.mail+'&password='+this.password,

      }).then(function (response) {
        console.log(response.data)
      });
    }
  }
}
script>

2. 服务端解决跨域问题

跨域:域名、端口号、协议(http/https)任何一个不相同都属于跨域

在spring-mvc.xml中加入这一段。其中,allowed-origins指的是允许的访问源的域名,"*"表示任何人都可以访问,也可以指明具体的域名

<mvc:cors>      
    <mvc:mapping path="/"        allowed-origins="*"        allowed-methods="POST, GET, OPTIONS, DELETE, PUT,PATCH"        allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"        allow-credentials="true" />
mvc:cors>

3. 解决axios中无法传递data中的参数的问题

原因:默认情况下发送axios时请求头中的内容类型为: (后端没有使用@RequestBody)

Content-Type:application/json;charset=UTF-8

而实际服务端需要的是:

Content-Type:application/x-www-form-urlencoded

因此,使用axios的qs内置库中的方法进行内容类型的转换

import Qs from 'qs'

this.axios({
	method:'post',
	url:'http://localhost:8081/regist',
	transformRequest: [function (data) {
		return Qs.stringify(data)
	}],
	data:{
		email:this.email
	}
})
.then(function (response) {
	alert(response.data.message)
});

你可能感兴趣的:(前端相关,vue.js,webpack,javascript)