Vue基础入门到精通案例大全

266 阅读9分钟

学习vue需要了解的知识

NPM 使用介绍

NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:

  • 允许用户从NPM服务器下载别人编写的第三方包到本地使用。
  • 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
  • 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

NodeJs介绍

简单的说 Node.js 就是运行在服务端的 JavaScript。

Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。

Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

**优点:**1. 高并发(最重要的优点)

\2. 适合I/O密集型应用

**缺点:**1. 不适合CPU密集型应用;CPU密集型应用给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起;

解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起;

\2. 只支持单核CPU,不能充分利用CPU

\3. 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃

原因:单进程,单线程

解决方案:(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;

(2)开多个进程监听同一个端口,使用cluster模块;

\4. 开源组件库质量参差不齐,更新快,向下不兼容

\5. Debug不方便,错误没有stack trace

vue

Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。

Vue 只关注视图层, 采用自底向上增量开发的设计。

Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

Vue 学习起来非常简单,本教程基于 Vue 2.1.8 版本测试。

第一个案例

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <!--获取属性值-->
  <p>{{ message }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
</script>
</body>
</html>

vue安装

1:独立版本

我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 标签引入

下载地址:vuejs.org/js/vue.min.…

2:cdn安装

3:npm安装

1:下载node.js

nodejs.org/zh-cn/downl…

直接点击下一步傻瓜式安装

2:配置环境变量

置环境变量 让path指向 node.js的安装目录的node.exe文件

如:

PATH=D:/node_home/node.exe

3:查看安装版本

安装完了node.js已经自带了npm这时候可以查看node.js和npm的版本

C:\Users\admin>node -v
v12.18.4

C:\Users\admin>npm -v
6.14.6

C:\Users\admin>

4:npm修改镜像

修改镜像比较麻烦,这里安装一个切换镜像工具 nrm

安装语法是npm install nrm

npm install nrm

5:查看可用的镜像

C:\WINDOWS\system32>nrm ls

  npm -------- https://registry.npmjs.org/
  yarn ------- https://registry.yarnpkg.com/
  cnpm ------- http://r.cnpmjs.org/
* taobao ----- https://registry.npm.taobao.org/
  nj --------- https://registry.nodejitsu.com/
  npmMirror -- https://skimdb.npmjs.com/registry/
  edunpm ----- http://registry.enpmjs.org/

切换镜像 :nrm use 镜像名

例如:

C:\WINDOWS\system32>nrm use taobao

   Registry has been set to: https://registry.npm.taobao.org/

6:测速:

C:\WINDOWS\system32>nrm test

  npm ---- 4480ms
  yarn --- 2979ms
  cnpm --- 1092ms
* taobao - 326ms
  nj ----- Fetch Error
  npmMirror  6259ms
  edunpm - Fetch Error


C:\WINDOWS\system32>

7:创建项目

这里也可以随便创建一个空文件夹,或用hbuilder工具创建一个空项目

8:初始化项目

进入项目目录

npm init -y

执行初始化命令后会多一个package.json文件

9:安装 vue

说明:

安装成功会多出node_modules

这时候就可以编写一个简单地vue项目了

--save是本地安装 -g 是全局安装

具体安装命令例如:

npm install vue --save

如果看到node_modules文件夹就说明安装成功了

4: npm其他命令

查看可安装的版本

npm view jquery versions

安装带有版本号的插件

npm install bootstrap@3.3.7 --save

npm install jquery@2.1.1 --save

模板语法

插值

普通文本插值

<div id="app">
    <!--插入一个普通的文本 或json对象 包括jsonarr-->
  <p>{{ message }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})

html插值

<div id="app">
    <div v-html="message"></div>
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
    message: '<h1>hello</h1>'
  }
})

属性插值

<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
   .class1{
      background: #444;
      color: #eee;
   }
</style>	
<div id="app">
  <!--这里等价于<div v-bind:class="'class1'"> -->
  <!--这里还可以把 【v-bind:class="a"】 缩写成  【:class="a"】-->
  <div v-bind:class="a">  
  
  </div>
</div>
    
<script>
  new Vue({
      el: '#app',
    data:{
        a: "class1"
    }
  });
</script>	
<div id="app">
    <pre><a v-bind:href="url">百度</a></pre>
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
    url: 'http://www.baidu.com'
  }
})
</script>	

表达式插值

   <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
   <div id="app">
	    {{5+5}}<br>
	   {{ true ? 'YES' : 'NO' }}<br> <!--这里输出是yes-->
	   {{ false ? 'YES' : 'NO' }}<br> <!--这里输出是NO-->
   </div>
	
   <script>
      new Vue({
       el: '#app'
      })
   </script>

指令

根据指令是否显示p元素

<div id="app">
     <p v-if="true">现在你看到我了我被显示了</p>
	 <p v-if="a">现在你看到我了</p>
</div>
    
<script>
    new Vue({
      el: '#app',
      data: {
        a: true
      }
    })
</script>	

用户输入双向数据绑定

双向绑定

	
<div id="app">
    <p>{{ message }}</p>
    <input v-model="message">
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
    message: '我是初始值!'
  }
})
</script>	

指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。

过滤器

