文章目录
😹 作者: gh-xiaohe
😻 gh-xiaohe的博客
😽 觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!!
🚏 浅学VUE
🚀 1、MVVM模型
总结:
<!-- MVVM模型 1. M:模型(Model) :data中的数据 2. V:视图(View) :模板代码 3. VM:视图模型(ViewModel):Vue实例 观察发现: 1.data中所有的属性,最后都出现在了vm身上。 2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。 -->
MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:
- 该层向上与视图层进行双向数据绑定
- 向下与Model层通过接口请求进行数据交互
🚬 为什么要使用MVVM
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处
- 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
- 可复用:你可以把一些视图逻辑放在一个Vi ewModel里面,让很多View重用这段视图逻辑。
- 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
- 可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。
🚬 MVVM模式的实现者
Model:模型层, 对应data中的数据
View:视图层, 在这里表示DOM(HTML操作的元素) 模板
ViewModel:连接视图和数据的中间件, Vue.js就是MVVM中的View Model层的实现者 Vue实例对象
View 层展现的不是 Model 层的数据, 而是 ViewModel 的数据, 由 ViewModel 负责与 Model层交互,获取和更新数据, 这就完全解耦了View层和Model层, 这个解耦是至关重要的, 它是前后端分离方案实施的重要一环。在MVVM架构中, 是不允许数据和视图直接通信的, 只能通过ViewModel来通信, 而View Model就是定义了一个Observer观察者
- ViewModel能够观察到数据的变化, 并对视图对应的内容进行更新
- ViewModel能够监听到视图的变化, 并能够通知数据发生改变
至此, 我们就明白了, Vue.js就是一个MVVM的实现者, 他的**核心就是实现了DOM监听与数据绑定**
🚄 2、Vue的第一个程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层 模板-->
<div id="app">
<!--拿数据-->
{{message}}
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
/*
* 1.绑定元素 div
* el element 元素
* data 数据 对象 键值对 前端
*
* */
var vm = new Vue({
el:'#app',
//Model : 数据
data: {
message: 'hello,Vue!1'
}
});
</script>
</body>
</html>
浏览器控制台输出
vm.message=“123”; // 页面即使发生改变
🚬 步骤
- ① 导入Vue
- ② 创建 new Vue 对象
- ③ 绑定元素
- ④ 放数据,从模板中取出
🚒 3、Vue基本语法
🚬 v-bind 绑定特定的元素,缩写 :号
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
{{message}}<br>
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var mv = new Vue({
el: "#app",
data: {
message: 'hello,Vue!1'
}
});
</script>
</body>
</html>
🚬 条件判断 v-if 、v-else
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<template v-if="ok">
<h1>早上</h1>
<p>起床</p>
</template>
<template v-else>
<h1>晚上</h1>
<p>睡觉</p>
</template>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var mv = new Vue({
el: "#app",
data: {
ok : true
}
});
</script>
</body>
</html>
🚬 条件判断 v-else-if
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-if="type === 'A'">100</h1>
<h1 v-else-if="type === 'B'">80</h1>
<h1 v-else-if="type === 'C'">60</h1>
<h1 v-else-if="type === 'D'">不及格</h1>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var mv = new Vue({
el: '#app',
data: {
type: 'A'
}
});
</script>
</body>
</html>
🚬 循环 [] 数组 {} 对象
🚭 v-for
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--items 里面 in 便利出来叫item 从后面往前写 -->
<li v-for="item in items">
{{item.message}}
</li>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
/*Model:数据*/
data:{
items:[
{message:'Java'},
{message:'MySQL'},
{message:'Linux'}
]
}
});
</script>
</body>
</html>
🚭 v-for(item,index)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--items 里面 in 便利出来叫item -->
<li v-for="(item,index) in items">
{{item.message}}~~~~~{{index}}
</li>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
/*Model:数据*/
data:{
items:[
{message:'Java'},
{message:'MySQL'},
{message:'Linux'}
]
}
});
</script>
</body>
</html>
🚬 v-on 监听事件 简写@符号
v-on:click 点击事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <button v-on:click="add">点击事件</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> var mv = new Vue({ el: "#app", data: { message: "Hello,Vue" }, methods: { //方法必须定义在Vue 的 Method对象中 add: function() { alert(this.message) } } }); </script> </body> </html>
🚬 v-model 双向绑定
🚭 v-bind 和 v-model的区别
- v-bind 单向绑定
- 数据只能从data流向页面
- v-model 双向绑定
- 不仅能从data流向页面,还能从页面流向data
🚭 input单行文本
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
输入的文本 <input type="text" v-model="qinjiang">
****{{qinjiang}}***
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
/*单行文本*/
var mv = new Vue({
el: "#app",
data: {
qinjiang: "双向绑定"
}
});
</script>
</body>
</html>
🚭 textarea多行文本
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--textarea 多行文本-->
<div id="app">
多行文本 <textarea name="" id="" cols="30" rows="10" v-model="message"></textarea>
{{message}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var mv = new Vue({
el: "#app",
data: {
message: ""
}
});
</script>
</body>
</html>
🚭 checkbox单复选框
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
单复选框:
<input type="checkbox" v-model="checked">
<label>{{checked}}</label>
<hr />
{{checked}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
checked:false
}
});
</script>
</body>
</html>
</body>
</html>
🚭 checkbox多复选框
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
多复选框
<input type="checkbox" value="Jack" v-model="checkedName">Jack
<input type="checkbox" value="Join" v-model="checkedName">Join
<input type="checkbox" value="mike" v-model="checkedName">mike
<span>选中的值:{{checkedName}}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var mv = new Vue({
el: "#app",
data: {
checkedName: []
}
});
</script>
</body>
</html>
🚭 radio单选框
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
单选框:
<input type="radio" value="One" v-model="picked">One
<input type="radio" value="Two" v-model="picked">Two
<span>选中的值 ~{{picked}}~ </span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
picked:"Two"
}
});
</script>
</body>
</html>
🚭 select 下拉框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
下拉框:
<select v-model="picked">
<option value="" disabled >----请选择----</option>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
</select>
<span>选中的值 ~{{picked}}~ </span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
picked:""
}
});
</script>
</body>
</html>
注意:
v-model表达式的初始值未能匹配任何选项,元系将被渲染为“未选中”状态。 在iOS中, 这会使用户无法选择第一个选项,因为这样的情况下,iOS不会触发change事件。因此,更推荐像上面这样提供一个值为空的禁用选项。
🚤 4、Vue组件Component
Vue.component("qinjiang",{ // qinjiang 组件名字
props: , // 参数用来接收
template: // 模板
methods: // 可以定义方法
});
①
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <qinjiang></qinjiang> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> /* * Vue对象 * component 组件 * 定义一个vue组件component组件 * */ Vue.component("qinjiang",{ template: '<li>Hello </li>' //模板 }); var mv = new Vue({ el: "#app", data: { } }); </script> </body> </html>
②
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--组件,传递给组件中的值:props--> <qinjiang v-for="item in items" v-bind:qin="item"/> <!--循环 绑定--> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> /* * Vue对象 * component 组件 * 定义一个vue组件component组件 * */ Vue.component("qinjiang",{ props: ['qin'], //参数用来接收 template: '<li>{{qin}}</li>' //模板 }); var vm = new Vue({ el: "#app", data: { items: ['Java','MySql','Linux'] } }); </script> </body> </html>
🚗 5、Vue网络通信Axios
介绍:浏览器和NodeJS的异步通信框架
作用:实现Ajax异步通信(xhlr)
data.json
{ "name": "gh_xiaohe个人博客", "url": "https://blog.csdn.net/gh_xiaohe", "page": 1, "isNonProfit": false, "address": { "street": "含光门", "city": "陕西西安", "country": "中国" }, "links": [ { "name": "bilibili", "url": "https://www.bilibili.com/" }, { "name": "个人博客", "url": "https://blog.csdn.net/gh_xiaohe" }, { "name": "百度", "url": "https://www.baidu.com/" } ] }
①
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="vue"> </div> <!--引入js文件--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script type="text/javascript"> var vm = new Vue({ el:"#vue", /* * mounted(){ 钩子函数,链式编程 ES6新特性 * * 编译好的HTML挂载到页面完成后执行的时间钩子此钩子函数中 * 一般会做一些ajax请求获取数据进行数据初始化 * 注意:mounted在整个实例中只执行一次 * */ mounted(){//钩子函数,链式编程 ES6新特性 axios.get('../data.json').then(response => console.log(response.data)); //执行完响应后 输出一句话 response相应的数据 } }); </script> </body> </html>
浏览器控制台
②
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> <!--v-cloak 解决闪烁问题--> <style> [v-cloak] { display: none; } </style> </head> <body> <div id="app" v-cloak> <div>属性名:{{info.name}}</div> <div>链接:<a v-bind:href="info.url">{{info.url}}</a></div> <div>页数:{{info.page}}</div> <div>是否有利润isNonProfit:{{info.isNonProfit}}</div> <div>地址:{{info.address.street}}--{{info.address.city}}--{{info.address.country}}</div> <div>数组:{{info.links}}</div> </div> <!--引入js文件--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> var mv = new Vue({ el: "#app", //此时data() 是方法 , 不是data 属性 二者不一样 data() { return { //请求的返回参数合适,必须和json字符串一样 可以省略不写 info: { name: null, url: null, address:{ street:null, city:null, country:null }, links:[] } } }, /* * mounted(){ 钩子函数,链式编程 ES6新特性 * * 编译好的HTML挂载到页面完成后执行的时间钩子此O钩子函数中 * 一般会做一些ajax请求获取数据进行数据初始化 * 注意:mounted在整个实例中只执行一次 * */ mounted() { //钩子函数,链式编程 ES6新特性 axios.get('../data.json').then(response => this.info=response.data); //执行完响应后 输出一句话 response相应的数据 } }); </script> </body> </html>
- 要求:返回的参数必须和Json字符串中一致
- axios.get(‘…/data.json’) 到 data.json获取数据
- info:接收axios 的数据
- info.address.street 显示数据信息
🚲 6、Vue计算属性component(特色)
计算出来的结果,保存在属性中,内存中运行(可以想象为缓存)
将不经常变化的计算结果进行缓存,节约开销
计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="vue">
<p>currentTime1:{{currentTime1()}}</p>
<p>currentTime2:{{currentTime2}}</p>
</div>
<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var mv = new Vue({
el:"#vue",
data: {
message:"hello"
},
methods:{
currentTime1: function() {
return Date.now();//返回一个时间戳
}
},
computed: {
currentTime2: function() { //计算属性:methods,computed方法名不能重名,重名之后,只会调用methods的方法
this.message; //mybatis 缓存 第一次计算 存在结果里面,有增删改 之后重新计算
return Date.now();//返回一个时间戳
}
}
});
</script>
</body>
</html>
说明:
- methods:定义方法,调用方法使用currentTime1,需要带括号
- computed:定义计算属性,调用属性使用currentTime2,不需要带括号;this.message是为了能够让currentTime2观察到数据变化而变化
- 如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.message=”qinjiang”,改变下数据的值,再次测试观察效果!
结论:
调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来, 采用计算属性可以很方便的做到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;
🚀 7、插槽 slot
在Vue.js中我们使用元素作为承载分发内容的出口,作者称其为插槽,可以应用在组合组件的场景中;
solt 插槽 动态的**可拔插** ,实现复用
① 基础实现
<div id="app"> <p>列表书籍</p> <ul> <li>Java</li> <li>Linux</li> <li>Python</li> </ul> </div>
②比如准备制作一个待办事项组件(todo),该组件由待办标题(todo-title)和待办内容(todo-items)组成,但这三个组件又是相互独立的,该如何操作呢?
// 方式一: Vue.component('todo',{ template:' <div>\ <slot name="todo-title"></slot>\ <ul>\ <slot name="todo-items"></slot>\ </ul>\ </div>' }); // 方式二: Vue.component('todo',{ template: '<div>'+ '<slot name="todo-title"></slot>'+ '<ul>'+ '<slot name="todo-title"></slot>'+ '</ul>'+ '</div>' });
③ 定义插槽 名为 todo-title 件和 todo-items
Vue.component('todo-title',{ props:['title'], template:'<div>列表书籍</div>' }); Vue.component("todo-items",{ props:['item'], template:'<li>Java</li>' });
④ 替换①
<div id="app"> <todo> <todo-title></todo-title> <todo-items></todo-items> </todo> </div>
⑤ 实例
var mv = new Vue({ el: "#app", data: { title: '列表书籍', message: ['Java','Linux','Python'] } });
⑥ 接受参数
Vue.component('todo-title',{ props:['title'], template:'<div>{{title}}</div>' }); Vue.component("todo-items",{ props:['item'], template:'<li>{{item}}</li>' });
⑦ 绑定
<div id="app"> <todo> <todo-title slot="todo-title" :title="title"></todo-title> <todo-items slot="todo-items" v-for="item1 in message" :item="item1"></todo-items> </todo> </div>
🚄 8、自定义事件
🚬 JavaScrpit 中如何移除数组元素
splice()方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:
var arr = ['Microsoft','Apple','Yahoo','AOL','Excite', 'Oracle']; //从索引2开始删除3个元素,然后再添加两个元素: arr.splice(2,3,'Google','Facebook');//返回删除的元素['Yahoo','AoL','Excite'] arr; // ['Microsoft','Apple','Google','Facebook','oracle'] //只制除,不添加: arr.splice(2, 2); // ['Google','Facebook'] arr; // ['Microsoft', 'Apple', 'Oracle'] //只添加,不删除: arr.splice(2,0,‘Google',‘Facebook');//返回[],因为没有删除任何元素 arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'oracle']
🚬 自定义事件
⑧ 在vue的实例中增加了methods对象并定义了一个名为removeItems的方法
var mv = new Vue({ el: "#app", data: { title: '列表书籍', message: ['Java','Linux','Python'] }, methods:{ removeItems: function (index) { console.log("删除"+this.message[index] + "Ok"); //只要执行了这个 removeItems 方法, 就自我删除 index 这个 元素 this.message.splice(index,1)//一次删除一个元素 splice()方法是修改Array的“万能方法” } } });
⑨ 思考在组价那中如何删除
修改todo-items待办内容组件的代码,增加一个删除按钮,并且绑定事件
Vue.component("todo-items", { props: ['item','index'], //只能绑定当前组件的方法 template: '<li>{{index}}--{{item}}----<button @click="remove">删除</button></li>', //组件里面也可以写方法 可以调用自己 当前组件 绑定当前事件 methods: { remove: function (index) { //这里的remove是自定义事件名称,需要在HTML中使用v-on:remove的方式 //this.$emit 自定义事件分发 this.$emit('remove',index); } } });
⑩ 修改todo-items待办内容组件的HTML代码,增加一个自定义事件,比如叫remove,可以和组件的方法绑定,然后绑定到vue的方法!
<todo-items slot="todo-items" v-for="(item,index) in message" :item="item" v-bind:index="index" @remove="removeItems(index)" :key="index"> </todo-items>
对上一个代码进行修改,实现删除功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- 要实现的效果可以动态删除数据 --> <div id="app"> <todo> <todo-title slot="todo-title" v-bind:title="title"></todo-title> <todo-items slot="todo-items" v-for="(item,index) in message" :item="item" v-bind:index="index" @remove="removeItems(index)"> </todo-items> </todo> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> Vue.component('todo',{ template:' <div>\ <slot name="todo-title"></slot>\ <ul>\ <slot name="todo-items"></slot>\ </ul>\ </div>' }); Vue.component('todo-title',{ props:['title'], template:'<div>{{title}}</div>' }); //vue 组件 组件 与 组件 之间可以用插槽 Vue.component("todo-items", { props: ['item','index'], //只能绑定当前组件的方法 template: '<li>{{index}}--{{item}}----<button @click="remove">删除</button></li>', //组件里面也可以写方法 可以调用自己 当前组件 绑定当前事件 methods: { remove: function (index) { //这里的remove是自定义事件名称,需要在HTML中使用v-on:remove的方式 //this.$emit 自定义事件分发 this.$emit('remove',index); } } }); /* 组件 怎么调用 vue 里面的方法 并且删除掉数据 */ //vue 实例 var mv = new Vue({ el: "#app", data: { title: '列表书籍', message: ['Java','Linux','Python'] }, methods:{ removeItems: function (index) { console.log("删除"+this.message[index] + "Ok"); //只要执行了这个 removeItems 方法, 就自我删除 index 这个 元素 this.message.splice(index,1)//一次删除一个元素 splice()方法是修改Array的“万能方法” } } }); </script> </body> </html>
🚬 图形理解
🚬 入门小节
遵循SoC关注度分离原则,Vue是纯粹的视图框架,并不包含,比如Ajax之类的通信功能,为了解决通信问题,我们需要使用Axios框架做异步通信;
说明 Vue的开发都是要基于NodeJS,实际开发采用Vue-cli脚手架开发,vue-router路由,vuex做状态管理;Vue UI,界面我们一般使用ElementUI(饿了么出品),或者ICE(阿里巴巴出品)来快速搭建前端项目~~
🚒 9、Vue-cli脚手架开发
🚬 1、什么是vue-cli
vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板;
预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个估计项目就是脚手架,我们的开发更加的快速;
主要的功能:
- 统一的目录结构
- 本地调试
- 热部署
- 单元测试
- 集成打包上线
🚬 2、需要的环境 node环境支持
Node.js:下载 | Node.js 中文网
安装就是无脑的下一步就好,安装在自己的环境目录下
Git:https://git-scm.com/doenloadshttps://git-scm.com/doenloads
镜像:git-for-windows Mirrorhttps://npm.taobao.org/mirrors/git-for-windows/
确认nodejs安装成功:
- cmd下输入node -v,查看是否能够正确打印出版本号即可!
- cmd下输入npm -v,查看是否能够正确打印出版本号即可!
安装Node.js淘宝镜像加速器(cnpm) 这样的话,下载会快很多~
# -g 就是全局安装
npm install cnpm -g
# 或使用如下语句解决npm速度慢的问题
npm install --registry=https://registry.npm.taobao.org
🚬 3、安装vue-cli
cnpm install @vue/cli -g //3.0以后的版本
#测试是否安装成功
#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack
vue list
目录 C:\Users\gh\AppData\Roaming\npm\node_modules\cnpm\node_modules\npm
🚬 4、创建是vue-cli步骤
🚬 5、 vue-cli目录:
🚤 10、Webpack
JavaScript 静态打包器 构建一个依赖关系图
import "jquery"; 导入
export function dostuff(){} 暴露
module "localModule" {} 一个模块
安装
- npm install webpack -g
- npm install webpack-cli -g
- npm install webpack-dev-server -g
🚬 使用Webpack
1、创建目录 webpack-study
2、创建modules目录 放置JS文件
3、modules 下创建模块文件,用于编写JS相关代码
4、modules 下创建main.js 入口文件
5、项目目录下创建webpack.config.js配置文件 使用webpack命令打包
6、引用JS文件(新建Html)下运行
① Hello.js
//暴露一个方法 exports exports.H1 = function () { document.write('<h1>0</h1>'); }; exports.H2 = function () { document.write('<h1>0</h1>'); };
② main.js
//引入 require 包 类似于 java 的 package var hello = require("../modules/hello") hello.H1(); hello.H2();
③ webpack.config.js
//模块到处打包 /* 两个属性 entry 程序的入口 output 输出 filename 输出到一个位置 */ module.exports = { entry:"./modules/main.js", output: { filename: "./js/bundle.js" // bundle.js 规范命名 }, }
④ webpack 打包
⑤ 多了一个 dist/js/bundle.js
⑥ 引用 index.html
前端模块化开发
<!--引入 打包之后的js bundle.js--> <script src="dist/js/bundle.js"></script>