MVVM模式
- M:即Model,模型,包括数据和一些基本操作
- V:即View,视图,页面渲染结果
- VM:即View-Model,模型与视图间的双向操作(无需开发人员干涉,由框架来完成)
Vue概念
一套用于构建用户界面的渐进式框架,Vue被设计为自底向上逐层应用,Vue的核心库只关注视图层。不仅易于上手,还便于与第三方库或既有项目整合,另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue也完全能够为复杂的单页应用提供驱动
官网:https://cn.vuejs.org/
参考:https://cn.vuejs.org/v2/guide
Node和NPM
npm是Node提供的模块管理工具,就像maven工具,可以非常方便的下载安装很多前端框架,包括Jquery,AngularJS,Vuejs都有
1. 下载安装
1.1 下载Node.js
下载地址:https://nodejs.org/en/
1.2 npm改淘宝镜像
npm install nrm -g
下载nrm- npm下载不了就直接
npm config set registry https://registry.npm.taobao.org
然后执行最后一步 nrm ls
查看所有镜像nrm use taobao
改为淘宝镜像npm config get registry
验证一哈
2. 使用npm搞一个最简单的vue工程
- 在工程根目录,终端输入
npm init -y
- 同样目录
npm install vue --save
- 在页面引入vue
<script src="./node_modules/vue/dist/vue.js"></script>
<html lang="en">
<head>
<script src="./node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>大家好,我{{name}}</h1>
</div>
</body>
<script>
const app = new Vue({ //初始化一个vue实例
el: "#app", //element 选择器
data: { //定义数据模型
name: "zhangsan"
}
})
</script>
</html>
3. Vue基础语法入门
当Vue实例被创建时,它会尝试获取在data中定义的所有属性,用于视图的渲染,并且监视data中的属性变化,当data发生改变,所有相关的视图都将被重新渲染,这就是“响应式”系统
3.1 {{}} 插值表达式
可以写js语法也可以写js内置函数和自定义函数,但是要有返回值
<h1>大家好,我{{name}}</h1>
3.2 v-text和v-html单向绑定 替代{{}}
插值表达式会有插值闪烁的问题,用这两个可以用默认值的方式来解决
<h1>大家好我是 <span v-text="name">张学友</span></h1>
<h1>大家好我是 <span v-html="name">张学友</span></h1>
3.3 v-model 双向绑定数据(表单元素)
<input type="text" v-model="name">
<!-- 复杂情况 -->
<div id="app">
<input type="checkbox" value="ios" v-model="language">ios<br>
<input type="checkbox" value="java" v-model="language">java<br>
<input type="checkbox" value="php" v-model="language">php<br>
您选择了{{language.join(",")}}
</div>
<script>
const app = new Vue({
el: "#app",
data: {
language: []
}
})
</script>
3.4 v-on:事件名(简写 @事件名) 事件绑定
可以直接绑定js代码也可以绑定方法,方法中用this就可以操作数据
<input type="button" value="点我呢哇" v-on:click="num++">
<input type="button" value="点我呢哇" @click="incr()">
3.5 事件修饰符
.stop
阻止事件冒泡到父元素.prevent
阻止默认事件发生.capture
使用事件补货模式.self
只有元素自身触发事件才执行.once
只执行一次
<input type="button" value="禁用默认事件" @contextMenu.prevent="incr()">
3.6 按键事件
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
.13
也是回车.65
是A键,以此类推A~Z
<input type="text" v-model="num" @keyup.enter="submit()">
3.7 组合按键
<input type="text" v-model="num" @keyup.alt.67="submit()">
3.8 v-for遍历数组/对象
<ul>
<li v-for="(user,index) in users" :key="index">{{index}} - {{user.name}} - {{user.age}}</li>
<li v-for="(val,key,index) in user" :key="index">{{index}} - {{key}} - {{val}}</li>
</ul>
3.9 v-if和v-show
当所得到的的结果为true时,所在的元素才会被渲染,区别就是v-show会被渲染,但是加了style="display:none"
,v-if不会被渲染,效率更好
<input type="button" value="点我看" @click="show=!show">
<span v-if="show">我if出来了</span>
<span v-show="show">我show出来了</span>
<!-- else-if和else必须紧跟if或者else-if -->
<input type="button" value="点我随机数" @click="random=Math.random()">{{random}}
<span v-if="random > 0.75">我大于0.75</span>
<span v-else-if="random > 0.5">我大于0.5</span>
<span v-else>我啥也不是</span>
3.10 v-bind (简写 : ) html属性不能用{{}}绑定,只能用v-bind
<input type="text" v-model="store">
<input type="button" value="变颜变色" v-bind:class="{active : store>0}">
3.11 computed 计算属性
const app = new Vue({
el: "#app",
data: {},
methods: {
birth(){
return this.birth1;
}
},
computed: {
birth1(){
const date = new Date(this.birthday);
return date.getFullYear()+ "年" + date.getMonth() + "月" + date.getDay() +"日"
}
}
})
3.12 watch监听
watch: {
search(val1,val2){ //search 监听哪个变量就叫啥
console.log(val1,val2) //val1新值 val2旧值
}
},
4. Vue生命周期钩子
Vue实例在被创建的时都要经过一系列初始化过程:创建实例,装载模板,渲染模板等。Vue为每个状态都设置了钩子函数(监听函数),每当Vue实例处于不同的生命周期时,对应的函数就会被触发调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D53vIvsY-1574665742940)(./images/lifecycle.png)]
- beforeCreate
- created 可以在这个时候发送ajax到后台请求数据
- beforeMounte
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
const app = new Vue({
el: "#app",
data: {
name: "zhangsan"
},
methods: {},
created(){
this.num = 10000;
},
monted(){}
})
5. 组件化
在vue里,所有的vue实例都是组件
5.1 全局组件
<body>
<div id="app">
<counter></counter>
</div>
</body>
<script>
Vue.component("counter", {
template: "<button @click='num++'>点我加1 {{num}}</button>",
data() { //组件数据是函数,保证组件的复用
return {
num: 0
}
},
})
const app = new Vue({
el: "#app"
})
</script>
5.2 局部组件
<body>
<div id="app">
<hello1></hello1>
</div>
</body>
<script>
const hello = {
template: "<div>打个招呼: 我思{{name}}</div>",
data() {
return {
name: "张三"
}
},
}
const app = new Vue({
el: "#app",
components: {
hello1 : hello // 组件名 : 组件对象
}
})
</script>
5.3 组件间通信(父向子,子向父)
- 父组件使用子组件时,自定义属性(属性名任意,属性值为要传递的数据)
- 子组件通过props接收父组件数据,通过自定义属性的属性名
<body>
<div id="app">
<!-- 通过自定义属性名传递给子组件 -->
<counter :num1="num"></counter>
</div>
</body>
<script>
Vue.component("counter", {
template: "<button @click='num1++'>点我加1 {{num1}}</button>",
props:["num1"] //子组件接收,num1可以正常使用
/*props:{ //高级应用,添加约束 做验证
num1: {
type:Number, //String Boolean Array Object
default: 0
}
}*/
})
const app = new Vue({
el: "#app",
data: {
num: 0
}
})
</script>
- 子向父没法直接传,所以传一个父的方法,可以改父的数据模型
<body>
<div id="app">
<!-- 自定义事件名 incr1 -->
<counter @incr1="incr()"></counter>
</div>
</body>
<script>
Vue.component("counter", {
template: "<button @click='subIncr'>点我加1</button>",
methods: {
subIncr(){
this.$emit("incr1");
}
},
})
const app = new Vue({
el: "#app",
methods: {
incr(){
this.num ++;
}
},
})
</script>
6. 路由 vue-router 实现多组件的跳转
- 引入vue-router组件
- 实例化vue-router
- 引入到vue实例中,通过router
- 放置锚点
- 显示页面
<!-- 导入js vue.js vue-router.js login.js register.js -->
<body>
<div id="app">
<span><router-link to="/login">登录页</router-link></span>
<span><router-link to="/register">注册页</router-link></span>
<hr>
<router-view></router-view>
</div>
</body>
<script>
const router = new VueRouter({
routes: [
{
path: "/login", // 路由路径,必须以“/”开头
component: loginForm
},
{
path: "/register",
component: registerForm
}
]
})
const app = new Vue({
el: "#app",
router
})
</script>
- 例: 登录组件(.js)
const loginForm = { //  一个汉字 一个空格   半个汉字
template: `
<div>
<h1>登录页</h1>
用户名:<input type="text"><br>
密 码:<input type="password"><br>
<input type="button" value="登陆">
</div>
`
}