vue.js允许你自定义过滤器,被用作一些常见的文本格式化。由"管道符"指示, 格式如下:

		<div id="app">
            <!--fun1是调用过滤器函数,把message传入此函数-->
            <!--fun2是调用过滤器函数,把fun1的返回值传入此函数-->
		  {{ message | fun1 | fun2}}  <!--最后输出应该是“value_=” -->
		</div>

		<script>
		new Vue({
		  el: '#app',
		  data: {
			message: 'value'
		  },
		  filters: {  
			 //这是过滤器函数,接收管道左边的值message
			fun1 (v) {
			  return v+"_"//过滤原字符串添加一个"_"
			},
			fun2 (v) {
			  return v+"=" //过滤原字符串添加一个"="
			}
		  }
		})
		</script>

缩写

v-bind 缩写

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>

v-on 缩写

<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>

条件语句

v-if语句

		<div id="app">
			<p v-if="b">现在你看到我了如果b的值是false就看不到我了</p> 
		</div>

		<script>
            new Vue({
              el: '#app',
              data: {
                b: true
              }
            })
		</script>

v-else语句

	<div id="app">
		<div v-if="false">
			如果是true就显示我
		</div>
		<div v-else>
		  否则选择我
		</div>
	</div>

	<script>
		new Vue({
		  el: '#app'
		})
   </script>

v-else-if

		<div id="app">
			<div v-if="type === 'A'">
			  A
			</div>
			<div v-else-if="type === 'B'">
			  B
			</div>
			<div v-else-if="type === 'C'">
			  C
			</div>
			<div v-else>
			  Not A/B/C
			</div>
		</div>

		<script>
            new Vue({
              el: '#app',
              data: {
                type: 'D'
              }
            })
		</script>

v-show

		<div id="app">
			<h1 v-show="ok">Hello!</h1>
		</div>

		<script>
		new Vue({
		  el: '#app',
		  data: {
			ok: true
		  }
		})
		</script>

循环语句

循环array

		<div id="app">
		  <ol>
			<li v-for="user in users">
			  {{ user.name}}  {{ user.age}}
			</li>
		  </ol>
		</div>

		<script>
		new Vue({
		  el: '#app',
		  data: {
			users: [
			  { name: 'zhnagsan',age: 12 },
			  { name: 'lisi'    ,age: 13 },
			  { name: 'wangwu'  ,age: 14 }
			]
		  }
		})
		</script>

迭代对象

	<div id="app">
	  <ul>
		<li v-for="value in user">
		  {{ value }}
		</li>
	  </ul>
	</div>

	<script>
	new Vue({
	  el: '#app',
	  data: {
		 user: {
		  name: 'zhangsan',
		  age: 13,
		  sex: '男'
		}
	  }
	})
	</script>

嵌套循环一个jsonarr

		<div id="app">
			 
			 <table border="1">
				  <tr>
					  <th>id</th>
					  <th>name</th>
					  <th>age</th>
				  </tr>
				  
				  <tr v-for="user in  users">
					  <td v-for="u in user">{{u}}</td>
				  </tr>
				 
			 </table>
		</div>

		<script>
            new Vue({
              el: '#app',
              data: {
               users:[
				  {id:1,name: 'zhnagsan',age: 12 },
				  {id:2, name: 'lisi'    ,age: 13 },
				  {id:3, name: 'wangwu'  ,age: 14 }
			   ]
              }
            })
		</script>

也可以提供第二个的参数为键名

	<div id="app">
	  <ul>
		<li v-for="(value, key) in user">
		{{ key }} : {{ value }}
		</li>
	  </ul>
	</div>

	<script>
	new Vue({
	  el: '#app',
	  data: {
		user: {
		  name: '张三',
		  age: 13,
		  sex: '男'
		}
	  }
	})
	</script>

第三个参数为索引:

	<div id="app">
	  <ul>
		<li v-for="(value, key, index) in user">
		{{ key }} : {{ value }} : {{index}}
		</li>
	  </ul>
	</div>

	<script>
	new Vue({
	  el: '#app',
	  data: {
		user: {
		  name: '张三',
		  age: 13,
		  sex: '男'
		}
	  }
	})
	</script>

实战案例不显示id通过索引来控制

<div id="app">
	 
	 <table border="1">
		  <tr>
			  <th>name</th>
			  <th>age</th>
		  </tr>
		  
		  <tr v-for="user in  users">
			  <td v-if="index!=0"  v-for="(value,key,index) in user">{{value}}</td>
		  </tr>
		 
	 </table>
</div>

<script>
	new Vue({
	  el: '#app',
	  data: {
	   users:[
		  {id:1,name: 'zhnagsan',age: 12 },
		  {id:2, name: 'lisi'    ,age: 13 },
		  {id:3, name: 'wangwu'  ,age: 14 }
	   ]
	  }
	})
</script>

实战案例不显示key来控制

<div id="app">
	 
	 <table border="1">
		  <tr>
			  <th>name</th>
			  <th>age</th>
		  </tr>
		  
		  <tr v-for="user in  users">
			  <td v-if="key!='id'"   v-for="(value,key) in user">{{value}}</td>
		  </tr>
		 
	 </table>
</div>

