1. 0 mvvm 思想
- M:即Model,模型,包括数据和一些基本操作
- V: View,视图,页面渲染结果
- VM: View-Mode ,模型与视图间的双向操作(无序开发人员干涉)
在MWM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到View中。而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中.
而MVVM中的VM要做的事情就是把DOM操作完全封装起来,开发人员不用再关心Model和View之间是如何互相影响的:
2. 0 Vue简介
Vue(读章/viu:/,类似于view)是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也元全能够为复杂的单页应用提供驱动。
官网: https://cn.vuejs.org/
参考: https://cn.vuejs.org/v2/guide/
Git地址: https://github.com/vuejs
尤雨溪,Vue.js创作者,Vue Technology创始人,致力于Vue的研究开发。
3. 0 入门简介
在vs code中打开一个空文件夹,打开控制台
$ npm init -y
$ npm install vue
- 创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板,响应式的
- 指令来简化对don的一些操作
- 声明式方法来做更复杂的操作,methods 封装方法
<body>
<div id="app">
<input type="text" v-model="num">
<button v-on:click="num++">点赞</button>
<button v-on:click="cancle">取消</button>
<h1> {{name}}xxx.有{{num}}个人给唱衰他</h1>
</div>
<script src="./vue/dist/vue.js"></script>
<script>
//1. vue 声明式渲染
let vm =new Vue({
el: "#app", //绑定元素
data: { //封装数据
name:"张三",
num:1
},
methods:{ //封装方法
cancle(){
this.num --;
}
}
});
</script>
</body>
3.1 插值表达式,v-text,v-html
<div id="app">
<!-- 插值表达式,写在标签体里,但在浏览器显示时 不友好 -->
{{msg}} {{hello()}} {{1+1}} <br/>
<span v-html="msg"></span>
<br/>
<span v-text="msg"></span>
</div>
<script src="../vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data:{
msg:"<h1>Hello</h1>"
},
methods:{
hello(){
return "world"
}
},
})
</script>
3.2 v-bind: , v-model:
<!-- 给html 标签的属性绑定,v-bind: 单向绑定 -->
<div id="app">
<a v-bind:href="link">gogogo</a>
<!-- class style : 简写-->
<span v-bind:class="{active:isActive,'text-danger':hasError}"
:style="{color: c1,fontSize:size}">你好</span>
</div>
<script src="../vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
link: "https://www.baidu.com",
isActive: true,
hasError: true,
c1: 'red',
size:'33px'
}
})
</script>
<!-- v-model 双向绑定,
表单项,自定义组建 -->
<div id="app">
精通的语言:<br>
<input type="checkbox" v-model="language" value="Java">Java<br>
<input type="checkbox" v-model="language" value="PHP">PHP<br>
<input type="checkbox" v-model="language" value="Python">Python<br>
选中了{{language.join(",")}}
</div>
<script src="../vue/dist/vue.js"></script>
<script>
let vm =new Vue({
el: "#app",
data: {
language:[]
}
})
</script>
3.3 v-on 事件绑定 @click=""
在事件处理程序中调用‘event.preventDefault()或‘event.stopPropagation()是非常常见的 需求。
尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理DOM事件细节。
为了解决这个问题,Vue.js为'v-on'提供了事件修饰符。修饰符是点开头的指令后缀来表示的。
- .stop:阻止事件冒泡到父元素
- .prevent:阻止默认事件发生
- .capture:使用事件捕获模式
- .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
- .once:只执行一次
<!-- v-on 双向绑定,@click="" -->
<div id="app">
<button v-on:click="num++">点赞</button>
<button @click="cancle">消</button>
<h1>有{{num}}个赞,</h1>
<!-- 事件 修饰符 @click.stop="hello" @click.prevent="hello" -->
<div style="border: 1px solid red;padding: 20px;" v-on:click.once="hello">
大
<div style="border: 1px solid bisque;padding: 20px;" @click.stop="hello">
小DIV <br>
<a href="https://www.baidu.com" @click.prevent.stop="hello">去百度</a>
</div>
</div>
<!-- 按键修饰符 -->
<input type="text" v-model="num" v-on:keyup.up="num+=2" @keyup.down="num-=2" @click.ctrl="num+=10">
</div>
<script src="../vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
num: 1
},
methods: {
cancle() {
this.num--;
},
hello() {
alert("点击了");
}
},
})
</script>
3.4 v-for
<div id="app">
<ul>
<li v-for="(user,index) in users" :key="index">
<!-- 1、显示user信息:v-for="item in items" -->
当前索引:{{index}}-- {{user.name}} ===>{{user.gender}} ==>{{user.age}}
<!-- 2、获取数组下标:v-for=" (item,index) in items" -->
<!-- 3、遍历对象:
v-for="value in object"
v-for=" (value,key) in object"
v-for=" (value,key,index) in object"
-->
<br>
对象信息: <br>
<span v-for="(item, key,index) in user">{{key}}==>{{item}}==>{{index}};</span>
<!--4、遍历的时候都加上:key来区分不同数据,提高vue渲染效率-->
</li>
</ul>
</div>
<script src="../vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
users: [{ name: "柳岩", gender: "女", age: 21 },
{ name: "张三", gender: "男", age: 12 },
{ name: "范冰冰", gender: "女", age: 34 },
{ name: "刘亦菲", gender: "女", age: 24 },
{ name: "古力娜扎", gender: "女", age: 24 },
]
}
})
</script>
3.5 v-show,v-if,v-else-if,v-else
<div id="app">
<button @click="show = !show">点我呀</button>
<!-- 1.使用v-if 显示 -->
<h1 v-if="show">if==看到我==</h1>
<!-- 2.使用v-show 显示 -->
<h1 v-show="show">show =看到我</h1>
</div>
<li v-for="(user,index) in users" :key="index" v-if="user.gender == '女'">
3.6 计算属性和监听器
<div id="app">
<!-- 某些结果是基于之前数据实时计算出哎的,计算属性来 -->
<ul>
<li>西游记;价格:{{xyjPrice}},数量:<input type="number" v-model="xyjNum"></li>
<li>水浒传;价格:{{shzPrice}},数量:<input type="number" v-model="shzNum"></li>
<li>{{totalPrice}}</li>
{{msg}}
</ul>
</div>
<script src="../vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
xyjPrice:99.98,
shzPrice:98.00,
xyjNum:1,
shzNum:1,
msg:""
},
computed: {
totalPrice(){
return this.xyjNum*this.xyjPrice+this.shzNum*this.shzPrice;
}
},
//watch 可以让我们监控一个值的变化,从而做出相应的反应
watch: {
xyjNum:function(newVal,oldVal){
if(newVal>=3){
this.msg="库存超出限制";
this.xyjNum=3;
}else{
this.msg="";
}
}
},
})
</script>
3.7 过滤器
<!-- 过滤器常用来处理文本格式化的操作,用在: 双花括号插值,和v-bind 表达式 -->
<div id="app">
<ul>
<li v-for="user in userList">
<!-- {{user.id}}==>{{user.name}}==>{{user.gender==1?"男":"女"}} -->
{{user.id}}==>{{user.name}}==>{{user.gender| genderFilter}}==>{{user.gender| gFilter}}
</li>
</ul>
</div>
<script src="../vue/dist/vue.js"></script>
<script>
// 全局过滤
Vue.filter("gFilter", function (val) {
if (val == 1) {
return "男";
} else {
return "女";
}
})
let app = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: "jacky", gender: 1 },
{ id: 2, name: "老马", gender: 0 }
]
},
filters: { //局部过滤器
genderFilter(val) {
if (val == 1) {
return "男";
} else {
return "女";
}
}
}
})
</script>
4. 0 组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。
例如可能会有相同的头部导航。但是如果每个页面都独自开发,这无疑增加了我们开发的成本。
所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
在vue里,所有的wue实例都是组件
<div id="app">
<button @click="count++">我被点击{{count}} 次</button>
<counter></counter>
<button-counter></button-counter>
</div>
<script src="../vue/dist/vue.js"></script>
<script>
//1.全局声明注册一个组建
Vue.component("counter", {
template: `<button @click="count++">我被点击{{count}} 次</button>`,
data() { //2.
return {
count: 1
}
},
});
//局部声明一个组件
const buttonCounter = {
template: `<button @click="count++">我被点击{{count}} 次</button>`,
data(){
return{
count:2
}
}
}
new Vue({
el: "#app",
data: {
count: 1
},
components:{
"button-counter":buttonCounter
}
})
</script>
- 组件其实也是一个Vue,实例,因此它在定义时也会接收:data、methods、生命周期函数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
- 但是组件渲染需要html,模板,所以增加了template属性,值就是HTML模板
- 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了
- data必须是一个函数,不再是一个对象。
5.0 生命周期钩子函数
每个Vue实例在被创建时都要经过一系列的初始化过程∶创建实例,装载模板,渲染模板等等。
Vue为生命周期中的每个状态都设置了钩子函数(监听函数)。每当Vue,实例处于不同的生命周期时,对应的函数就会被触发调用。
生命周期:你不需要立马弄明白所有的东西。
<div id="app">
<span id="num">{{num}}</span>
<button @click="num++">赞!</button>
<h2> {{name}},有{{num}}个人点赞</h2>
</div>
<script src="../vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
name: "张三",
num: 100
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
}
},
beforeCreate() {
console.log("========beforeCreate=====");
console.log("数据模型未加载:" + this.name, this.num);
console.log("fang方法未加载:" + this.show());
console.log("html模板未加载: " + document.getElementById("num"));
},
created() {
console.log("========Create=====");
console.log("数据模型加载:" + this.name, this.num);
console.log("fang方法加载:" + this.show());
console.log("html模板加载: " + document.getElementById("num"));
console.log("html模板还未渲染: " + document.getElementById("num").innerText);
},
beforeMount() {
console.log("========beforeMount=====");
console.log("html模板还未渲染: " + document.getElementById("num").innerText);
},
mounted() {
console.log("========Mounted=====");
console.log("html模板已渲染: " + document.getElementById("num").innerText);
},
beforeUpdate() {
console.log("========beforeUpdate=====");
console.log("数据模型已更新:" + this.num);
console.log("html模板未更新: " + document.getElementById("num").innerText);
},
updated() {
console.log("========updated=====");
console.log("数据模型已更新:" + this.num);
console.log("html模板已更新: " + document.getElementById("num").innerText);
}
});
</script>
6.0 使用Vue脚手架进行模块化开发
1. npm install webpack -g
2. npm install -g @vue/cli-init
全局安装vue脚手架
3. 初始化vue项目
vue init webpack appname:vue脚手架使用webpack模块初始化一个appname项目
- 如提示vue 不是内部指令,说明没有将vue.cmd 添加到用户的环境变量中,一般是:
C:\Users\用户名\AppData\Roaming\npm\node_modules@vue\cli-init\node_modules.bin
4.启动vue项目
项目的package.json 中有scripts,代表我们能运行的命令
npm start =npm run dev :启动项目
![news_20191112_2](https://img-blog.csdnimg.cn/20200916160025360.png)
=========index.html
<div id="app"></div>
=========src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
<!--xx.vue文件,写模式是:
<template></template>
<script></script>
<style></style>
-->
====Hello.vue 自己写的===
<template>
<div>
<h1> 你好,Hello ,{{name}}</h1>
</div>
</template>
<script>
export default {
data() {
return {
name: "张三"
}
},
}
</script>
<style></style>
====写好后注册到router/index.js中 写router地址===
{
path:'/hello',
name: "Hello",
component:Hello
}
====在 src/App.vue 的路由视图下展示==
<template>
<div id="app">
<img src="./assets/logo.png" />
<router-link to="/hello">去hello</router-link>
<!-- 路由视图 -->
<router-view />
</div>
</template>