Vue.js
1.简介
vue介绍:vue是一个兴起的前端js库,是一个精简的MVVM。从技术角度讲,Vue.js 专注于 MVVM 模型的 ViewModel 层。它通过双向数据绑定把 View 层和 Model 层连接了起来,通过对数据的操作就可以完成对页面视图的渲染。当然还有很多其他的mvmm框架如Angular,React都是大同小异,本质上都是基于MVVM的理念。 然而vue以他独特的优势简单,快速,组合,紧凑,强大而迅速崛起
官方在线文档:https://cn.vuejs.org/v2/guide/index.html
了解Vue.js :https://www.cnblogs.com/Renyi-Fan/p/9419742.html#_label0_18
作为兴起的框架,Vue.js抛弃了对IE8的支持,移动端支持安卓4.2+ 和IOS7+
在使用之前首先需要导入Vue.js的库:<script src="js/vue.js"></script>
Vue.js的Hell word:
记住一点,写有Vue语句的script放在html代码的下面,否则不会实现效果
<div id="app">{{message}}</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello world'
}
});
</script>
将js中message的值替换到了HTML模版中{{message}}中
特性1:数据绑定
H1显示的内容绑定你文本框中内容 v-model为数据绑定组件
一切使用vue从 new Vue开始,这一步不可缺少
<div id="app">
<h1>Your input is {{message}}</h1>
<input type="text" v-model="message">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello world'
}
});
</script>
特性2:组件化(自定义HTML标签)
<div id="app">
<message content="Hello World"></message>
</div>
<script>
var Message = Vue.extend({
props: ['content'],
template: '<h1>{{content}}</h1>'
});
Vue.component('message', Message);
var vm = new Vue({
el: '#app',
});
</script>
- 基础特性
2.1实例及选项
Vue.js的使用都是通过构造函数Vue{{option}}创建一个Vue的实例:
Var vm=new Vue({}).一个Vue实例相当于一个MVVM模式中的ViewModel,如图:
在实例化时我们可以传入一个选项对象,包含数据,模版,挂载元素,方法,生命周期钩子等选项.
2.1.1模版
选项中主要影响模版或DOM的选项有el和template,属性replace和template需要一起使用
el:类型为字符串,DOM元素或函数,例如el:’#app’ 在初始项中指定了el,实例将立即进入编译过程
template:类型为字符串.默认将template值替换挂载元素(el值对应的元素).例子如下:
<div id="app">
<p>123</p>
</div>
<script id="tpl" type="x-template">
<div class="tpl">
<a>This</a>
</div>
</script>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
template:'#tpl'
})
</script>
页面显示的只有This,原因就是因为用#tpl的内容把#app给代替了.
2.1.2 数据
Vue.js通过data属性定义数据 使用data的注意事项:1.data的值必须是一个函数,并且返回值是原始对象
2.data中的属性和props中的不能重名.
var data={a:1}
var vm=new Vue({
data:data
})
vm.$data===data//true
vm.a===data.a//true
//设置属性会影响到原始数据
vm.a=2
data.a//2
//反之亦然
data.a=3
vm.a//3
自定义一个标签,然后给标签定义属性 解析:
My-component是标签名 ,props用来绑定属性,data定义数据,给desc赋值为123,template为模版,具体表名标签的内容.
<div id="app">
<my-component title="myTitle" content="myContent"> </my-component>
</div>
<script>
var Mycomponent = Vue.component('my-component', {
props: ['title', 'content'],
data: function () {
return {
desc: '123'
}
},
template: '<div><h1>{{title}}</h1><p>{{content}}</p><p>{{desc}}</p></div>'
})
new Vue({
el:'#app'
})
</script>
2.1.3方法
我们可以通过属性methods对象来定义方法,并且使用v-on指令来监听DOM事件,例如:
<div id="app">
<button v-on:click="alert">alert</button>
</div>
<script>
new Vue({
el:'#app',
data:{a:1},
methods:{
alert:function () {
alert(this.a)
}
}
})
</script>
2.1.4生命周期
2.2数据绑定
Vue.js的核心是一个响应式的数据绑定系统,建立绑定后,DOM将和数据保持同步,无需手动维护DOM,是代码简洁易懂.
2.2.1数据绑定语法
v-bind:id可以简写为:id,这时中间的div的id为id-1,span标签显示的值为names的数值
<div id="app">
<span v-once="name">{{names}}</span>
<div v-bind:id="'id-'+id"></div>
</div>
var vm = new Vue({
el: '#app',
data: {
id: 1,
index: 0,
name: 'vue',
avatar: 'http://...',
count: [1, 2, 3, 4, 5],
names: ['vuel.0', 'vue2.0'],
items: [
{name: 'vue1.0', version: '1.0'},
{name: 'vue1.0', version: '1.0'}
]
}
});
在{{}}中的数据能使用表达式,但是每个绑定值只能使用单个表达式,不支持正则表达式
{{index==0?'a':'b'}}<br>
{{index+1}}<br>
{{name.split('').join('|')}}
指令
格式:v-
- 参数
<img v-bind:src=”avatar”/>
指令v-bind可以在后面带一个参数,用冒号(:)隔开,src即参数.此时img标签中的src会与vm实例中的acatar绑定,等同于<img src=”{{acatar}}”>
- 修饰符
以半角句号.开始的特殊后缀,用于表示指令应该以特殊方式绑定.
<button v-on:click.stop=”doClick”></button>
v-on的作用是在对应的DOM元素上绑定事件监听器doClick为函数名,stop为修饰符,作用是停止冒泡,相等于调用了e.stopPropagation()
2.2.2计算属性
1.computed为计算,它生产了一个对象 fullname的对象,这个对象将 vm这个Vue对象中的data中的两个数值相加,this指的是当前的Vue对象.
<div id="app">
<p>{{firstname}}</p>
<p>{{lastname}}</p>
<p>{{fullname}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstname: 'Gavin',
lastname: 'GLY'
},
computed: {
fullname: function () {
return this.firstname + '' + this.lastname
}
}
});
</script>
当你在浏览器中的控制台输出vm.firstname=’xxx’的时候,将会把fullname和firstname的值都改变
2.Setter
页面显示为1.00,这种方式能处理价格能避免前后端数据类型转换产生的问题
在更改vm.price=2,vm.cents会更新为200,传给后端就无需转换数据
<div id="app">
<p>{{price}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
cents: 100,
},
computed: {
price: {
set: function (newValue) {
this.cents = newValue * 100;
}, get: function () {
return (this.cents/100).toFixed(2);
}
}
}
})
</script>
2.2.3表单控件
v-model代表当前标签绑定一个值,绑定的值显示的就是这个标签当前的状态
<div id="app">
<!--text 用户输入和显示一致-->
<input type="text" v-model="message">
<span>输入为:{{message}}</span>
<!--Radio 单选框--><br>
<label><input type="radio" value="male" v-model="gender">男</label>
<label><input type="radio" value="female" v-model="gender">女</label>
<p>{{gender}}</p>
<!--Checkbox 单选--><br>
<input type="checkbox" v-model="checked">
<span>checked:{{checked}}</span>
<!--多选--><br>
<label><input type="checkbox" value="1" v-model="multiChecked">1</label>
<label><input type="checkbox" value="2" v-model="multiChecked">2</label>
<label><input type="checkbox" value="3" v-model="multiChecked">3</label>
<p>multiChecked:{{multiChecked.join('|')}}</p>
<!--select 单选--><br>
<select v-model="selected">
<option >A</option>
<option >B</option>
<option >C</option>
</select>
<span>selected:{{selected}}</span>
<!--多选--><br>
<select v-model="multiselected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select><br>
<span>multiselected:{{multiselected}}</span>
<!--绑定value 选中的话checked的值为a,未选中的话就是b-->
<input type="checkbox" v-model="checked" v-bind:true-value="a" v-bind:false-value="b">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
a:'123',
b:'321',
message: '',
gender: '',
checked: '',
multiChecked: [],
selected: '',
multiselected: []
}
});
</script>
2.2.4Class与Style绑定
1.Class绑定
语法:v-bind:class接收参数是一个对象,可以和普通的class属性共存
这样一个标签它的class属性就会有多个:
除了对象绑定还有下面的数组绑定[classA,classB]
<div id="app">
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
<div v-bind:class="[classA,classB]"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
hasError: false,
classA: 'class-a',
classB: 'class-b'
}
})
</script>
2.内联样式绑定
对象语法:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">123</div>
vue对象中的data语法:
activeColor: 'red',
fontSize: 30
或者直接绑定:
<div v-bind:style="styleObject">312</div>
data内:
styleObject:{
color:'red',
fontSize:'30px'
}
数组语法: 数组中的值需要和上方的styleObject格式一致,标明属性和属性值
<div v-bind:style="[styleObject,styleObject2]">123</div>
V-bind:style可以简写为:style
2.3模版渲染
v-if=”true” 类似<c:if>标签 可以和v-else一起使用,但是必须要放在一起使用,不符合条件的内容不会显示在源代码中
v-show=”true” 类型v-if可以和v-else一起使用,不符合条件的只是会隐藏,源代码可见
v-else 同上
v-for=” 变量名 in 数组或集合 ” 类似foreach循环 主要用于列表渲染,例如:
<div id="app">
<ul>
<li v-for="item in items">
<h3>{{item.title}}</h3>
<p>{{item.description}}</p>
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
items: [
{title: 'title-1', description: 'description-1'},
{title: 'title-2', description: 'description-2'},
{title: 'title-3', description: 'description-3'},
{title: 'title-4', description: 'description-4'},
]
}
});
</script>
如果想的到循环的次数的话v-for=”(item,index) in items” index就是循环次数
也可以充当for循环使用 v-for=”n in 5”
2.3.4template标签用法
template也支持v-for template的作用可以将指令作用到多个兄弟DOM元素上.
<div id="app">
<template v-if="true">
<p v-if=”false”>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
</template>
</div>
<script>
new Vue({
el: '#app',
data:{
yes:false
}
})
</script>
2.4事件监听和绑定
v-on监听DOM事件 v-on:click可以简写为@click
当你点击say的时候它会跳出弹窗,methods是用来定义方法的,方法名在前方法在后,中间用:隔开 function后面的括号中也可以加入参数
<div id="app">
<button v-on:click="say">say</button>
</div>
<script>
new Vue({
el:'#app',
data:{
msg:'hello vue.js'
},
methods:{
say:function () {
alert(this.msg)
}
}
})
</script>
获取原生DOM事件对象:
<div id="app">
<button v-on:click="say">say</button>
<button v-on:click="say($event)">showsay</button>
<button v-on:click="say()">say</button> 这个不可实现
</div>
<script>
new Vue({
el: '#app',
methods: {
say: function (even) {
console.log(even);
}
}
})
</script>
2.5 Vue.extend()
组件化开发,将一个页面看成一个大的根组件,里面包含的元素就是不同的子组件,子组件也可以在不同的根组件里被调用.一个页面通常声明一个Vue的实例new Vue({})作为根组件.
Vue.js提供了可被重复使用的子组件:Vue.extend(options)方法,创建基础Vue构造器的’子类’,参数options对象和直接声明Vue实例参数对象基本一致,使用方法如下: 具体看第6章
3.指令
v-bind 用于动态绑定DOM元素属性,元素实际的值是由vue实例中的data属性提供的.
v-model 2.2.3中已经说明,该指令主要用于input ,select ,textarea标签中,具有trim修饰符
v-if/v-else/v-show
v-for 在2.0中大致包含了以下几个方面:
1.参数顺序变化
当包含index或key时,对象参数改为(item,index)或(value,key),这样与js array对象的新方法forEach和map,一些迭代器的参数保持一致.
v-on 事件绑定 v-on:click可以简写为@click 在2.0中v-on只监听自定义事件,即用$emit触发的事件,如果要监听原生事件,需要修饰符.native 如:v-on:click.native
v-text 参数类型为字符串,作用是更新元素的textContent. {{}}文本插值本身也会编译成textNode的一个v-text指令,但是v-text需要绑定在某个元素上 如果直接使用{{msg}}的话在生命周期beforeCompile期间,此刻的msg数据还没有编译到{{msg}}中,有一瞬间会显示
但是如果用了v-text就不会出现这种情况.
v-HTML参数类型为字符串 接收的字符串不会进行编译等操作按普通的HTML处理.同v-text一样,也要绑定到某个元素上才不会出现闪现的情况.
v-pre 跳过编译这个元素和子元素,显示原始的{{}},用来减少编译时间
<div id="app">
<div v-pre>{{un}}</div>
</div>
<script>
new Vue({
el:'#app',
data:{
un:'this is an'
}
})
</script>
v-cloak 想当与在元素上加了一个[v-cloak]的属性,知道关联的实例结束编译.可以和css规则[v-cloak]{display:none}一起使用,可以隐藏未编译的Mustache标签直到实例准备完毕.例如:
<div v-cloak>{{msg}}</div>
v-once 标明元素或者组件只渲染一次,随后绑定数据发送的变化不会影响到.最大的提升了更新行为页面的性能.
3.2自定义指令基础
<div id="container">
<p>{{msg}}</p>
<!-- 准备实现需求:
在h1标签上面,加上一个按钮,当点击按钮时候,对count实现一次
自增操作,当count等于5的时候,在控制台输出‘it is a test’-->
<button @click="handleClick">clickMe</button>
<h1 v-if="count < 6" v-change="count">it is a custom directive</h1>
<h1 v-change-background-color="myBgColor" >it is a header1</h1>
</div>
<script>
// bind 指令在绑定到元素要执行的操作
// update如果在调用指令时候,传了参数,当参数变化时候,就会执行update所指定的方法
// unbind解绑要执行的操作
//directives 定义自定义指令
new Vue({
el: '#container',
data: {
msg: 'Hello Vue',
count:0,
myBgColor:'#ff0000'
},
methods:{
handleClick: function () {
//按钮单击,count自增
this.count++;
}
},
directives:{
change:{
bind: function (el,bindings) {//bindings为指令的参数
console.log('指令已经绑定到元素了');
console.log(el);
console.log(bindings);
//准备将传递来的参数
// 显示在调用该指令的元素的innerHTML
el.innerHTML = bindings.value;
},
update: function (el,bindings) {
console.log('指令的数据有所变化');
console.log(el);
console.log(bindings);
el.innerHTML = bindings.value;
if(bindings.value == 5)
{
console.log(' it is a test');
}
},
unbind: function () {
console.log('解除绑定了');
}
}, changeBackgroundColor: {
bind: function (el, bindings) {
console.log('in bind ');
console.log(bindings.value);
el.style.backgroundColor = bindings.value;
}
}
}
})
</script>
3.4 指令在2.0的变化
新的钩子函数componentUpdated,当整个组件都完成了update状态后即所有的DOM都更新后调用该钩子函数,无论指令接受的参数是否发生变化.
在2.0中取消了指令实例这一概念,即在钩子函数中的this不能指向指令的相关属性.指令的相关属性都通过参数的形式传递给钩子函数.
- 指令绑定bind函数执行后不直接调用update函数
- 只要组件发生重绘,无论指令接受的值是否发生变化,都会调用update函数,如果要过滤不必要的更新,可以使用
binding.value=binding.oldValue来判断
钩子函数接受的参数binding对象为不可更改,强行设定binding.value的值并不会引起实际的改动,如果一定要用这种方式修改的话,通过el直接修改DOM元素
5.过渡
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-active {
opacity: 0
}
</style>
<body>
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
<script>
new Vue({
el: '#demo',
data: {
show: true
}
})
</script>
过渡就是通过操作改变标签的CSS样式,(2.x版本和1.x版本差异过大,请知晓)
详情了解:https://www.jb51.net/article/108616.htm
6.组件
<div id="app">
<my-button/>
</div>
<script>
let myButton = Vue.extend({//创建一个组件构造器
template: `<button>点击我</button>`
})
Vue.component('my-button', myButton)//注册组件,并指定组件的标签,组件的HTML标签为<my-button>
let app = new Vue({//创建Vue实例,注意实例化vue对象时要在注册组件之后
el: '#app'
});
</script>
注册组件还可以写成:Vue.component('my-button', { template: `<button>点击我</button>` })
创建这样一个简单的组件并不是很困难的事情,重点是是要理解怎么创建组件
· Vue.extend()是Vue构造器的扩展,调用Vue.extend()创建的是一个组件构造器
· Vue.extend()构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML,简单的理解这个属性用来定义组件的模板(也就是组件的HTML结构)
· 使用Vue.component()注册组件,在注册组件时需要提供两个参数,第一个参数是组件的标签,比如上例中的my-button,第二个参数是组件构造器,比如上例中的myButton
· 组件应该挂载到某个Vue实例下,否则它不会生效。这一点需要特别的注意。另外同一个组件可以同时挂载到多个Vue实例下
以上代码为全局注册,
局部注册:,该组件只能在对应的Vue实例中使用,如果别的Vue实例调用该组件,将会报一个提示错误
只需要再实例化Vue的时候使用
let app = new Vue({
el: '#app',
components: {
'my-button': myButton
}
})
这样的话这个组件就只能在id为app的标签内使用.
总结:
· 通过Vue.component(tagName, options)注册全局组件,可以在任何Vue实例范围中使用
· 通过Vue实例的components属性注册局部组件,只能在该实例范围中使用
传入Vue构造器的多数选项也可以用在Vue.extend()或Vue.component()中,不过有两个特列:data和el。Vue规定:
在定义组件的选项时,data和el选项必须使用函数。
组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件A在它的模板中使用了组件B。它们之间必然需要相互通信:父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告诉父组件
在Vue中,父子组件的关系总结为prop向下传递,事件向上传递。父组件通过prop给子组件下发数据,子组件通过事件给父组件发送消息。
示例:
<div id="app">
<my-search>
</my-search>
</div>
<script>
let myButton = Vue.extend({ // 构造子组件
template: '<button>Search</button>'
}) // 构造父组件
let mySearch = Vue.extend({ // 在父组件mySearch中使用<my-button>标签
template: '<div><label for= "search"> Search the site </label>'+
'<input type = "search" name = "search" id = "search" placeholder = "Enter keyword"/> ' +
'<my-button/></div>',
components: {
'my-button': myButton//局部注册myButton组件只能在mysearch中使用
}
});
Vue.component('my-search', mySearch);//注册全局组件mysearch
let app = new Vue({
el: '#app',
data: {}
})
</script>
· 先使用Vue.extend()定义了一个myButton组件构造器和mySearch组件构造器
· components: {'my-button', myButton}将myButton组件注册到mySearch组件,并将myButton组件的标签设置为my-button
· 在mySearch组件内通过template标签,定义了搜索表单mySearch组件所需要的模板,并且引用了myButton组件
· Vue.component('my-search', mySearch)全局注册mySearch组件
· 在页面中使用my-search标签,挂截到app实例中,渲染整个mySearch组件,其子组件myButton也将被渲染出来
7.Vue常用插件
首先去https://unpkg.com/vue-router@3.0.1/dist/vue-router.js,然后Ctrl+s保存下来js文件,使用时和jquery是一样,直接引用, 详情学习v-router文档:https://router.vuejs.org/zh/guide/#html
代码例子:
<div id="app">
<h1>Hello App!</h1>
<p><!-- 使用 router-link 组件来导航. --><!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p><!-- 路由出口 --><!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
<script>// 1. 定义 (路由) 组件。// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. 定义路由// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器, 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 创建 router 实例,然后传 `routes` 配置 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
// 4. 创建和挂载根实例。 记得要通过 router 配置参数注入路由, 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
</script>
关于更多了解情况请见:https://router.vuejs.org/zh/guide/#html
vue的ajax请求 :axios
文档:https://www.jianshu.com/p/7a9fbcbb1114
let params=new URLSearchParams();
params.append("limit","20");
params.append("name","张三");
axios.post('studentaction.action?methodName=find',params).then(function (value) {
console.log(value.data);
})
Vuex教程:https://vuex.vuejs.org/zh/guide/