文章目录
1. Vue
1.1 概念
1.1.1 vue是什么?
Vue.js------ 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和Vue生态系统支持开发复杂单页应用。
- 渐进式:从核心到完备的全家桶
- 增量:从少到多,从一页到多页,从简单到复杂
- 单文件组件: 一个文件描述一个组件
- 单页应用: 经过打包生成一个单页的html文件和一些js文件vue对象与HTML关系
Vue对象与html关系
1.1.2 vue优缺点
- Vue 不缺入门教程,可是很缺乏高阶教程与文档
- Vue不支持IE8
- 量级问题(angular和react)
1.1.3 一个vue页面(在html中)以及插值表达式
按照Vue的语法 {{}}: 插值表达式
插值表达式: 根据表达式的内容 找到’对应的Vue对象’ 的 参数自定义的地方(一般是data),里面 获取对应参数值, 替换 — 运算 -->
引入vue.js最好放在head部分引入(避免页面抖屏)
执行过程:
- 创建了一个Vue对象(根据Vue语法)
- 这个Vue对象一旦创建, 会立即检查 它的el属性
- 他会根据el属性找到一个对应id的html代码
- 如果找到了, 把找到的html代码所对应的作用域 和 这个Vue对象’绑定起来’
- 这个html代码所对应的作用域 就不在仅仅是html代码作用域, 还是这个Vue对象作用域
- 这个作用域代码 会重新, 按照Vue语法再解析一遍
- el data: Vue固有属性
3\18 Lesson5
01_index2.html
下面很重要,入门理解 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
dom解析:是一个从上而下的过程
1, div被解析,{{msg}}只是一个普通的文本,没有任何别的特殊的地方
2, script被解析,创建了一个对象,这个对象是vue对象
3, {{msg}}按照vue语法, 就不再是单纯的文本, 而是叫插值表达式
插值表达式: 是个可以做运算的式子, 参数是在对应的vue对象中取出来的
一般是在对应的vue对象 的data中取出的
<div id="root">
<!-- 插值表达式-->
{{msg}}
<!-- 双向绑定-->
<input v-model="msg">
</div>
<script>
// 创建一个vue对象
dom解析从上而下,解析到这个创建对象的时候
1, 检查这个vue对象的el属性,它会根据el属性所指向的内容,查找对应的html元素
2, 如果找到了这个id相同的html标签/结点/元素, 建立绑定关系(这个vue对象和对应的html域)
3, 那么, 对应html域就不在是单纯的html语法域, 而是vue+html语法域
4, 这个曾经被解析过的html标签域, 会按照vue语法重新再解析一遍
new Vue({
el:"#root",
data: {// 我们自定义一些属性
msg: "123"
}
})
</script>
</body>
</html>
Note:
绑定的vue对象和html域分别是
html域:<div>标签包裹的部分,即插值表达式msg和input标签
<div id="root">
{{msg}}
<input v-model="msg">
</div>
new Vue({
el:"#root",
data: {
msg: "123"
}
})
遇到错误,第一步是打开浏览器的控制台
上面很重要,入门理解 |
3\19 Lesson1
最最常用的2个微指令:单向绑定和双向绑定
1.2 V指令(vue最核心的语法)
前端程序员最常用的3个东西(习惯):index、root、app
V-bind:单向绑定(可简化为:)
用来绑定数据和属性以及表达式
可以简化为一个冒号: 如下等价
<img v-bind:src="msg">
<img :src="msg">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
//Vue对象的作用域就是外层div标签内的部分
<div id="root" >
<img src="1111.png">
<!-- 单向绑定: 把html中的一些属性,绑定一个值(在vue对象中定义的值/参数)-->
<!-- 单向: src 依赖于 url这个参数-->
<!-- <img src="url">是不可以的-->
<img v-bind:src="url">
<!-- 相当于, 从vue对象中取出url的参数, 赋值给这个src属性-->
<!-- 另外, 如果vue对对象中这个url参数一旦改变, 这个src指向内容会跟着改变 -->
<!-- 单向: title 依赖于 msg这个参数-->
<div v-bind:title="msg">
div
</div>
</div>
<script>
new Vue({
el: "#root",
data: {
msg: "zs",
url: '1111.png'
}
})
</script>
</body>
</html>
注:移动到div上面会显示zs
V-model:双向数据绑定(可省略 :value)
双向绑定: 是在单向绑定的基础上, 双向/相互影响
只能用于表单元素的value上
如下等价: (原因是双向绑定只能绑定表单元素的value值)
<input v-model:value="msg">
<input v-model ="msg">
03_双向绑定.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root" >
{{msg}}
<!-- 输入1111.png则显示图片。输入框写图片路径很奇怪。-->
<!-- 因为双向绑定,msg值改变,所有引用msg值的都会跟着改变。-->
<img v-bind:src="msg">
<!-- value 和 msg 相互影响 -->
<!-- 输入导致value改变,value改变则msg改变,msg改变则插值表达式改变-->
<input v-model:value="msg">
</div>
<script>
new Vue({
el: "#root",
data: {
msg: "zs"
}
})
</script>
</body>
</html>
03_双向绑定2.html
<body>
<!-- 3个表单元素:input、textarea、select-option-->
<div id="root" >
{{msg}}
<img v-bind:src="msg">
<img :src="msg">
<!-- value 和 msg 相互影响 -->
<input v-model:value="msg">
<!-- 只能绑定value值,所以可以不写-->
<input v-model ="msg">
<textarea v-model ="msg"></textarea>
<select v-model="msg">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<script>
new Vue({
el: "#root",
data: {
msg: "3"
}
})
</script>
</body>
V-text,V-html:类似更新元素的innerText、innerHtml
类似于innertext innerhtml
<body>
<div id="root">
<div>
{{msg}}
</div>
<hr>
<!-- 不会解析-->
<div v-text="msg"></div>
<!-- 会解析-->
<div v-html="msg"></div>
<hr>
<div v-text="obj.name"></div>
<div v-text="obj.age"></div>
<div v-html="obj.name"></div>
<div v-html="obj.age"></div>
</div>
<script>
new Vue({
el: "#root",
data: {
msg: "<b>zs</b>",
obj:{
name: "<b>zs</b>",
age: 18
}
}
})
</script>
</body>
V-show:标签控制隐藏(display设置none)
隐藏和显示
对于v-show而言, 无论显示与否, 都要加载到dom上
面试前端必问题,java面试中的hashmap
<body>
<div id="root">
<div v-show="bool1">
123
</div>
</div>
<script>
new Vue({
el: "#root",
data: {
// true:控制台为display:none
// 改为false则不显示,控制台无
bool1: true
}
})
</script>
</body>
V-if:根据表达式的值的真假渲染元素
分支语句的隐藏和显示
对于v-if而言, 如果不显示, 不会加载到dom上(区别于V-show)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<div v-if="1 == 1">
v-if
</div>
<div v-else-if="bool2">
v-else-if
</div>
<div v-else>
v-else
</div>
</div>
<script>
new Vue({
el: "#root",
data: {
bool1: false ,
bool2: true
}
})
</script>
</body>
</html>
V-on:用于事件监听(可简化为@)
<button v-on:click="f">按钮</button>
<button @click="f">按钮</button>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<div>
{{msg}}
</div>
<!-- v-on监听了一个事件(click点击事件), 意味着button一旦被点击, 就会被(v-on)监听到
监听之后触发, 触发到对应vue对象中去-->
<!-- Vue写法是把onclick的on去掉,改为click-->
<button v-on:click="f">按钮</button>
<button @click="f">按钮</button>
<!-- <button οnclick="f()">按钮</button>-->
</div>
<script>
new Vue({
el: "#root",
data: {// 存储vue我们自定义的数据
msg: "zs"
},
// 我们希望把方法创建到里面,来改变msg的值
methods: {// 写我们自定义方法
//f这么写
f:function () {
// 一定要加this(不加访问不到), 这个this代指这个vue对象
// 语法规定可以直接找到,不用this.data.msg
this.msg = "ls"
}
}
})
// function f() {
// alert(123)
// }
</script>
</body>
</html>
vue的核心(环状结构)(以后感受)
作业:Dom实现改为使用vue实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
background: red;
margin: 0 auto;
font-size: 35px;
color: white;
}
.div2{
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
margin: 0 auto;
background: none;
}
</style>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<div id="div1">
{{msg}}
</div>
<div class="div2">
<button v-on:click="getname">点名</button>
</div>
</div>
<script>
new Vue({
el: "#root",
data: {
list : ['zs', 'ls', 'wu', 'zl'],
mid : -1,
msg: "zs"
},
methods: {
getname: function () {
var index = Math.floor(Math.random()*this.list.length)
while (index == this.mid){
index = Math.floor(Math.random()*this.list.length)
}
this.mid = index
this.msg = this.list[this.mid]
}
}
})
</script>
</body>
</html>
V-pre:阻止预编译
<body>
<div id="root">
<!-- 不会再被解析-->
<div v-pre>
{{msg}}
</div>
</div>
<script>
new Vue({
el: "#root",
data: {
}
})
</script>
</body>
V-once:只编译一次
<body>
<div id="root">
<!-- 需求:希望插值表达式的值不要跟着改变(即input输入改变导致data中msg改变后)-->
<!-- 只编译一次:插值表达式替换为zs的时候编译一次-->
<div v-once>
{{msg}}
</div>
<input v-model="msg">
</div>
<script>
new Vue({
el: "#root",
data: {
msg: 'zs'
}
})
</script>
</body>
V-cloak:延迟加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
<style>
/*属性选择器*/
[v-clock]{
/*隐藏*/
display: none;
/*font-size: 100px;*/
}
</style>
</head>
<body>
<div id="root">
<!-- 在div自定义了一个属性, v-clock , -->
<!-- 3s后,当html代码按照vue语法重新解释的时候, 遇到v-clock会把这个属性立马删除-->
<div v-clock>
{{msg}}
</div>
</div>
<script>
// 定时器: 3秒之后, 执行 f方法
setTimeout('f()', 3000)
function f() {
// 3秒之后,才触发f方法,才创建Vue对象,才建立绑定关系,才按照vue语法解释上面的域,即msg
new Vue({
el:"#root",
data: {
msg: 123
}
})
}
</script>
</body>
</html>
V-for:基于源数据多次渲染元素或模板块(循环渲染元素)
注意1:
v-for: 写在那个标签上, 循环遍历的就是那个标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<!-- 无序列表:ul-li-->
<ul>
<!-- <li>{{list[0]}}</li>-->
<!-- <li>{{list[1]}}</li>-->
<!-- <li>{{list[2]}}</li>-->
<!-- <li>{{list[3]}}</li>-->
<!-- v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
<li v-for="aaaa in list">
{{aaaa}}
</li>
</ul>
<input v-model="str"><button v-on:click="addli">添加</button>
</div>
<script>
new Vue({
el: "#root",
data: {
list: ["zs", "ls", "wu", "zl"],
str: ''
},
methods: {
addli: function () {
this.list.push(this.str)
this.str = ''
}
}
})
</script>
</body>
</html>
注意2:
对于v-for遍历 in/of 都可以, 没有什么区别
注意3:
在vue中如果使用v-for这个指令, 那么必须给每一个v-for指令所遍历出的元素/标签, 加一个:key=”唯一值” key不可重复
Key是一个底层标记(给底层代码用的): 不是给我们(程序员)用的
方式1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<ul>
<!-- v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
<!-- in/of 都可以用来遍历, 没有区别 -->
<!-- <li v-for="aaaa of list">{{aaaa}}</li>-->
<!-- 不正确-->
<!-- 对于v-for: 如果要做循环遍历, 必须要有key, 并且key要唯一 -->
<!-- :是双向绑定的缩写-->
<!-- <li v-for="aaaa of list" :key="aaaa">{{aaaa}}</li>-->
<!-- key绑定下标tag,这不是最终手段-->
<li v-for="(aaaa, tag) of list" :key="tag">{{aaaa}}--{{tag}}</li>
</ul>
<input v-model="str"><button v-on:click="addli">添加</button>
</div>
<script>
new Vue({
el: "#root",
data: {
list: ["zs", "ls", "wu", "zl"],
str: ''
},
methods: {
addli: function () {
this.list.push(this.str)
this.str = ''
}
}
})
</script>
</body>
</html>
PM Lesson
方式2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<ul>
<!-- v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
<!-- in/of 都可以用来遍历, 没有区别 -->
<!-- 对于v-for: 如果要做循环遍历,
必须要有key, 并且key要唯一 (这个key不是给程序员使用的), 底层-->
<!-- <li v-for="aaaa of list" :key="aaaa">{{aaaa}}</li>-->
<li v-for="aaaa of list" :key="aaaa.id">{{aaaa.name}}</li>
<!-- 只想显示name,就写aaaa.name。否则就是对象-->
</ul>
<input v-model="str"><button v-on:click="addli">添加</button>
</div>
<script>
new Vue({
el: "#root",
// 对象数组,上面遍历出来的是对象,用id来充当key即key="aaaa.id",这才是常见的写法
data: {
list: [{
id: 1,
name: 'zs'
}, {
id: 2,
name: 'zs'
}, {
id: 3,
name: 'ls'
}],
str: ''
},
methods: {
addli: function () {
this.list.push(this.str)
this.str = ''
}
}
})
</script>
</body>
</html>
方式3:(向列表中添加元素,点击某个元素,就删除某个元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
<ul>
<!-- v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
<!-- in/of 都可以用来遍历, 没有区别 -->
<!-- 对于v-for: 如果要做循环遍历, 必须要有key, 并且key要唯一 -->
<!-- <li v-for="aaaa of list" :key="aaaa">{{aaaa}}</li>-->
<li v-for="(aaaa, tag) of list"
:key="tag"
<!-- tag为要删除的下标-->
@click="deleteli(tag)"
>{{aaaa}}--{{tag}}</li>
</ul>
<input v-model="str"><button v-on:click="addli">添加</button>
</div>
<script>
new Vue({
el: "#root",
data: {
list: ["zs", "ls", "wu", "zl"],
str: ''
},
methods: {
addli: function () {
this.list.push(this.str)
this.str = ''
},
deleteli: function (index) {
this.list.splice(index, 1)
}
}
})
</script>
</body>
</html>
1.3 计算属性computed :指一个属性通过其他属性计算而来
计算属性, 首先是一个属性(外在表现), 这个属性是通过别的属性计算来的(依赖于别的属性而存在)
方式1:用方法来计算比较麻烦:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
{{sum}}
<br>
值1:<input v-model="input1" V-on:change="getsum"><br>
值2:<input v-model="input2" @change="getsum">
</div>
<script>
new Vue({
el: "#root",
data: {
sum: 0,
input1: '',
input2: ''
},
methods: {
getsum: function () {
this.sum = parseInt(this.input1) + parseInt(this.input2)
}
},
computed: { // 表示的是计算属性
}
})
</script>
</body>
</html>
方式2:改为使用计算属性来写:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
<!-- 找值,data找, 如果在data里面找不到, 去计算属性找 -->
{{sum}}<br>
<!-- 双向绑定:value和input1相互影响-->
值1:<input v-model:value="input1" ><br>
<!-- 注意:这里是双向绑定的省略写法。只能绑定value值,所以可以不写。-->
<!-- 值1:<input v-model="input1" ><br>-->
值2:<input v-model="input2" >
</div>
<script>
new Vue({
el: "#root",
data: {
input1: '',
input2: ''
},
computed: { // 表示的是计算属性
// 计算属性, 首先是一个属性,
// 这个属性是通过别的属性计算来的(依赖于别的属性而存在)
// 方法名, 这个计算属性的属性名sum
sum: function () {
// 不要在这里面写过多的逻辑(必要的逻辑是可以的)
return parseInt(this.input1) + parseInt(this.input2)
}
}
})
</script>
</body>
</html>
1.4 侦听器watch:监听一个属性改变触发一个事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
{{sum}}<br>
值1:<input v-model="input1" ><br>
值2:<input v-model="input2" >
</div>
<script>
new Vue({
el: "#root",
data: {
sum: 0,
input1: '',
input2: ''
},
computed: {
sum1: function () {
return parseInt(this.input1) + parseInt(this.input2)
}
},
watch: {// 侦听器, 侦听一个属性的改变
// // 侦听input1的改变, input1一旦改变就会触发这个方法
// input1: function () {
// this.sum = parseInt(this.input1) + parseInt(this.input2)
// },
//
// input2: function () {
// this.sum = parseInt(this.input1) + parseInt(this.input2)
// },
// 也可以侦听计算属性sum1:计算属性当做属性来看待
sum1: function () {
this.sum = this.sum1
}
}
})
</script>
</body>
</html>
2. 模板和组件
vue核心3个
微指令、模板(组件的补充)和组件(核心)
2.1 模板
模板的好处: 以后只需要在html留一个入口, 一切的内容都可以转移到vue对象中去
<div id="root"></div>
先基础性地理解模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<!-- 这里的div会被忽略,即被下面的模板替换-->
<div id="root">
{{msg}} 123
</div>
<script>
//template:
//一个字符串模板作为 Vue 实例的标识使用。
//模板将会 替换 挂载的元素。挂载元素的内容都将被忽略.
// 所谓挂载: html解析生成dom结点, 和dom树建立联系(对象引用关系)
new Vue({
el: "#root",
data: {
msg: 123
},
template: "<div>aaaa</div>"
})
</script>
</body>
</html>
模板的好处: 以后只需要在html留一个入口, 一切的内容都可以转移到vue对象中去
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root"></div>
<script>
// 模板的好处: 以后只需要在html留一个入口, 一切的内容都可以转移到vue对象中去
// 解耦:
// 所谓挂载: html解析生成dom结点, 和dom树建立联系(对象引用关系)
//template:
//一个字符串模板作为 Vue 实例的标识使用。
//模板将会 替换 挂载的元素。挂载元素的内容都将被忽略.
new Vue({
el: "#root",
data: {
msg: 123
},
template: "<div> <div @click='f'>{{msg}}</div> <input v-model='msg'> </div>",
methods: {
f: function () {
alert(123)
}
}
})
</script>
</body>
</html>
2.2组件
一个Vue对象就叫一个Vue组件
组件.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
<!-- 重新解析的时候,可以识别自定义标签aaaa,aaaa代表一个test1的对象-->
<!-- 这个对象有模板,模板<div>123</div>替换挂载的元素<aaaa></aaaa>-->
<aaaa></aaaa>
</div>
<script>
// 普普通通的js对象
var test1 = {
template: "<div>123</div>"
}
// component
new Vue({
el: "#root",
data: {},
components: {// 导入子组件, 导入子Vue对象\
// 别名: 原对象名
aaaa: test1
// 上面的js对象test1导入进来,和vue语法建立联系,就成为vue对象
}
})
</script>
</body>
</html>
组件2.html:详细分析整个过程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- step1:加载Vue语法-->
<script src="vue.js"></script>
</head>
<body>
<!-- step2:普通的div和div下面普通的aaaa标签-->
<div id="root">
<!-- step4:发现这不是html语法,在子组件中检查有没有定义aaaa标签。有,对应test1就是Vue的子对象了,也就是一个Vue对象了-->
<!-- 这里的内容就变成test1的所有内容,检查有没有模板;有模板,<div><div @click='f'>{{msg}}<div></div>替换<aaaa></aaaa>-->
<aaaa></aaaa>
<!-- 使用了才会有显示-->
<bbbb></bbbb>
</div>
<script>
// step3:普普通通的js对象
var test1 = {
template: "<div><div @click='f'>{{msg}}<div></div>",
// msg引发到这里了
data(){
return{
msg: 222
}
},
// 点击触发到这里
methods: {
f: function () {
alert(123)
}
}
}
// 可以有多个Vue对象,再注册一个test2就可以
var test2 = {
template: "<div><div @click='f'>{{msg}}<div></div>",
data(){
return{
msg: 3333
}
},
methods: {
f: function () {
alert(123)
}
}
}
// step3:创建Vue对象,检查el,重新解析step2中的Vue域
// component
new Vue({
el: "#root",
data: {
msg: 123
},
// 在这里注册之后,上面的才成为Vue
components: {// 导入子组件, 导入子Vue对象\
// 别名: 原对象名
aaaa: test1,
bbbb: test2
}
})
</script>
</body>
</html>
组件3.html: (上面的清空,这里加一个模板,显示的结果同上)
模板和组件加在一起构建出Vue的一个核心理论:把页面拆分成很多Vue对象,每一个Vue对象管控一小 片区域,Vue对象间通过父子的Vue对象,构建引用关系,最终汇合成一个页面。(这就是Vue的本质的东西)
3/19 PM Lesson2
2.3 生命周期(2创建 + 2挂载 + 2修改 + 2销毁)
重要程度和组件与模板不在一个量级上面
beforeCreate
Created
beforeMount
Mounted
beforeUpdtae
Updated
beforeDestroy
destoryed
创建对象的时候触发2个方法
![](https://img-blog.csdnimg.cn/20210321161450857.png)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
<!-- 执行创建和挂载的4个-->
{{msg}}
<!-- 修改msg,beforeUpdate和updated-->
<input v-model="msg">
</div>
<script>
var root = new Vue({
el: "#root",
data: {
msg: 123
},
beforeCreate:function () {
console.log("控制台打印:beforeCreate")
},
created:function () {
// 请求
// 获得后端数据
// 赋值给data数据
// 就可以显示了
console.log("控制台打印:created")
},
beforeMount:function () {
//页面还未被渲染
console.log(this.$el),
console.log("控制台打印:beforeMount")
},
mounted:function () {
//页面渲染完成
console.log(this.$el),
console.log("控制台打印:mounted")
},
beforeUpdate:function () {
console.log("控制台打印:beforeUpdate")
},
updated:function () {
console.log("控制台打印:updated")
},
beforeDestroy:function () {
console.log("控制台打印:beforeDestory")
},
destroyed:function () {
console.log("控制台打印:destroyed")
}
})
</script>
</body>
</html>
讲为什么created和mounted常用,先讲前后端分离
2.4 前后端分离
3. Vue项目(创建一个项目)
安装jdk(运行环境) idea 通过idea创建project 写代码.java 编译打包发布
安装node(js运行环境) vue-cli 通过vue-cli创建一个vue项目 写vue代码 编译打包发布
3.1 创建一个vue项目
安装node
http://nodejs.cn/download/
默认安装(一直next)就可以
如下成功
安装cnmp
npm install -g cnpm --registry=https://registry.npm.taobao.org
npm: 命令
install 安装
-g: 全局安装
Cnpm : 安装的那个包
--registry=https://registry.npm.taobao.org: 去那个地方下载这个包
如下成功
安装vue-cli
安装脚手架工具
cnpm install -g @vue/cli
cnpm install -g @vue/cli-init
如下成功
vue -V (v必须大写)
Webpack(模块打包机)
cnpm install -g webpack
Java war jar
前端 html css js
上面都是在配置环境 |
创建项目
路径在哪里,项目就创建在哪里
比如想把项目创建在桌面,就在命令符窗口把路径切换到桌面desktop下
vue init webpack 项目名(不要大写)
如
vue init webpack vuetest
默认回车
y/n 统一选n 再回车
注意最后一步: 手动安装
切换路径到项目目录下(如vuetest下)
执行cnpm install安装包node_modules
如下成功
启动前端项目:nmp run dev
实际上启动的是一个前端服务器
前端服务器启动成功
在浏览器中输入
http://localhost:8080
如下成功
day 6 AM
给一个前端项目怎么启动(做项目的时候)(只需要做一件事情,如下)
1, 下载下来
2, 给它装包: node_modules
3, 启动: npm run dev
37 KB
cnpm install
只多了一个包node_modules
80 MB
3.2 要了解的配置文件
第一个:index.js
关于端口的设置,一般默认8080就可以
第二个:package.json
Vue项目下执行Cnpm install安装包(没写包名怎么知道安装哪个?)(安装下面package.json文件中的包)(都在node_modules文件下)
Cnpm install -g @vue/cli
Cnpm install
Npm run dev 启动的是一个前端服务器
启动一个项目不一定通过nmp run dev
第3个:index.html
整个项目的入口
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vuetest</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>'
})
App.vue
Q:显示123创建了几个vue对象?
A:2个。main.js中new的一个,其中还导入了一个App子对象
3.3 组件传值
3.3.1 父子组件传值
3.3.1.1 子组件向父组件传值
子组件抛出方法:
this.$emit("changeinput", this.inputstr)
父组件接受方法:
<left class="left" v-on:changeinput="appchange"></left>
3.3.1.2 父组件向子组件传值
父组件传递
<right class="right" v-bind:rightparame="str"></right>
子组件接收
props: ['rightparame']
props:等价看做data(一个区别, props里面的参数不可修改)
3.3.2 中央总线/bus
中转站
第一步: 创建bus文件
import Vue from 'vue' // 导入Vue语法
// 创建一个Vue对象
const bus = new Vue()
// 整个js文件, 默认向外界暴露只有一个bus对象
export default bus
第二步: 在main.js引入
import bus from './bus'
Vue.prototype.$bus = bus
第三步使用
3.3.3 使用第三方插件/包的步骤
1, 导入包, 或者引入配置文件
2, 在main.js配置
3, 使用
cnpm i element-ui --save
3.3.4 Axios
异步请求