<script>
	new Vue({
	  el: '#app',
	  data: {
	   users:[
		  {id:1,name: 'zhnagsan',age: 12 },
		  {id:2, name: 'lisi'    ,age: 13 },
		  {id:3, name: 'wangwu'  ,age: 14 }
	   ]
	  }
	})
</script>

迭代整数

<div id="app">
  <ul>
    <li v-for="n in 10">
     {{ n }}
    </li>
  </ul>
</div>

<script>
new Vue({
  el: '#app'
})
</script>

计算属性

字符串倒序

<div id="app">
  {{ message.split('').reverse().join('') }}
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'ABC!'
  }
})
</script>

computed 和methods

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

<div id="app">
  <p>原始字符串: {{ message }}</p>
  <p>计算后反转字符串: {{ fun1 }}</p>
  <p>使用方法后反转字符串: {{ fun2() }}</p>
</div>

<script>
	var vm = new Vue({
	  el: '#app',
	  data: {
		message: 'ABC'
	  },
	  computed: {
		fun1 () {
		  return this.message.split('').reverse().join('')
		}
	  },
	  methods: {
		fun2 () {
		  return this.message.split('').reverse().join('')
		}
	  }
	})
</script>

computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter

<div id="app">
  <p>{{ jisuan }}</p>
</div>

<script>
	var vm = new Vue({
	  el: '#app',
	  data: {
		name: '我是原来的老值'
	  },
	  computed: {
		jisuan: {
		  // getter
		  get () {
			return this.name
		  },
		  // setter
		  set (newValue) {
			this.name = newValue
		  }
		}
	  }
	})
	// 调用 setter, vm.name 和 vm.url 也会被对应更新
	alert("调get方法获取老值为:   "+vm.jisuan)
	//调set方法赋新值
	vm.jisuan = '新值';
	alert("调get方法获取新值为:   "+vm.jisuan)
</script>

监听属性

外部编写监听属性

<div id = "app">
 <p style = "font-size:25px;">计数器: {{ counter }}</p>
 <button @click = "counter++">点我</button>
</div>
<script type = "text/javascript">
	 var vm = new Vue({
		el: '#app',
		data: {
			//这个属性将要被监听
		   counter: 1
		}
	 });

	//用watch监听属性counter ,我们可以通过 watch 来响应数据的变化
    //watch是vue的一个属性不是自定义属性 和data、el、methods都是平级的。
    //访问vue的属性是需要加上$符号的 例如:$watch、$data等
	 vm.$watch('counter', function(newval, olderval) {
		alert('我正在监听计数器值的变化 :' + olderval + ' 变为 ' + newval + '!');
	 });

</script>

内部编写监听

		<div id="div">
			<button @click="fun1()">counter加一</button>
			<br>
			<button @click="b+=2">监听b</button><br>
			counter:{{counter}}<br>
			b: {{b}}
		</div>
	    
	    <script type="text/javascript">
	    	 new Vue({
				 el:"#div",
				 data:{
					counter:0,
					b:0
				 },
				 methods:{
					 fun1(){
						 this.counter += 1
					 }
				 },
				 watch:{
					 //监听的属性名和函数名名一致
					 counter(newvalue,oldervalue){
						 alert("counter: "+newvalue+"  "+oldervalue)
					 },
					 b(newvalue,oldervalue){
						 alert("b: "+newvalue+"  "+oldervalue)
					 }
				 }
			 })
	    </script>

内部编写监听属性

计算米和千米之间的转换

watch是监听属性的vue属性不是自定义属性

      <div id = "computed_props">
         千米 : <input type = "text" v-model = "kilometers">
         米 : <input type = "text" v-model = "meters">
      </div>
	  
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#computed_props',
            data: {
               kilometers : 0,
               meters:0
            },
            watch : {
                //这个是监听kilometers属性 方法名就是要监听的属性名
               kilometers() {
                  this.meters = this.kilometers * 1000
               },
                 //这个是监听meters属性 方法名就是要监听的属性名
                meters () {	   
                  this.kilometers =  this.meters/ 1000;
               }
            }
         });
      </script>

样式绑定

class 属性绑定

我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:

案例1:显示 class

	<style>
		.active {
			width: 100px;
			height: 100px;
			background: green;
		}
	</style>
	<div id="app">
	  <div v-bind:class="{ 'active': isActive }"></div>
	</div>

	<script>
        new Vue({
          el: '#app',
          data: {
            isActive: true
          }
        })
	</script>

点击按钮显示和禁用class

       	<style>
       		.active {
       			width: 100px;
       			height: 100px;
       			background: green;
       		}
       	</style>
       	<div id="app">
       	     <div :class="{'active': b}"></div>
			 <button @click="b=true">启用active样式</button>
			 <button @click="b=false">禁用active样式</button>
       	</div>
       	<script>
               new Vue({
				   el:"#app",
				   data:{
					   b:false
				   }
			   })
       	</script>

案例2:切换 class

<style>
    .active1 {
        width: 100px;
        height: 100px;
        background: green;
    }

    .active2 {
        width: 100px;
        height: 100px;
        background: yellow;
    }
</style>
<div id="app">
    <div :class="{'active1': b1,'active2':b2}"></div>
    <button @click="b1=true;b2=false">启用active1样式</button>
    <button @click="b2=true;b1=false">禁用active2样式</button>
