介绍
-
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
-
MVVM模式的实现者(Vue实现DOM监听与数据绑定)
-
View是视图层,也就是用户界面。前端主要由HTML和CSS来构成,为了更方便地展现ViewModel或者Model层的数据。
-
Model是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则。在Vue表示JavaScript对象
-
ViewModel由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者从后端获取得到Model数据进行转换出来,做二次封装,以生成符合View层使用预期的视图数据模型。视图状态和行为都封装在ViewModel里。这样的封装使得ViewModel可以完整地去描述View层。
-
-
Vue七大属性
-
el –element 选择器:
通过el指定vm1所管理的view的位置,相当于一个容器,跟上面的div id = "app"做关联,从此以后上面div id = "app"里面的内容要通过vue来渲染,都要经过vue处理才能看得到上面div里面的内容
-
data属性:
用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在data中。
-
methods属性:
放置页面中的业务逻辑,js方法一般都放置在methods中,用来写方法,函数的
-
template属性
用来设置模板,会替换页面元素,包括占位符。
-
render属性
创建真正的Virtual Dom
-
computed属性
用来计算,根据已经存在的属性计算出新的属性,对于同样的数据,会缓存。当其依赖属性的值发生变化是,这个属性的值会自动更新,与之相关的DOM部份也会同步自动更新。其实一般情况,我也会把一些关于逻辑的代码都写在computed中。
-
watch侦听属性
监听data中数据的变化,两个参数,一个返回新值,一个返回旧值 当你有一些数据需要随着其它数据变动而变动时或者执行异步操作或开销较大操作时,建议使用watch
-
-
computed和watch是有区别的
-
watch: 监视,能够监听到数据的变化,只要数据变化的时候,都会自定执行对应的方法,其中可以检测的数据来源分为三部分 data , computed , props computed: 计算属性,存在一个计算缓存的特性,每一次计算之后,只要里面的逻辑不发生变化,每一次重复调用,都会使用上一次执行的结果,能够节省计算的时间
-
入门案例
-
引入vue.js
-
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
-
-
搭建helloword
-
<div id="app" >
{{message}}
</div>
<script src="https://lib.baomitu.com/vue/2.6.12/vue.min.js"></script>
<script>
var app=new Vue(
{ el:"#app",
data:{
message:"hello,vue"
}
}
)
</script>
-
vue指令
-
v-for 循环
-
v-if v-else 条件判断 移除标签
-
v-bind 绑定标签属性 比如动态绑定id值 v-bind:src="" => :src=""
-
v-on 事件处理,监听dom事件 v-on:click="" =>@click=""
-
v-mode 表单输入绑定
-
v-show 通过样式的display控制标签的显示
computed 和 watch
-
初始化显示/相关data改变执行
<div id="app">
<input type="text" v-model="xing">
<input type="text" v-model="ming">
<input type="text" v-model="name">
<input type="text " v-model="name2">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
xing: "niu",
ming:"mingyuan",
name2:""
},
computed:{
name(){
return this.xing+" "+this.ming; //方法返回值作为属性!!!
}
},
//配置监视xing的变化
watch:{
xing:function(value){
this.name2=value+" "+this.ming;
}
}
});
vm.$watch('ming',function(value){
this.name2=this.xing+" "+value;
});
</script>
-
set/get
get() 回调函数(你定义的,你没有调用但执行了)计算并返回当前属性的值
set(value) 回调函数 当属性值发生改变是回调 更新相关的属性数据
格式:
computed:{
name3:{
get(){
},
set(){
}
}
},
强制Class 和Style绑定
-
:class="变量名" 动态
-
:class=" '类名' " 静态
-
:class="{类名:Boolean类型变量}" true 表示类名添加 false 表示类名移除
-
:style="key:value,color:color1" 属性名:变量名
条件渲染
-
v-if / v-else 删除dom元素
-
v-show 改变style的display的属性
列表渲染
遍历数组
<div id="for">
<ul >
<li v-for="(person,index) in persons" :key="index" >
{{index}}------{{person.name}}---{{person.age}}------
<button @click="del(index)">删除</button>
<button @click="upd(index)">更新</button>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm2 = new Vue({
el: "#for",
data: {
persons: [
{name:"niuniu",age:18},
{name:"huahua",age:16},
{name:"lala",age:19}
]
},
methods: {
del(index){
this.persons.splice(index,1);
},
upd(index){
// this.persons[index]={name:"aaaaa",age:18};
this.persons.splice(index,1,{name:"aaaaa",age:18})
}
},
});
</script>
-
vue 本身只监视属性的改变,没有监视内部变化
// this.persons[index]={name:"aaaaa",age:18}; 这个方法 改变了 persons指向的数组的内部数据 但实际上persons指向的地址是不发生变化的因此他不会更新界面
-
this.persons.splice(index,1) 这个更新了界面是因为 vue对数组的方法进行了重写
重写方法的内部包括:原方法的内容+更新界面方法 因此调用了这些方法 界面数据会改变
遍历对象(很少使用了解)
v-for="(item,key) in persons[1]" item 属性值 key属性名
搜索过滤
<div id="for">
<input type="text" v-model="searchname">
<ul >
<li v-for="(person,index) in newpersons" :key="index" >
{{index}}------{{person.name}}---{{person.age}}------
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm2 = new Vue({
el: "#for",
data: {
searchname:"",
persons: [
{name:"niuniu",age:18},
{name:"huahua",age:16},
{name:"lala",age:19}
]
},
computed:{
newpersons(){
//filter 监听一个数组返回一个满足条件的新数组
//indexOf返回参数中字符串在原字符串的下标 如果没有找到 返回值为-1
return this.persons.filter(item=>item.name.indexOf(this.searchname)!==-1);
}
}
});
</script>
排序
-
<div id="for">
<ul>
<li v-for="(person,index) in newpersons" :key="index">
{{index}}------{{person.name}}---{{person.age}}------
</li>
</ul>
<button @click="setSortflag(1)">升序</button>
<button @click="setSortflag(2)">降序</button>
<button @click="setSortflag(0)">正常</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm2 = new Vue({
el: "#for",
data: {
sortflag: 0, //0正常 1升序 2降序
persons: [{
name: "niuniu",
age: 18
},
{
name: "huahua",
age: 32
},
{
name: "lala",
age: 19
}
]
},
methods: {
setSortflag(flag) {
this.sortflag = flag;
}
},
computed: {
newpersons() {
let newperson= this.persons.filter(item=>item.name.indexOf("")!==-1); //每次要更新视图 如果直接赋值是不会更新视图的
let sortflag =this.sortflag;
if (sortflag!== 0) {
newperson.sort( //返回复数p1在前返回正数p2在前
function(p1,p2){
if (sortflag === 1){
return p1.age-p2.age
}else{
return p2.age-p1.age
}
}
)
}
return newperson;
}
}
})
</script>
事件处理
-
绑定事件
-
停止事件冒泡
-
组织事件默认行为
-
按键修饰符
<div id="for">
<!-- 绑定监听 -->
<button @click="test1">事件绑定</button>
<button @click="test2(1)">传递参数</button>
<button @click="test3">无参传递事件</button>
<button @click="test4(123,$event)">带参传递事件</button><br>
<div style="width: 200px; height: 160px; " @click="wout">
<!-- @click.stop 停止事件冒泡 -->
<div style="width: 100px; height: 80px; " @click.stop="win">
</div>
</div>
<!-- 组织事件默认行为 -->
<a href="http:www.baidu.com" @click.prevent="">去百度</a>
<!-- 按键修饰符 @keyup.名称/keycode-->
<input type="text" name="" id="" @keyup.Enter="testkey">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm2 = new Vue({
el: "#for",
methods: {
test1:function(){
alert("事件绑定")
},
test2:function(num){
alert("传递参数"+num)
},
test3:function(event){
alert("无参传递事件"+event.target.innerHTML)
},
test4:function(num,event){
alert("带参传递事件"+num+'------'+event.target.innerHTML)
},
wout:function(){
alert("点击了外部")
},
win:function(){
alert("点击了内部")
},
testkey:function(){
alert("按下enter");
}
},
});
</script>
表单输入绑定
-
@submit
-
@submit.stop 停止事件冒泡
-
@submit.prevent 阻止默认行为
-
<div id="demo">
<form action="" @submit.prevent="login">
账号:<input type="text" name="username" v-model="username"> <br>
密码: <input type="text" name="password" v-model="password"> <br>
性别: <input type="radio" name="sex" value="男" v-model="sex">男
<input type="radio" name="sex" value="女" v-model="sex" >女 <br>
爱好:<input type="checkbox" value="蓝球" name="blueball" v-model="likes">蓝球
<input type="checkbox" value="红球" name="redball"v-model="likes" >红球
<br>
语言: <select name="yuyan" id="" v-model="yyitem">
<option value="">未选择</option>
<option v-for="yy in yys" :value="yy" >{{yy}}</option>
</select><br>
<input type="submit">
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const vm= new Vue({
el:"#demo",
data: {
username:"",
password:"",
sex:"男",
likes:[],
yys:["java","python","c++"],
yyitem:"python"
},
methods: {
login:function(){
console.log(this.username+"---"+this.password+"----"+this.sex+"----"+this.likes+"---"+this.yyitem);
}
},
})
</script>
生命周期
-
初始化钩子函数 mounted 初始化显示后立即被调用
-
销毁前执行 beforeDestory
-
过滤器
<div id="demo">
<p>显示格式化 过滤器</p>
<!-- 绑定过滤器 -->
<p>性别:{{sex | realsex}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
//value 为绑定该过滤器的值 即sex
Vue.filter("realsex",function(value){
return value===1?'男':'女'
})
const vm=new Vue({
el:"#demo",
data:{
sex:1
}
})
</script>
自定义指令
<div id="demo">
<p>自定义指令</p>
<p v-big-text="msg"></p>
{{msg}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script type="text/javascript">
Vue.directive('big-text',function(el,binding){
console.log(el,binding)
//el 就是标签
//binding 内容
// def: {bind: ƒ, update: ƒ}
// expression: "msg"
// modifiers: {}
// name: "big-text"
// rawName: "v-big-text"
// value: "AbcDefG"
// __proto__: Object
//转大写
el.textContent=binding.value.toUpperCase();
})
const vm=new Vue({
el:"#demo",
data:{
msg:"AbcDefG"
},
})
</script>
局部指令
const vm=new Vue({
el:"#demo",
data:{
msg:"AbcDefG"
},
directives:{
lower:function(el,binding){
console.log(binding);
el.textContent=binding.value.toLowerCase();
}
}
})
vue组件
自定义标签
<body>
<div id="app">
<niuniu v-for="item in items" v-bind:a="item"></niuniu>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//组件
Vue.component("niuniu",{
props:['a'],
template:'<li>{{a}}</li>'
});
var demo1=new Vue({
el:"#app",
data:{
items:[1,2,3,4]
},
methods:{
}
})
</script>
</body>
网络通信
axios
<body>
<div id="app">
<div>名字:{{msg.name}}</div>
<div>年龄:{{msg.age}}</div>
<div>主页:{{msg.url}}</div>
<a v-bind:href="msg.url">主页</a>
女朋友:<ul>
<li v-for="item in msg.girlfriends">
{{item}}
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var demo1=new Vue({
el:"#app",
data(){
return{
msg:{
name:null,
age:null,
url:null,
girlfirends:[
]
}
}
},
mounted(){
axios.get("data.json").then((response)=>(this.msg=response.data))
}
})
</script>
</body>
解决网速慢导致先加载模板再出数据
<div id="app" v-cloak>
<style>
[v-cloak]{
display: block;
}
</style>
Vue-router路由
安装 cnpm install vue-router --save-dev
配置router
-
<router-view></router-view> 显示路由跳转的视图
-
<router-link to=""></router-link> 相当于a标签
-
this.$router.push("/content")
this.$router.push({name:'xxx',params:{xx:xx}})
js里 路由跳转函数
嵌套路由
实现视图局部改变
点击导航 内容部分改变 头部和导航栏不发生变化
routes:[
{
path:'/content',
name:'Content',
component:Content,
children:[
{
path:'/member',
name:'shopitem',
component:member
},
{
path:'/shopitem',
name:'shopitem',
component:shopitem
}
]
}
]
参数传递
-
路径匹配
-
方式一
路由: path:'/shopitem/:id' id即为参数
link: to="/shopitem/1"
这样 1 就赋给了 id
{{$route.params.id}}
这样就获取到了参数id -
方式二
路由: path:'/shopitem/:id' id即为参数
link: :to="{name:xxx,params:{id=1}}" name 为路由的名字
这样 1 就赋给了 id
{{$route.params.id}}
这样就获取到了参数id
-
-
props
-
激活props传参方式
{
path:'/shopitem/:id',
name:'shopitem',
component:shopitem,
props:ture 激活props传参
} -
传参
路由: path:'/shopitem/:id' id即为参数
link: :to="{name:xxx,params:{id=1}}" name 为路由的名字
这样 1 就赋给了 id -
获取参数
<template>
<div>
{{id}}
</div>
</template>
<script>
export default {
name:"shopitem",
props:['id']
}
</script>
-
重定向(传参方式与上面一致)
{
path:'/goshopitem',
redirect:'/goshopitem'
}
路由模式与hash模式
-
默认为hash模式 地址栏会显示#
-
路由模式 不带#
export default new VueRouter({
mode:'history', 在路由配置加入这行
404处理
在router配置文件中加入以下代码
{
path:'*',
component:notfound
}
路由钩子+axios
-
路由钩子函数
-
beforeRouterEnter 进入路由前执行
-
beforeRouterLeave 进入路由后执行
-
-
axios (类似ajax)
-
安装 cnpm install axios -s
-
main.js 导入使用
import axios from 'axios'
Vue.prototype.axios=axios; -
export default {
name:"member",
//导航
beforeRouteEnter (to, from, next) {
//to 到达的组件
// from 从哪个组件来
next(vm=>{
this.memberlist();
})
},
methods: {
memberlist:function(){
this.axios({method:'get',url:'xxxxx'}).then((response) => {
console.log(response.data)
})
}
},
}
-
vue-x
-
安装 cnpm install vuex --save
-
main.js里面 导入使用
初始化一个vue项目
-
npm install -g @vue/cli-init
# `vue init` 的运行效果将会跟 `vue-cli@2.x` 相同
vue init webpack my-project
int a; -
cnpm install vue-router --save-dev
-
进入项目目录 执行 cnpm install 导入依赖
浙公网安备 33010602011771号