Vue
一 、下载安装
百度
二 、快速入门:
菜鸟教程:https://www.runoob.com/vue2/vue-tutorial.html
三 、Vue基础
1、第一个vue 程序
https://www.cnblogs.com/hellman/p/10985377.html
1.第一步,创建项目
进入你的项目目录,创建一个基于 webpack 模板的新项目: vue init webpack 项目名
说明:
Vue build ==> 打包方式,回车即可;
Install vue-router ==> 是否要安装 vue-router,项目中肯定要使用到 所以Y 回车;
Use ESLint to lint your code ==> 是否需要 js 语法检测 目前我们不需要 所以 n 回车;
Set up unit tests ==> 是否安装 单元测试工具 目前我们不需要 所以 n 回车;
Setup e2e tests with Nightwatch ==> 是否需要 端到端测试工具 目前我们不需要 所以 n 回车;
1、build:构建脚本目录
1)build.js ==> 生产环境构建脚本;``
2)check-versions.js ==> 检查npm,node.js版本;
3)utils.js ==> 构建相关工具方法;
4)vue-loader.conf.js ==> 配置了css加载器以及编译css之后自动添加前缀;
5)webpack.base.conf.js ==> webpack基本配置;
6)webpack.dev.conf.js ==> webpack开发环境配置;
7)webpack.prod.conf.js ==> webpack生产环境配置;
2、config:项目配置
1)dev.env.js ==> 开发环境变量;
2)index.js ==> 项目配置文件;
3)prod.env.js ==> 生产环境变量;
3、node_modules:npm 加载的项目依赖模块
4、src:这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:
1)assets:资源目录,放置一些图片或者公共js、公共css。这里的资源会被webpack构建;
2)components:组件目录,我们写的组件就放在这个目录里面;
3)router:前端路由,我们需要配置的路由路径写在index.js里面;
4)App.vue:根组件;
5)main.js:入口js文件;
5、static:静态资源目录,如图片、字体等。不会被webpack构建
6、index.html:首页入口文件,可以添加一些 meta 信息等
7、package.json:npm包配置文件,定义了项目的npm脚本,依赖包等信息``
8、README.md:项目的说明文档,markdown 格式
9、.xxxx文件:这些是一些配置文件,包括语法配置,git配置等
2. 第二步,编码
-
引入vue.js
-
创建Vue实例对象,设置el 和 data 属性
-
把数据渲染到界面上
<body>
<div id="app">
{{ message }}
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "Hello Vue!"
}
})
</script>
</body>
Hello Vue
2、el挂载点
-
作用范围
el 选项命中的元素及其内部的后代元素
-
其他选择器
可以使用其他CSS 元素选择器,但是推荐使用id
-
其他dom元素
可以使用其他dom元素,但是必须是双标签,并且不能是和
3、data数据对象
-
Vue中使用的对象定义在data 中
-
data中可以写复杂类型数据
-
渲染复杂类型的数据时,遵循js 的语法即可
四、本地应用
1、内容绑定、事件绑定
1. v-text
作用:设置标签的文本值(textContent)
默认会全部被替代,可使用差值表达式{{ }}修改制定部分
内部支持写表达式
<div id="app">
<h2 v-text = "message">我不在</h2>
<h3>{{message}} 我还在</h3>
<h4 v-text ="message+'被拼接到text'">拼接</h4>
<h4>{{message+"被拼接到差值"}} 我还在</h4>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: "哈哈哈!"
}
})
</script>
)]
2. v-html
作用:设置标签的innerHTML
数据为普通文本,跟v-text没有任何差别
内容中的html 结构会被解析为html 标签
v-text只会解析成文本
<div id="app">
<h1 v-text = "message" ></h1>
<h1 v-html= "message"></h1>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: "<a href = 'http://www.baidu.com'> 点我</a>"
}
})
</script>
3. v-on基础
为元素绑定事件
@ = v-on:
this 拿到当前挂载元素范围内的数据
<div id="app">
<h2>{{message}}</h2>
<input type="button" value ="单击click" v-on:click="doit" />
<input type="button" value ="单击click" @click="doit" />
<input type="button" value ="双击dblclick" v-on:dblclick="dome" />
<input type="button" value ="this" @click="dothis" />
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: "哈哈哈"
},
methods:{
doit : function(){
alert("干他!")
},
dome:function(){
alert("干我!")
},
dothis:function(){
this.message+="拿到哈哈了"
}
}
})
</script>
4. 案例
<div id ="app">
<button @click = "sub">-</button>
<span>{{num}}</span>
<button @click = "add">+</button>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
num:1
},
methods:{
add:function(){
if(this.num < 10){
this.num++;
}else{
alert("最大值了!");
}
},
sub:function(){
if(this.num>0){
this.num--;
}else{
alert("最小值了!")
}
}
}
})
</script>
2、显示切换属性绑定
1. v-show
作用:根据表达式的真假切换元素的显示状态
原理:修改元素的display
指令后面的值都会解析成布尔值 true为显示
<div id="app">
<img src="/src/assets/logo.png" v-show="true">
<img src="/src/assets/logo.png" v-show="isShow">
<img src="/src/assets/logo.png" v-show="num>=10">
<button @click ="addnum">num++</button>
<span>{{num}}</span>
<button @click ="subnum">num--</button>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
num:1,
isShow:false,
},
methods:{
addnum:function(){
this.num ++;
},
subnum:function(){
this.num --;
}
}
})
</script>
2. v-if
用法类似于v-show
作用:根据表达式的真假切换元素的显示状态(同 v-show)
本质是切换dom元素是否存在来显示状态
v-show 操作的是样式 dom 元素存在
3. v-bind
设置元素的属性
<div id="app">
<img v-bind:src="imgSrc">
<img :src="imgSrc">
<img :title="imgTitle+'???'" src="/src/assets/logo.png">
<img :class="isActive?'active':' ' "><!--三元-->
<img :class="{active:active}"> <!--对象-->
</div>
<script>
var app = new Vue({
el: "#app",
data: {
imgSrc: "/src/assets/logo.png",
imgTitle:"啦啦",
imgActive:false
}
})
</script>
3、列表循环,表单元素绑定
1. v-for
根据数据生成列表结构
数组经常和v-for结合使用
数组长度更新会响应式地更新到页面上
<div id="app">
<ul>
<li v-for="item in arr">{{item}}</li>
<li v-for="(i,index) in Objarr">
{{index+1}}{{i.name}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
arr: ["a", "b", "c"],
Objarr: [{ name: "张三" },
{ name: "李四" },
{ name: "王五" }
]
}
})
</script>
2. v-on 补充
传递自定义参数,事件修饰符
事件绑定的方法写成函数调用的形式,可传入自定义参数
定义方法时需要定义形参来接收传入的实参
事件的后面跟上 . 修饰符可以触发对事件的限制
<div id="app">
<input type="button" value="点我传参" @click="doit('老铁',666)" >
<input type="text" @keyup.enter="sayHi" >
</div>
<script>
var app = new Vue({
el: "#app",
methods: {
doit: function (p1, p2) {
console.log(p1);
console.log(p2);
},
sayHi: function () {
alert("你按了enter");
}
}
})
</script>
3. v-model
获取数据和设置表单元素的值(双向数据绑定)
<input type="text" v-model="message" >
4、vue 的生命周期
从 new Vue 创建实例、运行、销毁期间,伴随各种事情,这些事情都被称为生命周期
生命周期钩子,也就是生命周期函数
<script>
var app = new Vue({
el: "#app",
methods: {
},
// 创建时生命周期函数
beforeCreate() {
//我们遇到的第一个生命周期函数,表示实例被完全创建出来之前会执行他,
//在beforeCreate 函数还行的时候,data 和methods中的的数据都没有被初始化
},
created() {
// 这是遇到的第二个生命周期函数,data methods 数据都已经初始化好了
// 这里表示vue 开始编译模板,把vue代码指令进行执行,最终在内存中生成一个编译好的模板字符串,
// 然后把模板字符串渲染到DOM,此时只是在内存中渲染好了模板,并没有把模板真正的挂载到我们的页面中
},
beforeMount() {
//这是遇到的第三个生命周期函数,表示疤已经在内存模板中渲染好了,但是尚未吧模板渲染到页面中
},
mounted() {
//这是第四个生命周期函数,表示内存中的模板已经真实地挂载到真实页面中。
},
//运行时生命周期函数 ,数据被更新才会执行
beforeUpdate(){
//这时候界面还没有被更新,但是数据被更新了
},
updated(){
//他执行的时候,数据和界面都是最新的
},
beforeDistroy(){
//次函数执行的时候,实例已经从运行阶段进入到销毁阶段,但是实例中的method,data,过滤器,指令等。。。都处于可用状态
},
distroyed(){
//执行到这,实例所有东西都被销毁,所有东西都不可用
}
})
</script>
5、组件和模块化
1. 什么是组件?
组件的出现为了拆分vue实例代码量,能够让我们以不同的组件来划分不同的功能模块,将来我们需要什么样的功能,就可以对调用对应的组件即可。方便ui 的重用
2. 组件化和模块化的区别
模块化:是从代码逻辑的角度划分的,方便代码分层开发,保证每个功能模块的职能单一
组件化:组件化是从ui界面的角度进行划分的,前端的组件化方便UI组件的重用
3. 创建组件
无论哪种方式创建出来的组件,有且只有一个根元素
方式一
如果注册时候使用驼峰命名,myCom1,则调用的标签需要变小写用 - 连接
如果不用驼峰,则全小写即可
<div id="app">
<!-- 如果要使用组件,则直接吧组件名称,以HTML的形式引入到界面中即可 -->
<my-com1></my-com1>
</div>
<script>
// 1 使用Vue.extend来创建全局的Vue组件
var com1 = Vue.extend({
template: '<h3>使用Vue.extend创建的</h3>'//通过template属性,指定了组件要展示的HTML结构
})
// 2 使用Vue.component('组件名称',创建出来的组件模板对象)
Vue.component('myCom1', com1)
//优化:
Vue.component('myCom1', Vue.extend({
template: '<h3>使用Vue.extend创建的</h3>'
}))
var app = new Vue({
el: "#app",
data: {},
})
</script>
方式二
Vue.component('mycom2',{
template:'<h3>方式二</h3>'
})
方式三
<div id="app">
<mycom3></mycom3>
</div>
<template id="temp">
<div>
<h1>template外部定义</h1>
</div>
</template>
<script>
Vue.component('mycom3',{
template:"#temp"
})
var app = new Vue({
el: "#app",
data: {},
})
</script>
内部自定义组件
<div id="app">
<mycom3></mycom3>
<login></login>
</div>
<template id="temp">
<div>
<h1>template外部定义</h1>
</div>
</template>
<template id="temp2">
<h1>内部login</h1>
</template>
<script>
Vue.component('mycom3',{
template:"#temp"
})
var app = new Vue({
el: "#app",
data: {},
methods:{},
//filters:{},
//directives:{},
components:{
//自定义实例内部组件
login:{
template:"#temp2"
}
}
})
</script>
4. 组件中的data 和methods
- 组件可以有自己的data数据
- 组件中的data数据必须是一个方法
- 这个方法的内部必须返回一个对象才行
- 组建中的data数据使用方式和实例中的一样
<div id="app">
<mycom3></mycom3>
</div>
<template id="temp">
<div>
<h1>template外部定义{{msg}}</h1>
</div>
</template>
<script>
Vue.component('mycom3',{
template:"#temp",
data:function(){
return {
msg:"我是组件中的msg"
}
}
})
var app = new Vue({
el: "#app",
})
</script>
5.组件切换
后续。。
6.父组件向子组件传值
7. 使用ref 获取DOM上的元素和组件引用
6、过滤器
1. 全局过滤器格式
概念:Vue.js允许自定义过滤器,可用作一些常见的文本格式化,过滤器可以用在两个地方:mustachc插值和bind表达式。过滤器应该被添加在js表达式的尾部,由管道符指示
<div id="app">
<p>{{msg | msgfil }}</p>
</div>
<script>
// 定义一个过滤器 msgfil
Vue.filter("msgfil", function (msg) {
// replace 方法第一个参数除了是字符串,也可以是正则表达式
return msg.replace(/一/g, "啦啦啦");
})
var app = new Vue({
el: "#app",
data: {
msg: "我还是曾经的那个少年没有一点点改变,一二三四,四三二一"
},
methods: {
}
})
2. 时间格式过滤器
<div id="app">
<p>{{date}}</p>
<p>{{date | datefil }}</p>
</div>
<script>
// 定义一个全局过滤器,进行实践格式化
Vue.filter("datefil", function (date) {
// 根据给定的字符串得到特定的时间
var dt = new Date(date);
// yyyy-mm-dd
var y = dt.getFullYear();
var m = dt.getMonth() + 1;
var d = dt.getDate();
// return y + "-" + m + "-" + d;
return `${y}-${m}-${d}`//字符串模板
})
var app = new Vue({
el: "#app",
data: {
date: "2020.6.4.11:16:23"
},
methods: {
}
})
</script>
优化:
<div id="app">
<p>{{date}}</p>
<p>{{date | datefil("") }}</p>
</div>
<script>
// 定义一个全局过滤器,进行实践格式化
Vue.filter("datefil", function (date, arg) {
// 根据给定的字符串得到特定的时间
var dt = new Date(date);
// yyyy-mm-dd
var y = dt.getFullYear();
var m = dt.getMonth() + 1;
var d = dt.getDate();
// return y + "-" + m + "-" + d;
if (arg & arg.toLowerCase() === "yyyy-mm-dd") {
return `${y}-${m}-${d}`;
} else {
var hh = dt.getHours();
var mm = dt.getMinutes();
var ss = dt.getSeconds();
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
})
var app = new Vue({
el: "#app",
data: {
date: "2020.6.4 11:16:23"
},
methods: {
}
})
</script>
五、网络应用
1、axios网络请求库的使用(ajax)
http://www.axios-js.com/zh-cn/
先导包再使用
使用get或者post方法即可发送对应的请求
then 方法中的回调函数会在请求成功或失败时触发,成功是第一个,失败是第二个
通过回调函数的形参,可以获取响应内容或者错误信息
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
axios.get(地址?查询字符串(格式:key=vlue)).then(function(resonse){},function(err){})
axios.post(地址,参数对象(格式:key:vlue).then(function(response){},function(err){})
地址和key 是接口文档提供
<div id="app">
<input type="button" value="get请求" @click="getjoker">
<input type="button" value="post请求" @click="postjoker">
</div>
<script>
var app = new Vue({
el: "#app",
methods: {
/* 接口1随机笑话
请求地址:https://autumnfish.cn/api/joke/list
请求方式 get
请求参数:num(数字 笑话条数)
响应内容:随机笑话 */
getjoker: function () {
axios.get("https://autumnfish.cn/api/joke/list?num=3").then(function (response) {
console.log(response);
},
function (err) {
console.log(err);
}
)
},
/* 接口2:用户注册
请求地址:https://autumnfish.cn/api/user/reg
请求方式:post
请求参数:username (用户名,字符串)
响应内容:注册是否成功*/
postjoker: function () {
axios.post("https://autumnfish.cn/api/user/reg", { username: "maoni" }).then(function (response) {
console.log(response)
},
function (err) {
})
}
}
})
</script>
)]## 2、axios+vue
axios 回调函数中的this已经改变,无法访问到data中的数据
把this保存起来,回调函数中直接使用保存的this即可
和本地应用最大的区别就是改变了数据来源
<div id="app">
<input type="button" value="get请求" @click="getjoker">
<p>{{joker}}</p>
</div>
<script>
var app = new Vue({
el: "#app",
data:{
joker:"这是笑话"
},
methods: {
/* 接口1 随机笑话
请求地址:https://autumnfish.cn/api/joke
请求方式 get
响应内容:随机笑话 */
getjoker: function () {
var that=this;
axios.get("https://autumnfish.cn/api/joke").then(function (response) {
console.log(response.data);
that.joker=response.data;
},
function (err) {
console.log(err);
}
)
}
}
})
</script>
六、路由
1、什么是路由?
后端路由:对于普通网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上的资源
前端路由:对于单页面的程序来说主要通过URL 中的hash 也就是#之后的来实现不同的页面之间切换,同时,hash 有一个特点:HTTP请求中不会包含hash相关的内容,所以单页面程序中的页面跳转主要通过hash 来实现;
在单页面程序中,这种通过hash 改变来切换页面的方式被称作前端路由
2、路由基本使用
1. 第一步引入 router.js
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
2. 创建一个路由对象
当导入vue-router 包之后,在window 全局对象中就有了VueRouter 构造函数
在new 路由对象的时候可以为构造函数传递一个配置对象,
<div id="app">
<a href="#/login">登录</a>
<a href="#/register">注册</a>
<router-view></router-view>
</div>
<!-- 1、导入路由包 -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script>
//2、 创建个组件模板对象 login
var login = {
template: "<h1>登录组件</h1>"
}
var register = {
template: "<h1>注册组件</h1>"
}
// 3、创建一个路由对象,当导入vue-router包之后,在window 全局对象中就有了VueRouter 构造函数
// 在new 路由对象时候,可以为构造函数传递一个配置对象
var routerObj = new VueRouter({
// 这个路由对象中的route 表示路由匹配规则
routes: [ //每个路由规则都是一个对象,这个规则对象身上必须有两个属性
// 1.path 表示监听哪个路由连接地址
// 2、component 表示前面匹配到的path,则展示 component 属性对应的那个组件 放的是组件模板对象 login
// 此处
{ path: "/login", component: login },
{ path: "/register/", component: register }
]
})
var app = new Vue({
el: "#app",
data: {},
methods: {},
router: routerObj, //将路由规则对象,注册到vue 实例上,用来检测路由变化,然后展示对应的路由组件
})
</script>
3. router-link
router-link: 默认渲染a标签
<div id="app">
<!-- <a href="#/login">登录</a>
<a href="#/register">注册</a> -->
<router-link to ="/login" tag = "span">登录</router-link>
<router-link to ="/register">注册</router-link>
<router-view></router-view>
</div>
4. redirect 重定向
{ path: "/", redirect: "/login" },
{ path: "/login", component: login},
{ path: "/register", component: register }
5. 路由规则中使用query 传参
#/login?id=10
6. 使用param传参
#/login/:id
7. 路由嵌套
children
8. 命名视图实现经典布局
七、综合应用