</div>
<script>
    new Vue({
        el:"#app",
        data:{
            b1:true,
            b2:false
        }
    })
</script>

绑定多个样式

<style>
	.widthheight {
		width: 100px;
		height: 100px;
		background: red;
	}
	.solid {
		width: 100px;
		height: 100px;
		border: solid black;
	}
</style>	
			
<div id="app">
	<!--通过属性绑定两个样式-->
    <!--相当于  <div v-bind:class="['widthheight','solid']"></div> -->
	<div v-bind:class="[a, b]"></div>
    
</div>

<script>
	new Vue({
	  el: '#app',
	  data: {
		a: 'widthheight',
		b: 'solid'
	  }
	})
</script>

内联样式绑定

<div id="app">
	<div v-bind:style="{ color: a1, fontSize: a2 + 'px' }">我是div被内联样式控制</div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    a1: 'red',
	a2: 50
  }
})
</script>

也可以直接绑定一个样式对象

<div id="app">
  <div v-bind:style="styleObject">hello</div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    styleObject: {
      color: 'green',
      fontSize: '30px'
    }
  }
})

v-bind:style 可以使用数组将多个样式对象应用到一个元素上:

<div id="app">
  <div v-bind:style="[a, b]">hello</div>
</div>

<script>
    new Vue({
      el: '#app',
      data: {
        a: {
          color: 'green',
          fontSize: '30px'
        },
        b: {
            //添加边框 加粗效果
          'font-weight': 'bold'
        }
      }
    })
</script>

事件处理器

单击事件弹出框

<div id="app">
  <button v-on:click="alert('我被点击了')">单击事件</button>
</div>

<script>
new Vue({
  el: '#app'
})
</script>

双击事件

		<div id="app">
			<input v-on:dblclick="alert(123)" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

change内容发生改变事件

		<div id="app">
			 <input v-on:change="alert(213)" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

键盘按下事件

		<div id="app">
			 <input v-on:keydown="alert(213)" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

键盘松开事件

		<div id="app">
			 <input v-on:keyup="alert(213)" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

鼠标按下事件

		<div id="app">
			 <input v-on:mousedown="alert(213)" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

鼠标松开事件

		<div id="app">
			 <input v-on:mouseup="alert(213)" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

当鼠标在此元素上离开时触发事件

		<div id="app">
			 <input v-on:mouseout="alert(213)" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

鼠标在此元素上移动时发生的事件

		<div id="app">
			 <input v-on:mousemove="alert('移动事件')" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script> 

鼠标进入此元素时触发事件


		<div id="app">
			 <input v-on:mouseover="alert('鼠标进入')" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

获取焦点事件

		<div id="app">
			 <input  v-on:focus="alert('获取焦点事件')" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

失去焦点事件

		<div id="app">
			 <input  v-on:focusout="alert('失去焦点事件')" />
		</div>
		<script>
		new Vue({
		  el: '#app'
		})
		</script>

单击事件调一个方法

<div id="app">
  <button v-on:click="fun1()">点击</button>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    name: 'Vue.js'
  },
  methods: {
    fun1() {
          //
		  alert(event.target.tagName)
          //event.srcElement    event.target
    }
  }
})
</script>

也可以直接用javascript调用一个函数和访问一个属性

<script>
	var vue = new Vue({
	  data:{
	    name:"张三"
	  },
	  methods: {
		fun1 () {
		  alert('hello')
		}
	  }
	})
	// 也可以用 JavaScript 直接调用方法
	vue.fun1() 	
	//直接访问vue的属性
	alert(vue.name)
	
</script>

表单双向绑定

输入框

单行文本

<div id="app">
  <input v-model="message1">
  <p>{{ message1 }}</p>	
  
  <textarea v-model="message2"></textarea>
	<p>{{ message2 }}</p>
</div>

<script>
	new Vue({
	  el: '#app',
	  data: {
		message1: 'message1',
		message2: 'message2'
	  }
	})
</script>

输入框

多行文本

		 <div id="div">
		 	 <textarea v-model="userName"></textarea>
			 {{userName}}
		 </div>
		 
		 <script type="text/javascript">
		 	new Vue({
				el:"#div",
				data:{
					userName:"初始设置"
				}
				
			});
		 </script>

单个复选框

<div id="app">
  <p>单个复选框:</p>
  <input type="checkbox"  v-model="checked">
  <label>{{ checked }}</label>
</div>

<script>
new Vue({
  el: '#app',
  data: {
	checked : false
  }
})
</script>

多个复选框

<div id="app">
  <input type="checkbox"  value="A" v-model="checkedNames">
  <label>百度</label>
	<br>
  <input type="checkbox"  value="B" v-model="checkedNames">
  <label>谷歌</label>
	
  <br>
  <span>选择的值为: {{ checkedNames }}</span>
</div>

<script>
	new Vue({
	  el: '#app',
	  data: {
		checkedNames: []
	  }
	})
</script>

