vue.js入门上
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='vue_person'>
<h1>name:{{name}}</h1>
<h1>age:{{age}}</h1>
<h1>{{SayHi()}}</h1>
<!-- 在h1标签中的{{}}是用来输出对象属性和函数的返回值的。 -->
</div>
<script src="vue.min.js"></script>
<script type="text/javascript">
//每个Vue应用都需要通过实例化Vue来实现。
//1、创建Vue实例
//var MyInfo = { name: "stephen", age: "26"}
var vm = new Vue({
el:'#vue_person', //el通常绑定的是一个选择器。
data:{ //data用于定义属性,当前存在name和age这两个属性。
name:"vichin",
age:27,
},
//data:MyInfo,可以使用对象来与vue构造函数中的data进行绑定。
methods:{ //用于定义函数,可以通过return来返回函数值。
SayHi:function () {
return 'Hello World';
}
}
});
//当一个Vue实例被创建时,它向Vue的响应式系统中加入其data对象中能够找到的所有属性,当这些属性的值发生变化的时候,html视图将也会产生相应的变化。
//我们创建的vue对象vm还有一些有用的属性和方法。在使用的时候都以$作为前缀,以便与用户自定义的属性进行区别。
//例如:当我们需要获取到id为vue_person的这个div标签时,
//1、使用js手段:
let jsGetDOM = document.getElementById('vue_person');
//2、使用vue提供的方法
let vueGetDOM = vm.$el;
jsGetDOM===vueGetDOM;//这里返回的是true!!!
//更多属性与方法:https://cn.vuejs.org/v2/api/#vm-data
</script>
</body>
</html>
vue的简单介绍
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>组件的声明周期函数</h1>
<div id="app">
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
let vm=new Vue({
el:"#app",
data:{
num:0
},
beforeCreate: function () {//整个页面创建之前所调用的生命周期函数
console.log('beforeCreate');
},
created: function () {//在Vue实例创建之后所调用的生命周期函数
console.log('Created');
},
beforeMount: function () {//挂载之前所调用的生命周期函数
},
mounted: function () {//挂载之后所调用的生命周期函数
},
beforeUpdate: function () {//在数据更新之前所调用的生命周期函数
},
updated: function () {//在数据更新之后,DOM更新之后所要调用的生命周期函数
},
beforeDestroy: function () {
},
destroyed: function () {
},
watch: {
num: function () {//监听器
console.log('变量num的值发生了变化');
}
}
});
vm.$watch('num', function (newVal, oldVal) {//观察变量num在修改前后的值
console.log(newVal, oldVal);
});
</script>
</body>
</html>
Vue中的声明周期函数
vue中的指令:
指令后的(双)引号内的代码,都是JS的表达式。
<child v-bind:content="hello world"></child> 写法是错误的,因为不会有变量叫做hello world,如果要想向子组件child中传入字符串,正确的写法是:<child content="hello world"></child>
若是向子组件传递其他类型的参数,可以使用v-bind指令,因为=号后面的(双)引号后跟的是JS表达式。
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-model指令的使用。</h1>
<h2> v-model指令可以使vue实例中的数据与html标签中的文本内容进行关联,当html标签中的文本内容发生变化时,vue实例中的数据也会随之发生变化。当实例中的数据发生变化时,html标签中的文本也会随之发生变化。(适用于 需要以数据驱动 从而生成的页面)
</h2>
<h3 style='color: red'>v-model指令用于带有value值的标签,例如:input select textarea</h3>
<div id="app">
<p>{{msg}}</p>
<input type="text" v-model='msg' />
</div>
<script src="vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:"Hello World"
}
});
</script>
</body>
</html>
v-model
v-if和v-show指令在效果上是一致的,但是具体到细节上的区别是:
1、v-if会将不符合条件的html标签给注释掉,而v-show是使用css样式 dispaly:none。
2、基于上面的性质;v-if有更高的切换消耗,而v-show有更高的初始渲染消耗。若需要频繁的切换,可以使用v-show。如果在运行时条件不大可能改变的,则使用v-if较好
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-show指令的使用。</h1>
<!-- v-if指令,常用于添加删除元素 -->
<div id="app">
<p v-show='show'>my name is vichin</p>
<p v-show='hide'>my name is stephen</p>
<p><label v-if="age < 18">未</label><label>成年</label></p>
<!-- v-if后面可以放一个表达式,因为age是大于18的,所有条件不成立,所有‘未’字不显示出来。 -->
</div>
<script src="vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
show:true,
hide:false,
age:27
}
});
</script>
</body>
</html>
v-show
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-if指令的使用。</h1>
<!-- v-if指令,常用于添加删除元素 -->
<div id="app">
<p v-if='show'>my name is vichin</p>
<p v-if='hide'>my name is stephen</p>
<p><label v-if="age < 18">未</label><label>成年</label></p>
<!-- v-if后面可以放一个表达式,因为age是大于18的,所有条件不成立,所有‘未’字不显示出来。 -->
</div>
<script src="vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
show:true,
hide:false,
age:27
}
});
</script>
</body>
</html>
v-if
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-else指令的使用。</h1>
<!-- v-else指令需要配合v-if或者v-else-if来使用。 -->
<div id='app'>
<p>
<lable>vicin今年的年龄是:{{age}}。</lable>
<label v-if="age < 18">不属于</label>
<!-- 如果v-else不是紧跟着v-if来用的,就会报编译错误! -->
<label v-else>属于</label> <!-- v-else的使用 -->
<label>成年人</label>
</p>
</div>
<script type="text/javascript" src="vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
show:true,
hide:false,
age:27
}
});
</script>
</body>
</html>
v-else
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-else-if指令的使用。</h1>
<div id='app'>
<p>输入的成绩对应的等第是:</p>
<p v-if='score >= 90'>优秀</p>
<p v-else-if='score >= 75'>良好</p>
<p v-else-if='score >= 60'>及格</p>
<p v-else>不及格</p>
<input type="text" v-model='score' />
</div>
<script type="text/javascript" src="vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
score:85
}
});
</script>
</body>
</html>
v-if、v-else-if、v-else综合使用
v-for的优先级别高于v-if之类的其他指令。
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-for指令的使用。</h1>
<!-- 适用于基于数据渲染一个列表,类似于JS中的遍历。其数据类型可以是Array、Object、number、string
该指令必须使用特定的语法(item、index) in items,为当前遍历元素提供别名。 -->
<div id='app'>
<!-- 遍历数组 -->
<p v-for="(score,index) in scores" v-bind:key="index">
<!--不建议使用index来作为key,因为可能会存在些许性能影响。建议使用后台传过来的数据中的主键来作为key,(硬要用的话,也没问题) -->
<label>第{{index + 1}}名分数是:</label><label>{{score}}</label>
</p>
<!-- 遍历一个对象 -->
<p v-for="e in employee" v-bind:key="key">
{{e}}
</p>
<!-- 遍历一个string -->
<p v-for="str in weather">
{{str}}
</p>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
//在vue中,建议使用push pop shift unshift splice sort reverse等方法来操作数组,这样数组产生的变化才会影响DOM。
//vm.$set(vm.scores,0,80) 或者Vue.set(vm.scores,0,80) 也可以让DOM发生变化。更改scores的引用也可以!
scores: [95, 85, 75, 65],
//当需要往这个对象中添加一个属性的时候,我们直接用employee.address='SZ'是不会影响DOM的,需要将整个employee这个对象所指的那个引用进行更改,
//即:vm.employee={ name: 'vichin', age: 18, sex: 'M', address:'SZ' }
//或者使用Vue.set(vm.employee,'address','SZ')//通过set方法,向vm.employee这个对象添加一个属性,值为SZ。
//vm.$set(vm.employee,'address','SZ')
employee: { name: 'vichin', age: 18, sex: 'M' },
weather: 'TodayIsSoCold'
}
});
</script>
</body>
</html>
v-for指令
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-for指令的使用。</h1>
<div id='app'>
<table>
<thead>
<tr><th>姓名</th><th>年龄</th><th>性别</th></tr>
</thead>
<tbody>
<tr v-for="p in persons">
<td>{{p.name}}</td>
<td>{{p.age}}</td>
<td>{{p.sex}}</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
persons:[
{name:"vichin",age:18,sex:"M"},
{name:"stephen",age:19,sex:"M"},
{name:"james",age:20,sex:"M"},
{name:"wade",age:21,sex:"M"}
]
}
});
</script>
</body>
</html>
v-for指令demo
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>v-text、v-html指令的使用。</h1>
<div id='app'>
<p v-text="msg">p标签中,原文本</p>
<!-- 使用v-text指令,会将标签中原文本给替换掉 -->
<div v-html="htmlContent"></div>
<!-- 向页面输入html标签 -->
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:"Today is so cold",
htmlContent:"<input type='date' />"
}
});
</script>
</body>
</html>
v-text、v-html
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.active{
background-color: orangered;
font-size: 20px;
color: #fff;
}
</style>
</head>
<body>
<h1>v-bind指令的使用。</h1>
<h2>动态绑定一个或多个特性、或一个组件prop到表达式,v-bind指令可以再其名称后面带一个参数,中间用一个冒号隔开。这个参数通常是HTML元素的特性。
例如:
绑定属性: v-bind:src='../img/pic.png' 可以缩写成::src="../img/pic.png"
绑定一个类:v-bind:class="{red:isRed}" 或 :class="[classA,classB]"
绑定样式 v-bind:style="{font-size:size+'px'}" 或 :style="[styleObjectA,styleObjectB]"
绑定一个有属性的对象,比如:v-bind="{id:someProp,'other-attr':otherProp}"
</h2>
<div id='app'>
<!-- 绑定一个属性,imgSrc是一个变量-->
<img v-bind:src="imgSrc" v-bind:id='fontColor' v-bind:alt="alt">
<!-- 给标签动态绑定类 -->
<p v-for="(college,index) in colleges" :class="index === activeIndex ? 'active' : ''">
{{college}}
</p>
<!-- <div v-bind:class='[isActive?"active":"",isGreen?"green":""]'>样式绑定(支持多个,当isActive为true的时候,active样式就会生效)</div> -->
<div v-bind:class='{active:isActive,green:isGreen}'>样式绑定(支持多个,当isActive为true的时候,active样式就会生效)</div>
<!-- 绑定样式 -->
<p v-bind:style='{color:fontColor}'>Today is so cold</p>
<div v-bind:style="{color:fontColor,background:isGreen?'#FF0000':'',fontSize:'50px'}">绑定内联样式</div>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
imgSrc:".../img/pic1.png",
alt:"我是天才",
colleges:[
'清华大学',
'北京大学',
'南京大学',
'浙江大学'
],
activeIndex:2,
fontColor:"blue",
isActive:true,
isGreen:false
}
});
</script>
</body>
</html>
v-bind
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.active{
background-color: orange;
font-size: 20px;
color: #fff;
}
</style>
</head>
<body>
<h1>v-on指令的使用。</h1>
<!-- 动态的绑定一个或多个特性,或一个组建prop到表达式;其作用和v-bind类似。注意:如果用在普通元素上时,只能监听原生DOM事件;但是如果用在自定义元素组件上时,也可以监听子组建触发的自定义事件。
常用修饰符:
.stop---调用event.stopPropagation()。停止冒泡
.prevent---调用event.preventDefault()。停止监听原生事件。
.capture---添加事件侦听器时使用capture模式。
.self---只当事件是从侦听器绑定的元素本身触发时才触发回调
.{keyCode|keyAlias}---只当事件是从侦听器绑定的元素本身触发时才触发回调。
.once---触发一次。 -->
<p>使用手法:</p>
<div id='app'>
<button v-on:click="doThis">方法处理器</button>
<button v-on:click="doThat('hello',$event)">内联语句</button>
<button @click="doThis">缩写</button>
<button @click.stop="doThis">停止冒泡</button>
<button @click.prevent="doThis">阻止默认行为</button>
<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>
<!-- -->
<button @click.stop.prevent="doThis">串联修饰符</button>
<input @keyup.enter="onEnter" value="键式修饰符,键别名" />
<input @keyup.13="onEnter" value="键式修饰符,键代码" />
<button v-on:click.once="doThis">事件只触发一次</button>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:"Today is so cold",
fontColor:'#5CCCFA',
fontWeight:"bold",
fontSize: 30
},
methods:{
doThis(){
console.log(1);
},
onEnter(){
console.log(2)
},
doThat:function (para1,para2) {
console.log(3);
}
}
});
</script>
</body>
</html>
v-on
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
#app{
margin:50px auto;
width: 600px;
}
fieldset{
border: 1px solid orangered;
margin-bottom: 100px;
}
fieldset input{
width:200px;
height: 20px;
margin: 10px 0;
}
fieldset select{
margin: 10px 0;
}
table{
width:600px;
border: 2px solid orangered;
text-align: center;
}
thead{
background-color: orangered;
}
</style>
</head>
<body>
<div id="app">
<!-- 第一部分 -->
<fieldset>
<legend>员工录入系统</legend>
<div>
<span>姓名:</span>
<input type="text" placeholder="请输入姓名" v-model='newEmp.name'/>
</div>
<div>
<span>年龄:</span>
<input type="text" placeholder="请输入年龄" v-model='newEmp.age'/>
</div>
<div>
<span>性别:</span>
<select v-model='newEmp.sex'><option value="M">男</option><option value="F">女</option></select>
</div>
<button @click="createNewEmp()">创建新用户</button>
</fieldset>
<!-- 第二部分 -->
<table>
<thead>
<tr>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
<td>删除</td>
</tr>
</thead>
<tbody>
<tr v-for="(p,index) in persons">
<td>{{p.name}}</td>
<td>{{p.age}}</td>
<td>{{p.sex}}</td>
<td><button @click="DelEmp(index)">删除</button></td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
let vm=new Vue({
el:"#app",
data:{
persons:[
{name:"vichin",age:27,sex:"M"},
{name:"stephen",age:28,sex:"M"},
{name:"james",age:29,sex:"M"},
{name:"wade",age:30,sex:"M"}
],
newEmp:{name:"",age:0,sex:"M"}
},
methods:{
createNewEmp(){
if(this.newEmp.name===""){
alert('姓名不能为空!');
return;
}
if(this.newEmp.age<18){
alert('不得录用未成年人!');
return;
}
//往数组中添加一条记录
this.persons.unshift(this.newEmp)
//清空数据,下次再添加的时候,就没有任何关联了
this.newEmp={name:"",age:0,sex:"M"};
},
DelEmp(index){
this.persons.splice(index, 1);
}
}
});
</script>
</body>
</html>
指令小demo(用户管理)
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-once指令与动态组件component</title>
</head>
<body>
<p>component是vue自带的组件,一开始进入页面时,变量type的值是child,这个时候component组件就会去加载child这个组件,当点击按钮将type的值更改为body-content的时候,component组件就会去加载body-content这个组件
</p>
<div id="root">
<component :is="type"></component>
<button @click="handleBtnClick">change</button>
</div>
<script src="vue.js"></script>
<script>
//使用v-once指令会有效的提高一些静态内容的展示性能
Vue.component('child', {
//template: '<div>child</div>'这里不适用v-once指令,当页面显示的内容切换成body-content时,vue会去销毁掉child这个组件,当处于body-content时,再切换回child时,会销毁body-content组件,再重新创建child组件。
template: '<div v-once>child</div>'//使用了v-once指令后,当vue创建好这个组件后,会将该组件进行缓存,当页面从body-content切换回child组件时,会去缓存中获取child组件,而非去重新创建。
});
Vue.component('body-content', {
//template: '<div>body-content</div>'
template: '<div v-once>body-content</div>'
});
var vm = new Vue({
el: '#root',
data: {
type: 'child'
},
methods: {
handleBtnClick: function () {
this.type = this.type === 'child' ? 'body-content' : 'child';
}
},
});
</script>
</body>
</html>
v-once指令与动态组件component
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>计算属性</h1>
计算属性顾名思义就是这个属性是通过计算得来的,所以在调用的时,在插值表达式中使用了reserve,而并不是reserver(),这样的一个方法的调用形式。
当页面重新渲染的时候(不是刷新页面),计算属性所依赖的变量(在这里所依赖的属性是lastname和firstname)没有发生任何改变时,该计算属性的结果不会发生变化,直接读取缓存使用。
当属性需要较大的计算或改变频率较低的时候,推荐使用计算属性。
而method是当页面重新渲染的时候(页面元素data变化,页面就会重新渲染),都会调用method
<div id="app">
<p>初始值:{{lastname}}</p>
<p>翻转值:{{reserveStr()}}</p>
<p>计算属性:{{reserve}}</p>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
lastname: "vichin",
firstname: 'wei'
},
methods: {
reserveStr() {
return (this.lastname + " " + this.firstname).split("").reverse().join('');
}
},
computed: {
reserve: function () {
return this.lastname + " " + this.firstname;
}
// reserve: {
// get: function () {
// return (this.lastname + " " + this.firstname).split("").reverse().join('');
// },
// set: function (value) {//当设置这个计算属性的值的时候,set方法就会被执行。在控制台中输入vm.reserve='stephen',会打印出stephen123
// console.log(value + "123");
// }
// },
//计算选项,默认只有get方法。get方法return值
// reserve() {
// return (this.lastname + " " + this.firstname).split("").reverse().join('');
// },
}
});
</script>
</body>
</html>
计算属性
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>全局组件</title>
</head>
<body>
<h1>全局组件</h1>
<div id="app">
<my-date v-bind:para='1' >
<h3>向插槽内写入信息,如果组件中的slot标签去除,那么这段文字将不会显示</h3>
</my-date>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
//1、创建实例
let vm=new Vue({
el:"#app"
});
//2、创建组件构造器
let profile=Vue.extend({
//模板选项
//使用slot标签声明一个插槽,在使用组件的时候,可以向插槽内输入想要的内容。
template:`<div><p v-on:click='Clickme'>今天是过了大雪了!</p><slot></slot></div>`,
props:['para'],//使用props来接收父组件传递的参数。
methods:{
Clickme:function () {
console.log(this.para);
}
}
});
//3、注册一个组建
Vue.component('my-date',profile);
</script>
</body>
</html>
全局组件
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>组件参数校验</title>
</head>
<body>
<div id='app'>
<child :content="'123456'"></child>
<child content='vichin'></child>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
Vue.component('child', {
//props: ['content'],//最基础的接收参数的方法。
props: {
//content: String//定义接受到的参数必须为string类型的。
// content: [String, Number] 接收到的参数可以是String类型,也可以是Number类型。
content: {
type: String,
required: true,//调用子组件时,必须要传递content参数
default: 'default value',
validator: function (value) {
return value.length > 5;
}
}
},
template: '<div>{{content}}</div>'
});
var vm = new Vue({
el: '#app'
});
</script>
</body>
</html>
组件参数校验
使用is属性指定名称来解决模板标签出现的bug。ol标签下必须要写li标签,select标签内必须要写option标签,table标签内必须要写tr标签(H5编码规范)
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>document</title>
</head>
<body>
<div id='app'>
<table>
<row></row>
</table>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
Vue.component('row', {
template: "<tr><td>this is a row</td></tr>"
});
var vm = new Vue({
el: '#app'
});
</script>
</body>
</html>
不使用is属性
不使用is属性生成的DOM(tr标签并没有在table标签内)
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='app'>
<table>
<tr is='row'></tr>
</table>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
Vue.component('row', {
template: "<tr><td>this is a row</td></tr>"
});
var vm = new Vue({
el: '#app'
});
</script>
</body>
</html>
使用is属性来解决这一bug
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件传参</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="root">
<!-- 父组件通过属性的形式与子组件进行通信 -->
<!-- 使用v-bind指令声明一个属性叫做count,其值便是父组件要传递给子组件的内容 -->
<counter v-bind:count='0' @addone='addone'></counter>
<!-- 定义一个事件addOne,当事件触发时,调用handleAddOne方法。 -->
<!-- 子组件通过申明props属性来进行接收 -->
<counter v-bind:count='0' @addone='addone'></counter>
<!-- 父组件中,定义一个total -->
<div>{{total}}</div>
</div>
<script type="text/javascript">
// 定义一个局部组件
var counter={
props:['count'],//接收一个叫做count的内容。
template:'<div v-on:click="handleClick">{{number}}</div>',//使用mustache语法调用接收到的内容。
methods:{
handleClick:function () {
//this.count++;这里子组件不能随意的去修改父组件传递过来的参数。(Vue的单向数据流)
this.number+=1;
this.$emit('addone', 1);//使用$emit方法让子组件触发一个名叫addOne的事件。并让子组件传递一个参数1,告诉父组件,每次自增为1。(可以传递多个参数,只要以逗号分隔开来即可。)
}
},
data:function(){
return {
number:this.count
}//因为不能该父组件中的参数,所有可以声明一个参数为number,来接收传递过来的参数。
}
}
var vm=new Vue({
el:'#root',
data:{
total:0
},
components:{
counter:counter//注册局部组件
},
methods:{
addone:function(para){
this.total+=para;
}
}
})
</script>
</body>
</html>
使用局部组件和指令,完成一个点击计数的功能
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model='todovalue'/>
<button v-on:click='Addcontent'>提交</button>
<ul>
<!-- 向组件中传入参数,参数名称叫做content,值是从for循环中取出的item -->
<!-- 向组件中传入参数,参数名称叫做index,值是for循环时的索引 -->
<!-- 声明一个自定义事件,事件名叫subitem,当该事件被触发时,调用实例中的Subitem方法。 -->
<todoitem v-bind:content='item' :index='index' v-for='item,index in list' v-on:subitem='Subitem'></todoitem>
</ul>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
//创建一个全局组件
Vue.component('todoitem',{
props:['content','index'],//接收叫做content的内容
template:'<li v-on:click="click_item" >{{content}}</li>',
methods:{
click_item:function () {
this.$emit('subitem',this.i);
}
},
data:function(){
return {
item:this.content,
i:this.index
}
}
});
var vm=new Vue({
el:'#app',
data:{
list:[],
todovalue:''
},
methods:{
Addcontent:function () {
if (this.todovalue) {
this.list.push(this.todovalue);
this.todovalue='';
}
},
Subitem:function(para){
this.list.splice(para,1);
}
}
});
</script>
</body>
</html>
使用全局组件和指令,完成一个todolist
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>组件的使用</h1>
<div id="app">
<parent></parent>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
//1、子组件构造器
let child=Vue.extend({
template:`<label>子组件1</label>`
});
let child1=Vue.extend({
template:`<label>子组件2</label>`
});
//2、父组件构造器
Vue.component('parent',{
components:{
'my-child':child,
'my-child1':child1
},
template:
`
<div><my-child></my-child><my-child1></my-child1></div>
`
});
let vm=new Vue({
el:"#app"
});
</script>
</body>
</html>
父子组件
组件通信:
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>多层组件通信</h1>
<!-- 父组件在div中的实际使用 -->
<div id="app">
<!-- 调用最外层组件,传递title和img信息给最外层的这个组件(通过vue实例) -->
<my-parent :imgtitle="title" :imgsrc="img"></my-parent>
</div>
<!-- 声明子组件1,用于存放图片 -->
<template id='my_img'>
<img :src="imgsrc" width="200">
</template>
<!-- 声明子组件2,用于存放标题 -->
<template id='my_title'>
<h2>{{title}}</h2>
</template>
<!-- 声明一个父组件 -->
<template id='my_parent'>
<div>
<child1 :imgsrc="imgsrc"></child1>
<child2 :title="imgtitle"></child2>
</div>
</template>
<script src="vue.min.js"></script>
<script type="text/javascript">
//1、子组件实例化
let Child1=Vue.extend({
template:"#my_img",//将组件与模板相关联
props:['imgsrc']
});
let Child2=Vue.extend({
template:"#my_title",//将组件与模板相关联
props:['title']
});
//2、注册父组件
Vue.component('my-parent',{
props:['imgtitle','imgsrc'],
components:{
'child1':Child1,
'child2':Child2
},
template:'#my_parent'
});
声明一个Vue实例
new Vue({
el:'#app',
data:{
title:'葫芦奶娃',
img:'05.jpeg',
}
});
</script>
</body>
</html>
vue多层组件之间的通信
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>使用观察者模式(bus总线,发布订阅模式),来解决非父子组件的传值问题</title>
</head>
<body>
<div id="root">
<child content='dell'></child>
<child content='lee'></child>
</div>
<script src="vue.js"></script>
<script>
// 首先,声明一个Vue的实例,并将值赋值给bus。在后面再次实例化Vue对象的时候,这些对象都会有bus这个属性,并且这些属性都指向了同一个Vue对象。
Vue.prototype.bus = new Vue();
Vue.component('child', {
data:function(){
return {
content_:this.content
};
},
template: '<div @click="handleClick">{{content_}}</div>',
props: {
content: String
},
methods: {
handleClick: function () {
this.bus.$emit('change', this.content_);//bus指向了一个Vue的实例,所以是存在$emit这个方法。
}
},
mounted: function () {//生命周期函数,当该组件被挂载的时候,执行。
var _this = this;//下面的function内,this的作用域会发生变化,所以声明一个实例来指向原先this所指的引用。
this.bus.$on('change', function (msg) {//与$emit事件一样,this.bus也有on事件,用该事件去监听change事件。
_this.content_ = msg;
});
},
});
var vm = new Vue({
el: '#root'
});
</script>
</body>
</html>
非父子组件的传值
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>使用自定义事件,让子组件的信息传递给父组件</h1>
每个Vue实例都实现了时间接口;
使用$on(eventName)监听事件。
使用$emit(eventName)触发事件。
父组件可以在使用了子组件的地方直接使用v-on(或者是@)来监听子组件的触发。
<!-- 父组件在div中的实际使用 -->
<div id="app">
<my-btn @total="allcounter()"></my-btn><!-- 这里使用@total来监听total方法,没执行一下total方法后就执行一下alcounter方法 -->
<my-btn @total="allcounter()"></my-btn>
<my-btn @total="allcounter()"></my-btn>
<p>一共点击了{{totalcounter}}次</p>
</div>
<!-- 声明子组件 -->
<template id='my_btn'>
<button @click="total()">点击{{counter}}次</button>
</template>
<script src="vue.min.js"></script>
<script type="text/javascript">
//注册按钮
Vue.component('my-btn',{
template:'#my_btn',
data(){
return {
counter:0
}
},
methods:{
total(){
this.counter++;
// 通知外界,此方法被调用了
this.$emit('total');
}
}
});
// 声明一个Vue实例
new Vue({
el:'#app',
data:{
totalcounter:0
},
methods:{
allcounter(){
this.totalcounter ++;
}
}
});
</script>
</body>
</html>
使用自定义事件,让子组件的信息传递给父组件
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>匿名slot(插槽————感觉有点想占位符)</h1>
<!-- 父组件在div中的实际使用 -->
<div id="app">
<my-slot>
<img src="05.jpeg" width="200" />
</my-slot>
</div>
<template id='my_slot'>
<div id='panel'>
<h2 class="panel-header">插槽头部</h2>
<!-- 预留一个插槽 -->
<slot>插槽默认显示</slot><!-- 这里的slot可以代替任何一个标签,我们在使用的时候,传入div,它就会变成div标签。传一个label就会变成lable标签,如果我们什么都不传,默认显示显示slot标签内的内容 -->
<footer>插槽尾部</footer>
</div>
</template>
<script src="vue.min.js"></script>
<script type="text/javascript">
Vue.component("my-slot",{
template:'#my_slot'
});
// 声明一个Vue实例
new Vue({
el:'#app',
data:{
totalcounter:0
},
methods:{
allcounter(){
this.totalcounter ++;
}
}
});
</script>
</body>
</html>
匿名slot
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>实名slot(插槽————感觉有点想占位符)</h1>
<div id="app">
<my-student>
<span slot='user_name'>vichin</span>
<span slot='user_age'>27</span>
<div slot='user_sex'>male</div>
</my-student>
</div>
<template id='my_student'>
<div id='main'>
<slot name='user_name'>姓名插槽</slot>
<slot name='user_age'>年龄插槽</slot>
<slot name='user_sex'>性别插槽</slot>
</div>
</template>
<script src="vue.min.js"></script>
<script type="text/javascript">
Vue.component("my-student",{
template:'#my_student'
});
// 声明一个Vue实例
new Vue({
el:'#app',
data:{
totalcounter:0
},
methods:{
allcounter(){
this.totalcounter ++;
}
}
});
</script>
</body>
</html>
具名插槽slot
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>具名插槽</title>
</head>
<body>
<div id="root">
<child>
<h3>vichin</h3>
</child>
<hr>
<body-content>
<div slot='header'>header</div>
<div slot='footer'>footer</div>
</body-content>
</div>
<script src="vue.js"></script>
<script>
Vue.component('child', {
template: '<div><p>hello</p><slot>default value</slot></div>'
});
Vue.component('body-content', {
template: '<div><slot name="header"></slot><div>content</div><slot name="footer"></slot></div>'
});
var vm = new Vue({
el: '#root'
});
</script>
</body>
</html>
具名插槽slot1
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue-router(用于组件之间的过渡、切换)</title>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<style>
body{
background-color: #e8e8e8;
}
</style>
</head>
<body>
<div id="app">
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<div class="page-header">
<h1>
IT666
</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 使用router-link来导航
通过传入to属性来指定链接
router-link默认会被渲染成一个a标签 -->
<router-link class='list-group-item' to='/h5'>HTML5</router-link>
<router-link class='list-group-item' to='/php'>php</router-link>
<router-link class='list-group-item' to='/java'>java</router-link>
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- 路由出口 -->
<!-- 将路由匹配到的组件渲染在这里 -->
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
<!-- 创建模块 -->
<template id='h5'>
<div><h2>HTML5</h2>
<p>新热点</p>
<div>
<ul class="nav nav-tabs">
<router-link to='/h51'>基础班</router-link>
<router-link to='/h52'>进阶版</router-link>
</ul>
<div class="tab-content">
<router-view></router-view>
</div>
</div>
</div>
</template>
<template id='h51'>
<div><h3>HTML5基础</h3>
<p>这是会讲解基础的一些信息</p>
</div>
</template><template id='h52'>
<div><h3>HTML5进阶</h3>
<p>这里会阐述进阶的一些信息</p>
</div>
</template>
<template id='php'>
<div><h2>php</h2>
<p>拍黄片</p>
</div>
</template>
<template id='java'>
<div><h2>java</h2>
<p>扎哇</p>
</div>
</template>
<script src="vue.min.js"></script>
<script type="text/javascript" src="Vue-router.js"></script>
<script type="text/javascript">
//1、创建组件
const HTML5=Vue.extend({
template:'#h5'
});
const HTML51=Vue.extend({
template:'#h51'
});
const HTML52=Vue.extend({
template:'#h52'
});
const php=Vue.extend({
template:'#php'
});
const java=Vue.extend({
template:'#java'
});
//2、定义路由
const routes=[
// 一级路由的配置
{
path:'/h5',
component:HTML5,
children:[//配置二级路由
{path:'/h51',component:HTML51},
{path:'/h52',component:HTML52},
{path:'/',redirect:'/h51'}
]
},
{path:'/php',component:php},
{path:'/java',component:java},
// 配置根路由
{path:'/',redirect:'/h5'}
]
//3、创建路由实例
const router=new VueRouter({
routes//使用ES6语法(对象结构)
});
//4、创建Vue实例,并与元素进行绑定
new Vue({
router
}).$mount('#app')
</script>
</body>
</html>
Vue-router
菜鸟教程上的demo
class和style的高级用法,其中showWarning和mix是vue实例下的一个方法,warning是vue实例下的一个对象。
以vue结尾的文件叫做单文件组件。
模板放在template标签内,行为放在script标签内,样式放在style标签内。
首次运行项目,先进入到文件夹 cd travel。然后再使用命令 npm run dev
启动一个项目使用npm run start
停止一个服务npm travel clear
在vue项目中进行页面跳转不适用a标签,而是使用<router-link to='/list'>标签。to后面表示要跳转的页面。项目中是跳转到list这个页面。
npm install fastclick --save 将fastclick这个包安装到项目的依赖之中,不管是在开发环境之中,还是在打包生成线上版本的代码都需要使用fastclick(会将版本信息写道package.json文件里的dependencies节点)
在style标签中使用scoped属性,可以让style标签中的样式只能应用于本组件中<style lang='stylus' scoped></style>
安装axios: npm install axios --save
在使用:style="{font-weight:fontWeight(实际这的值是一个bold)}"给标签增加样式时,发现运行不了,后来将font-weight改写成fontWeight之后,就可以正常运行了。是不是在vue中,不支持横杠的出现?
在使用父子组件的时候,<div><my-child></my-child><my-child1></my-child1></div>,如果将my-child和my-child1这两个组件分别放在两个div中,那么就会只显示第一个组件,第二个组件并不显示。(<div><my-child></my-child></div><div><my-child1></my-child1></div>)
父组件标签中,不能单独使用子组件的标签,如若想用,必须重新在外部注册成另外一个组件
以上是 vue.js入门上 的全部内容, 来源链接: utcz.com/z/378887.html