多个复选框默认勾选A和B


		   <div id="app">
			   
			 <input type="checkbox" value="A" v-model="values">
			 <input type="checkbox" value="B" v-model="values">
			 <input type="checkbox" value="C" v-model="values">
			 
			 {{values}}
		   </div>
		   
		   <script>
		   new Vue({
				 el: '#app',
				 data: {
				//当values是数组类型的时候 绑定checkbox是追加数据而不是替换数据
				 values : ["A","B"]
			 }
		   })
		   </script>

change事件实现全选和反选效果

		   <div id="app">
			 <input type="checkbox" v-model="b" v-on:change="fun1()"/> <br>
			 <input type="checkbox" value="A" v-model="values">
			 <input type="checkbox" value="B" v-model="values">
			 <input type="checkbox" value="C" v-model="values">
			 {{values}}
		   </div>
		   
		   <script>
		   new Vue({
				 el: '#app',
				 data: {
				//当values是数组类型的时候 绑定checkbox是追加数据而不是替换数据
				 values : [],
				 b:false
			     },
				 methods:{
					 fun1(){
						if(this.b){
							this.values=['A','B','C']
						}else{
							this.values=[]
						}
					 }
				 }
		   })
		   </script>

单选按钮

<div id="app">
  <input type="radio"  value="A" v-model="picked">
  <label>百度</label>
  <br>
  <input type="radio"  value="B" v-model="picked">
  <label>谷歌</label>
  <br>
  <span>选中值为: {{ picked }}</span>
</div>

<script>
	new Vue({
	  el: '#app',
	  data: {
		picked : 'A'
	  }
	})
</script>

下拉框

<div id="app">
    <select v-model="value">
        <option value="">-请选择一个选项--</option>
        <option value="A">你选中了A</option>
        <option value="B">你选中了B</option>
        <option value="C">你选中了C</option>
    </select>
    {{value}}
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            value : '' //value值是哪一个选项将被默认选择这一项
        }

    })
</script>

自定义组件

语法:Vue.component(tagName, options)

<div id="app">
	<a1></a1>
</div>

<script>
// 注册
Vue.component('a1', {
  template: '<h1>自定义组件!</h1>'
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>

局部组件

<div id="app">
	<a1></a1>
</div>

<script>
var Child1 = {
  template: '<h1>自定义组件!</h1>'
}

// 创建根实例
new Vue({
  el: '#app',
  components: {
    'a1': Child1
  }
})
</script>

props

作用是父组件向子组件传递数据

<div id="app">
	<child pname1="我是属性值1" pname2="我是属性值2"></child>
</div>

<script>
// 注册
Vue.component('child', {
  props: ['pname1','pname2'],
  template: '<span>插入属性值: {{ pname1 }} {{pname2}}</span>'
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>

动态prop

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件

<div id="app">
	<div>
	  <input v-model="parentMsg">
	  <br>
	  <child v-bind:pname="parentMsg"></child>
	</div>
</div>

<script>
	// 注册
	Vue.component('child', {
	  // 声明 props
	  props: ['pname'],
	  // 同样也可以在 vm 实例中像 “this.message” 这样使用
	  template: '<span>{{ pname }}</span>'
	})
	// 创建根实例
	new Vue({
	  el: '#app',
	  data: {
		parentMsg: '父组件内容'
	  }
	})
</script>

父组件给子组件传一个动态绑定的user

		<div id="app">
			id:<input v-model="user.id"/>
			userName:<input v-model="user.userName"/>
			<a1 v-bind:pn1="user"></a1>
		</div>
		<script>
			 Vue.component("a1",{
				 template:
				 `
				    <span>{{pn1.id}}  --  {{pn1.userName}}</span>
				 `,
				 props:["pn1"]
			 })
			
			
			new Vue({
				el:"#app",
				data:{
					user:{id:1,userName:"张三"}
				}
			})
			
		</script>

循环组件,每循环一次父组件给子组件传一个user

        <div id="div">
			 <input v-model="users[0].id" />
			 <tag1  v-bind:user1="user" v-for="user in users" ></tag1>
			
		</div>
         <script>
			 //自定义一个组件 传入user对象
			 Vue.component("tag1",{
				 template:
				 `
				   <span>
						<hr>
						<ul>
						   <li>{{user1}}</li>
						</ul
					</span>
					 <hr>
				 `,
				 props:["user1"]
			 })
			 
			 
			 //创建vue对象
			 new Vue({
				 el:"#div",
				 data:{
					 users:
					  [
						   { userName: '张三',password:"123" },
						   { userName: '李四',password:"234" },
						   { userName: '王五',password:"345" }
					  ]
				 }
			 })
			 
		 </script>

组件内部也可以定义函数

        <div id="div">
			 <tag1></tag1>
		</div>
         <script>
			 //自定义一个组件 传入user对象
			 Vue.component("tag1",{
				 template:
				 `
				   <span>
					   <button v-on:click="mothod1()">点我一下</button>
					</span>
				 `,
				 methods:{
					 mothod1(){
						 alert("我被点击了")
					 }
				 }
				 
			 })
			 
			 
			 //创建vue对象
			 new Vue({
				 el:"#div",
				 methods:{
					 method2(){
						 alert(1231)
					 }
				 }
			 })
			 
		 </script>

自定义子组件属性

自定义组件里面的data 必须是一个函数,通过调用函数获属性

         <div id="div">
			 <tag1></tag1>
		</div>
         <script>
			 //自定义一个组件 传入user对象
			 Vue.component("tag1",{
				 template:
				 `
				   <span>
					   <button v-on:click="mothod1()">点我一下</button>
					</span>
				 `,
				 methods:{
					 mothod1(){
						 alert(this.name+"  "+this.age)
					 }
				 },
				 data:function(){
					 return {
						   name:"q3",
						   age:12
					 }
				 }
				 
			 })
			 //创建vue对象
			 new Vue({
				 el:"#div",
				 methods:{
					 method2(){
						 alert(1231)
					 }
				 }
			 })
			 
		 </script>

组件 - 自定义事件

内部函数触发外部函数无参数

        <div id="div">
			
        	<tag1 v-on:event1="func2()"></tag1>
		
        </div>

        <script type="text/javascript">
        	
			Vue.component("tag1",{
				template:
				`
				     <button v-on:click="func1()">点击我</button>
				`,
				methods:{
					func1(){
						//添加一个触发外部的自定义事件
						this.$emit("event1")
					}
				}
			})
			
			new Vue({
				el:"#div",
				methods:{
					func2(){
						alert(222)
					}
				}
			})
        </script>

内部函数触发外部函数无参数

<div id="app">
	<div id="counter-event-example">
	  <p>{{ total }}</p>
	  <!-- 第三步当这个event1事件被触发时,调fun2()函数,event1 由内向外触发 -->
	  <button1 v-on:event1="fun2()"></button1>
	  <button1 v-on:event1="fun2()"></button1>
	</div>
</div>
<script>
	
Vue.component('button1', {
	//第一步:当按钮被点击时触发fub1()函数
  template: '<button v-on:click="fun1()">请点击按钮</button>',
  methods: {
    fun1 () {
		// 第二步:触发外部event1事件 emit 发出
      this.$emit('event1')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    fun2 () {
      this.total += 1
    }
  }
})
</script>

内部函数向外部函数传简单数据

<div id="div">
	<button1 v-on:event1="fun2($event)"></button1>
</div>
<script>
	
    Vue.component('button1', {
      template: '<button v-on:click="fun1()">请点击按钮</button>',
      methods: {
        fun1 () {
          this.$emit('event1','我是子组件的数据被到父组件了。')
        }
      },
    })
    new Vue({
      el: '#div',
      methods: {
        fun2 (a) {
            //输出子组件传过来的数据
            alert(a)
        }
      }
    })
</script>

内部函数向外部函数传json数据

<div id="div">
    <!--$event是接收参数-->
	<button1 v-on:event1="fun2($event)"></button1>
</div>
<script>
	
    Vue.component('button1', {
      template: '<button v-on:click="fun1()">请点击按钮</button>',
	  data: function(){
		  return{
			 user:{name:"zhagsan",age:13}
		  }
	  },
      methods: {
        fun1 () {
            //$emit向外触发一个自定义的事件 event1是事件名
          this.$emit('event1',this.user)
        }
      },
    })
    new Vue({
      el: '#div',
      methods: {
        fun2 (user) {
            //输出子组件传过来的数据
            alert(user.name+"  "+user.age)
        }
      }
    })
</script>

内部函数向外部函数传表单数据

<div id="div">
	<button1 v-on:event1="fun2($event)"></button1>
</div>
<script>
	
    Vue.component('button1', {
      template: `
	    <p>
			userName:<input  v-model="user.name"> <br>
			password: <input  v-model="user.age"><br>
			<button @click="fun1()">点击我</button>
		</p>
		
	  `
	  ,
	  data: function(){
		  return{
			 user:{name:"zhagsan",age:13}
		  }
	  },
      methods: {
        fun1 () {
          this.$emit('event1',this.user)
        }
      },
    })
	
    new Vue({
      el: '#div',
      methods: {
        fun2 (user) {
            //输出子组件传过来的数据
            alert(user.name+"  "+user.age)
        }
      }
    })
</script>

组件内部元素不显示的问题

例如:

这个是正确的可以正常显示

  template: `
    <p>
		userName:<input  v-model="user.name"> <br>
		password: <input  v-model="user.age"><br>
		<button @click="fun1()">点击我</button>
	</p>
	

这个是正确的可以正常显示

  template: `
		<span>
			<div>A</div>
			<div>A</div>
		</span>
  `

这个是不正常的,是不能正常显示的

		<p>
			<div>A</div>
			<div>A</div>
			<input>
			<input>
		</p>

全局属性

<div id="div">
    <button2></button2>
    <button2></button2>
	<button2></button2>
</div>

<script>
    //count是全局属性
	var abc = { count: 0}
	Vue.component('button2', {
		data: function () {
			// data 选项是一个对象(外部对象),会影响到其他实例
			return abc
		},
		template: '<button v-on:click="count++">点击了 {{ this.count }} 次。</button>'
	})
	
	new Vue({ 
		el: '#div' ,
	})
</script>

局部属性

<div id="div">
    <button2></button2>
    <button2></button2>
	<button2></button2>
</div>

<script>
	Vue.component('button2', {
		data: function () {
			// count是局部属性
			return { count: 0}
		},
		template: '<button v-on:click="count++">点击了 {{ this.count }} 次。</button>'
	})
	
	new Vue({ 
		el: '#div' ,
	})
</script>

组件内部input元素和外面属性进行双向绑定

<div id="app">
    <runoob-input   v-model="num"></runoob-input>
    <p>输入的数字为:{{num}}</p>
</div>
<script>
	
	//<input v-model="parentData">
Vue.component('runoob-input', {
    template: `
    <p>   <!-- 包含了名为 input 的事件 -->
      <input :value="value"   @input="$emit('input', $event.target.value)">
    </p>
    `,
	props:["value"]
})
   
new Vue({
    el: '#app',
    data: {
        num: 100,
    }
})
</script>

Vue.js Ajax(axios)

Axios是什么:

​ Axios是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中

promise是什么:

1、主要用于异步计算 2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果 3、可以在对象之间传递和操作promise,帮助我们处理队列

安装axios:

使用 cdn:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

或者

<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>

再或者直接下载axios.min.js文件

github.com/axios/axios

案例1:

axios.get("url",{ withCredentials: true}) //保持登录状态
axios.defaults.withCredentials = true;//保持登录状态
axios.get("url")

案例2:

        axios.get("child.html").then(function(response){
			alert(response.data)
		})

案例3:

axios.get("child.html").then(response => alert(response.data))

案例4:回调函数

语法是:axios.get(url).then(calbackfunction); //和jquery的ajax一样返回的是json数据

     
	 <script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
	 <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
	 <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
	<div id="div">
		 <table border="1">
			 <td>id</td>
			 <td>userName</td>
			 <td>password</td>
			 <tr v-for="user in users">
				 <td>{{user.id}}</td>
				 <td>{{user.userName}}</td>
				 <td>{{user.password}}</td>
			 </tr>
		 </table>
		
	</div>
   <script type="text/javascript">
   	    new Vue({
			el:"#div",
			data:{
				users:[]
			},
			created() {
				var this_ = this;
				axios.get("http://localhost:8080/getUsers").then(function(data){
					this_.users = data.data;
				})
			}
		})
   </script>
 

案例3:简写回调函数

		 <div id="div">
		 	 <table border="1">
		 	 	<tr>
					<th>userName</th>
					<th>password</th>
				</tr>
		 	 	<tr v-for="user in users">
					<td v-if="key != 'id'" v-for="(value,key) in user">{{value}}</td>
				</tr>
		 	 </table>
		 </div>
		<script type="text/javascript">
			 new Vue({
				 el:"#div",
				 data:{
					 users:[]
				 },
				 created() {
				 	axios.get("http://localhost:8080/getUsers").
                    then(response => this.users = response.data)
				 }
			 })
		</script>

get传参数

第一种

 axios.post("http://localhost:8080/getUsers?id=1&name=张三")

第二种

 axios.get("http://localhost:8080/getUsers",{params:{id:2, name:"lisi"}})

post传参数

 axios.post("http://localhost:8080/getUsers?id=1&name=张三")
var data  =  new FormData()
data.append("id",1)
data.append("name","zhangsan")
axios.post("http://localhost:8080/getUsers",data)

发送多个ajax请求

语法:

ajax1(){
    axios.get("http://localhost:8080/ajax1")
    .then(response => alert(response))
}
ajax2(){
    axios.get("http://localhost:8080/ajax2")
    .then(response => alert(response))	 
}
axios.all([ajax1(), ajax2()]).then(alert("success"))

案例:

<div id="div">
    {{a}} ---- {{b}}
</div>

<script>
    new Vue({
        el:"#div",
        data:{
            a:"a",
            b:"b"
        },
        created() {
            axios.all([this.ajax1(), this.ajax2()]).then(alert("success"))
        },
        methods:{
            ajax1(){
                axios.get("http://localhost:8080/ajax1")
                    .then(response => this.a = response.data)
            },
            ajax2(){
                axios.get("http://localhost:8080/ajax2")
                    .then(response => this.b = response.data)	 
            }
        }
    })
</script>

文件上传

前端

<script src="js/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
	<input id="file" type="file"
	 accept="image/png,image/gif,image/jpeg"
	  @change="upload"/>
</div>
<script>
	new Vue({
		el:"#app",
		methods:{
		    upload () {  
				var file = document.getElementById("file").files[0]
				var param = new FormData()  // 创建form对象
				param.append('file', file)  // 通过append向form对象添加数据
				param.append('chunk', 'hello') // 添加form表单中其他数据
				var config = {
				  headers: {'Content-Type': 'multipart/form-data'}
				}
				axios.post("http://localhost:8080/upload",param,config).then(response =>{
					alert(response.data)
				})
			}
		}
	})
</script>

后端

@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file, String chunk) {
    if (file.isEmpty()) {
        return "上传失败,请选择文件";
    }
    String fileName = file.getOriginalFilename();
    String filePath = this.getClass().getResource("/").getPath();
    new File(filePath + "static").mkdirs();

    File dest = new File(filePath + "static/"+fileName);
    System.out.println(dest.getPath());
    try {
        file.transferTo(dest);
        System.out.println("上传成功");
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "success";
}

钩子函数以及生命周期

<div id="app">
     <p>{{ message }}</p>
	 
	 <button onclick="update()">update</button>
	 <button onclick="delete1()">update</button>
</div>
 
<script type="text/javascript">
     
  var app = new Vue({
      el: '#app',
      data: {
          message : "xuxiao is boy"
      },
       beforeCreate: function () {
                console.group('beforeCreate 创建前状态===============》');
               console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
               console.log("%c%s", "color:red","data   : " + this.$data); //undefined
               console.log("%c%s", "color:red","message: " + this.message) //undefined
        },
        created: function () {
            console.group('created 创建完毕状态===============》');
            console.log("%c%s", "color:red","el     : " + this.$el); //undefined
               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
               console.log("%c%s", "color:red","message: " + this.message); //已被初始化
        },
        beforeMount: function () {
            console.group('beforeMount 挂载前状态===============》');
            console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
            console.log(this.$el);
               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化 
               console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
        },
        mounted: function () {
            console.group('mounted 挂载结束状态===============》');
            console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
            console.log(this.$el);   
               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
               console.log("%c%s", "color:red","message: " + this.message); //已被初始化
        },
        beforeUpdate: function () {
            console.group('beforeUpdate 更新前状态===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);  
               console.log("%c%s", "color:red","data   : " + this.$data);
               console.log("%c%s", "color:red","message: " + this.message);
        },
        updated: function () {
            console.group('updated 更新完成状态===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);
               console.log("%c%s", "color:red","data   : " + this.$data);
               console.log("%c%s", "color:red","message: " + this.message);
        },
        beforeDestroy: function () {
            console.group('beforeDestroy 销毁前状态===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);   
               console.log("%c%s", "color:red","data   : " + this.$data);
               console.log("%c%s", "color:red","message: " + this.message);
        },
        destroyed: function () {
            console.group('destroyed 销毁完成状态===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el); 
               console.log("%c%s", "color:red","data   : " + this.$data);
               console.log("%c%s", "color:red","message: " + this.message)
        }
    })
	
	
	
	function update(){
		app.message="AAAA"
	}
	
	function delete1(){
		//app.message="AAAA"
		app.$destroy();
	}
	
	
</script>

三级菜单演示案例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		
		<script type="text/javascript" src="node_modules/axios/dist/axios.js"></script>
		<script src="node_modules/vue/dist/vue.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="node_modules/jquery/dist/jquery.js"></script>
		<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css">
		<script src="node_modules/bootstrap/dist/js/bootstrap.js"></script>
		
		<script src="./js/header.js" type="text/javascript" charset="utf-8"></script>
		<script src="./js/foot.js" type="text/javascript" charset="utf-8"></script>
		<script src="./js/navigationElement.js" type="text/javascript" charset="utf-8"></script>
		
		
	</head>
	<body>
		
		<div id="div">
			<form class="form-inline" role="form">
			  <select  style="width: 300px;" class="form-control" v-model="value1"  @change="loadSelect2(value1)">
				  <option value="--请选择--">--请选择--</option>
				  <option  v-bind:value="category.id"    v-for="category in categorys1">{{category.id}}  --  {{category.categoryName}}</option>
			  </select>
			  
			  <select style="width: 300px;"  class="form-control" v-model="value2"  @change="loadSelect3(value1)">
				  <option value="--请选择--">--请选择--</option>
				  <option  v-bind:value="category.id"    v-for="category in categorys2">{{category.id}}  --  {{category.categoryName}}</option>
			  </select>
			  
			  <select style="width: 300px;"  class="form-control" v-model="value3">
				  <option value="--请选择--">--请选择--</option>
			  	  <option  v-bind:value="category.id"    v-for="category in categorys3">{{category.id}}  --  {{category.categoryName}}</option>
			  </select>
			</form>	 
		</div>
		
		<script>
			var vue = new Vue({
				el:"#div",
				data:{
					value1:"",
					value2:"",
					value3:"",
					categorys1:[],
					categorys2:[],
					categorys3:[]
				},
				created() {
					this.loadSelect1(0)
				},
				methods:{
					loadSelect1(parentId){
						this.value1="--请选择--"
						axios.get("http://localhost:8081/getCategorys?parentId="+parentId).then(response => {
							
							this.categorys1 = response.data
							
							
							
						})
					},
					loadSelect2(parentId){
						this.value2="--请选择--"
						axios.get("http://localhost:8081/getCategorys?parentId="+parentId).then(response => {
							this.categorys3 = []
						
							this.categorys2 = response.data
								
						})
					},
					loadSelect3(parentId){
						this.value3="--请选择--"
						axios.get("http://localhost:8081/getCategorys?parentId="+parentId).then(response => {
							this.categorys3 = response.data
						})
					}
				}
			})
			
			
		</script>
		
	</body>
</html>

@Resource
CateGoryMapper cateGoryMapper;
public List<Category> getChildsId(Long parentId){
    List<Category> categories = new ArrayList<Category>();
    if(parentId==0){
        categories = cateGoryMapper.getParents();
    }else{
        Category conditionCategory = new Category();
        conditionCategory.setParentId(parentId);
        categories = cateGoryMapper.getEntitysByEntity(conditionCategory);
    }
    return  categories;
}

有关其他技术学习请进入 juejin.cn/user/175884…