Vue Node.js iview
一、 安装
1.1步骤
- Node.js zip 文件下载
- Node.js zip 配置步骤
- Vue NPM方式安装
- 安装 Vue cli
cnpm install vue-cli -g - 创建项目
二、 Vue Vue.js
2.1 Vue基础
2.1.1 el:挂载点
el 类似于JQ的选择器
id: | # |
---|---|
class | . |
标签 | 直接使用 |
Vue实例的作用范围是什么呢?
Vue会管理el选项命中的元素及其内部的后代元素
是否可以设置其他的dom元素呢?
可以使用其他的标签,不能使用在HTML和BODY上
2.1.2 data:数据对象
- Vue中用到的数据定义在data中
- data中可以写复杂类型的数据
- 渲染复杂类型数据时,遵守js的语法即可
2.1.3 template 模板
如果template中定义了内容,那么优先加载template,如果没有定义内容那么加载的是#app的模板(html的内容)
2.1.4 ecomponents 模板
- 挂载组件的
<script type="text/javascript">
//1.声子
var App = {
template:'
<div>我是入口组件</div>
'
};
new Vue({
el:'#app',
data(){
return {
}
},
components:{
//2.挂子
App
},
// 3.用子
template : '<App / >'
});
</script>
三、本地应用
3.1 Vue指令
3.1.1 v-text
设置标签的文本值(textContent)
<body>
<div id="app">
<h2 v-text="message">你好</h2>
<!-- 不会显示"你好" -->
<h2 v-text="info">你好</h2>
<!-- 不会显示"你好" -->
<h2>{{ message }}你好</h2>
<!-- 会显示"你好" -->
</div>
</body>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el : "#app",
data:{
message:"YoRHa! ! !",
info:"YoRHa"
}
})
</script>
结果:
3.1.2 v-html
- v-html指令的作用是:设置元素的innerHTML
- 内容中有html结构会被解析为标签
- v-text指令无论内容是什么,只会解析为文本
<body>
<div id="app">
<p v-html="content"></p>
<p v-text="content"></p>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
content: "<a href='https://blog.csdn.net/lushixuan12345'>YoRHa</a>"
}
})
</script>
</body>
结果:
3.1.3 v-on
- v-on指令的作用是:为元素绑定事件
- 指令可以简写为@
- 绑定的方法定义在methods属性中
<body>
<div id="app">
<input type="button" value="v-on指令" v-on:click="doit">
<input type="button" value="v-on指令" @click="doit">
<h2 @click="changeStudent">{{student}}</h2>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
student:"张三"
},
methods:{
doit:function(){
alert("do");
},
changeStudent:function(){
this.student+="是法外狂徒"
},
},
})
</script>
</body>
结果:
点击张三后:
3.1.4 案例:计数器
加加减减到10或0时alert
<body>
<div id="app">
<div class="input-num"></div>
<button @click="sub">
-
</button>
<span>{{ num }}</span>
<button @click="add">
+
</button>
</div>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
num:1,
},
methods:{
add:function(){
if(this.num<10){
this.num++;
}else{
alert("最大为10")
}
},
sub:function(){
if(this.num>0){
this.num--;
}else{
alert("最小为0")
}
},
},
})
</script>
</body>
结果:
3.1.5 v-show
- v-show指令的作用是:根据真假切换元素的显示状态
- 原理是修改元素的display,实现显示隐藏
- 指令后面的内容,最终都会解析为布尔值
- 值为true元素显示,值为false元素隐藏
- 数据改变之后,对应元素的显示状态会同步更新
<body>
<div id="app">
<div id="app">
<img src="地址" v-show="isShow">
<img src="地址" v-show="age>=18">
</div>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
isShow:false,
age:16
}
})
</script>
</body>
3.1.6 v-if
- v-if指令的作用是:根据表达式的真假切换元素的显示状态
- 本质是通过操纵dom元素来切换显示状态
- 表达式的值为true,元素存在于dom树中,为false,从dom树中移除
- 频繁的切换v-show,反之使用v-if,前者的切换消耗小
<body>
<div id="app">
<div id="app">
<p v-if="isShow">我是一个p标签</p>
<p v-if="表达式">我是一个p标签</p></div>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
isShow:false
}
})
</script>
</body>
3.1.7 v-bind
- v-bind指令的作用是:为元素绑定属性
- 完整写法是v-bind:属性名
- 简写的话可以直接省略v-bind,只保留:属性名
- 需要动态的增删class建议使用对象的方式
<body>
<div id="app">
<div id="app">
<img v-bind:src= "imgSrc" >
<img v-bind:title="imgtitle+'!!!!">
<img v-bind:class="isActive?'active':'' ">
<img v-bind:class="{active:isActive}">
</div>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
imgSrc:"图片地址",
imgTitle:"YoRHa",
isActive:false
}
})
</script>
</body>
3.1.8 v-for
- v-for指令的作用是:根据数据生成列表结构
- 数组经常和v-for结合使用
- 语法是( item,index ) in数据
- item和index可以结合其他指令一起使用
- 数组长度的更新会同步到页面上,是响应式的
<body>
<div id="app">
<div id="app">
<ul>
<li v-for="item in arr"></li>
<li v-for="(item,index) in arr" :title="item">{{ index }}{{ item }}
</ul>
</div>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
arr:[1,2,3,4,5]
}
})
</script>
</body>
3.1.9 v-on 补充
- 事件绑定的方法写成函数调用的形式,可以传入自定义参数
- 定义方法时需要定义形参来接收传入的实参
- 事件的后面跟上.修饰符可以对事件进行限制
- .enter可以限制触发的按键为回车
- 事件修饰符有多种 官方文档详情
<body>
<div id="app">
<div id="app">
<input type="button" value="点击" @click="doIt(666)">
<input type="text"@keyup.enter="sayHi">
</div>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
methods: {
doIt:function(p1){
console.log(p1);
},
sayHi:function(){
alert("hello");
},
},
})
</script>
</body>
3.1.10 v-model (双向数据绑定)
- v-model指令的作用是便捷的设置和获取表单元素的值
- 绑定的数据会和表单元素值相关联
- 绑定的数据←→表单元素的值
- 只会体现在uI控件中只能应用在有value属性的
<body>
<div id="app">
<input type="text" v-model="message">
<h2>{{ message }}</h2>
</div>
<!-- 1.开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
message:"YoRHa"
}
})
</script>
</body>
3.2 补充知识点
3.2.1 class选择
<p :class="['box1', 'box2', isShow ? 'box3': '']">YoRHa.....</p>
<p :class="[{'boxl' : isShow}]">YoRHa.....</p>
<p :class="class0bj">YoRHa.....</p>
<script>
new Vue ({
el : '#app',
data(){
isShow: true,
class0bj:{'boxl' : true,' box2’:true,'box3': true}
}
}) ;
</script>
3.2.2 .stop 和.self 的区别
.stop 是真正意义上的阻止冒泡;
.self 只会阻止自己身上冒泡行为的触发,并不会真正阻止霣泡的行为。
3.2.3 :style选择
<p :style="style1">YoRHa.....</p>
<p :style="[style1,style2]">众里寻他千百度.....</p>
<script>
new Vue ({
el : '#app',
data: {
style1 : {'color' : 'green', 'fontSize' : '40px’}
style2: {' font-style' : 'italic'}
}
}) ;
</script>
3.2.4 v-for
- count从 1 开始计算
<p v-for="count in 100">第{{count}}次,总计100次</p>
3.2.5 Array.prototype.slice.call(arguments)
- 能将具有length属性的对象(key值为数字)转成数组。[]是Array的示例,所以可以直接使用[].slice()方法
var obj = {0:'hello',1:'world',length:2};
console.log(Array.prototype.slice.call(obj,0));//["hello", "world"]
没有length属性的情况:
var obj = {0:'hello',1:'world'};//没有length属性
console.log(Array.prototype.slice.call(obj,0));//[]
3.2.6 some 与 filter
- some 用于检测数组中的元素是否满足指定条件 举例:验证数组中是否有字段"YoRHa"
- filter 用于把Array的某些元素过滤掉,然后返回剩下的元素
let arr = [1,2.4,5,6,9.10,15];
let r = arr.filter( (x)=>{
return x %2 !== 0;
);
结果: [1.5,9.15]
3.2.7 ref $refs
- ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
<template>
<div id="app">
<div ref="testDom">11111</div>
<button @click="getTest">获取test节点</button>
</div>
</template>
<script>
export default {
methods: {
getTest() {
console.log(this.$refs.testDom)
}
}
};
</script>
3.2.8 slot
<script>
vue.component('myLi',{
template: '
<!--插槽内置组件slot做为承载分发内容的出口-->
<button>
<slot name='h2'></slot>
<slot name='h3'></slot>
</button>
});
var Vcontent = {
template:'
<div>
<ul>
<myLi>
<h2 slot='h2'>h2</h2>
<h3 slot= 'h3' >h3</h3>
</myLi>
</ul>
</div>
'
}
</script>
3.2.9 过滤器
- 局部 过滤器
<script>
var App ={
data(){
return {
price: 0
}
},
template:'
<div>
<input type="number" v-model = ' price' / >
<h3>{{price | mycurrentcy}}</h3>
</div>
',
filters:{
//1.声明过滤器
myCurrentcy:function( value){
return"¥" + value
}
}
</script>
- 全局 过滤器
<script>
Vue.filter( ' myReverse ' ,function(value){
})
var App ={ ... }
</script>
三、 通信
3.1通过prop传值 [父传子]
<script>
//全局组件
//第一个参数是组件的名字第一个参数是options
//1.Parent 2.Child
vue.component('Child',{
template:'
<div>
<p>我是一个孩子组件</p>
<input type="text" v-model = 'childData' / >
</div>
',
prop:['childData ']
});
//先给父组件中绑定自定义的属性
//在子组件中使用props接收父组件传递的数据
//可以在子组件中任意使用
vue.component('Parent',{
data( ){
return {
msg:"我是父组件的数据"
}
},
template:'
<div>
<p>我是一个父组件</p>
<Child :childData = 'msg'/>
</div>
'
});
//1.声子
var App = {
template: '
<div>
<Parent />
</div>
'
};
new Vue({
el:'#app',
data(){
return {
}
},
components:{
//2.挂子
App
},
// 3.用子
template : '<App / >'
});
</script>
3.2通过绑定事件传值 [子传父]
<script>
//全局组件
//第一个参数是组件的名字第一个参数是options
//1.Parent 2.Child
vue.component('Child',{
template:'
<div>
<p>我是一个孩子组件</p>
<input type="text" v-model = 'childData' @input='changeValue(childData)' / >
</div>
',
prop:['childData '],
method:{
changeValue(val){
//自定义的事件一定通过$emit()去触发
// $emit(自定义的事件名,消息)
this.$emit('childHandler',val)
}
}
});
//在父组件绑定自定义的事件
//在子组件中触发原生的事件在函数中使用$emit触发自定义的childHandler
vue.component('Parent',{
data( ){
return {
msg:"我是父组件的数据"
}
},
template:'
<div>
<p>我是一个父组件</p>
<Child :childData='msg' childHandler='childHandler'/>
</div>
',
methods:{
childHandler(val){
console.log(val)
}
}
});
//1.声子
var App = {
template: '
<div>
<Parent />
</div>
'
};
new Vue({
el:'#app',
data(){
return {
}
},
components:{
//2.挂子
App
},
// 3.用子
template : '<App / >'
});
</script>
3.3 监听
<div id=" app">
<input type="text" v-model = 'msg ' >
<h3>{{msg}}</h3>
</div>
<script>
new Vue({
el: " #app' ,
data(){
return {
msg:''
}
},
watch: {
msg:function( newV , oldv){
console.log( newV ,oldV);
}
}
});
</script>
3.4 attrs和$listeners[父子]
A->C
A的 props: ['message'],
A的template里 : <B v-bind="$attrs" v-on = '$listeners' ></B>
B的template里 : <C v-bind="$attrs" v-on = '$listeners'></C>
B的template里 : <div @click = 'cclickHandler '>{{$attrs.messagec}}</div>
3.5 中央事件总线[兄弟]
四、 路由
- 传统开发方式url改变后,立刻发生请求响应整个页面,有可能资源过多,传统开发会让页面出现白
- SPA单页面应用Single Page Application
- 锚点值改变后 不会立刻发送请求,而是在某个合适的时机,发起ajax请求页面局部渲染
- 优点︰页面不立刻跳转用户体验好
4.1 下载 vue-router
npm install vue-router
4.2 配置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
<!--1.引入vue的模块-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!--2.引入vue-router模块-->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
var login = {
template:
`<div>
<div>我是Login页面</div>
<router-link to="/login/mine">mine</router-link>
<router-link to="/login/about">about</router-link>
<router-view></router-view>
</div>
`
};
var index = {
template:
`<div>我是index页面</div>`
};
var mine = {
template:
`<div>我是mine页面</div>`
};
var about = {
template:
`<div>我是about页面</div>`
};
//3.创建router对象
var router = new VueRouter({
//4.配置路由对象
routes:[
//路由匹配的规则
{
path:"/login",
name:login,
component:login,
children:[
{
path:'mine',
name:mine,
component:mine,
},
{
path:'about',
name:about,
component:about,
},
],
},
{
path:"/index",
name:index,
component:index,
}
]
});
var App = {
template:
`<div>
<div>我是首页</div>
<router-link to="/login">login</router-link>
<router-link to="/index">index</router-link>
<router-view></router-view>
</div>
`
};
new Vue({
el : "#app",
data(){
return {
}
},
components: {
App
},
//6.交给vue实例化管理
router,
template:'<App/>'
});
</script>
</body>
</html>
4.3 响应路由参数的变化
- 提醒一下,当使用路由参数时,例如从/user/foo导航到/user/bar ,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
//在当前的组件内部监听路由信息的变化
watch: {
'$route'(to,from){
console.log(to) ;
console.log (from) ;
this.msg = to.params.id ;
//可以发送ajax请求
}
4.4 重定向
const router = new VueRouter({
routes:[
{ path: '/a',redirect:'/b'}
})
4.5 keep-alive
- 组件缓存
var App ={
template : '
<div>
<router-link to= ' /timeline'>首页</router-link>
<router-link to=' /pins '>沸点</router-link>
<keep-alive>
<router-view</router-view>
</keep-alive>
</ div>
4.6 meta的使用_权限控制 (与4.7结合)
{
path: ' /blog ',
component:Blog,
//给未来的路由做权限控制
meta:{
//证明用户访问该组件的时候需要登录
auth:true
}
}
4.7 路由守卫 (与4.6结合)
router.beforeEach((to, from, next) =>{
console.log(to);
console.log(from) ;
if (to.meta.auth) {
//用户点击了博客链接该用户需要登录
next({
path:'/login'
})
}else{
//直接放行
next();
}
//...
next( );
})
4.8 Axios
4.8.1 安装
- 使用npm:
npm install axios
- cdn
<script src="https://unpkg.com/axios/dist/axios.min.js" ></script>
4.8.1 使用
vue.prototype.$axios = axios;
挂载全局 所有组件可用
vue.prototype vue的原型
$axios 命名
= axios 引用
.方法 | 处理 |
---|---|
.then(res=>{}) | 成功处理 |
.catch(err=>{}) | 失败处理 |
axios.get | get请求 |
---|---|
axios.post | post请求 |
4.8.2 并发使用
methods:{
sendAjax(){
//请求1 get :
//请求2 post:/add
//配置url
this.$axios.defaults.baseURL = 'http://127.0.0.1:8888/ ' ;
var r1 = this.$axios.get( ' ' );
var r2 = this.$axios.post( ' add ' ,'a=1 ' );
this.$axios.all([r1,r2])
.then(this.$axios.spread((res1,res2x)=>{
//全部成功
}))
.catch(err=>{
//其一失败
console.log(err);
})
}
}
4.8.3 请求 / 相应 拦截器
methods: {
sendAjax(){
//添加请求拦截器
this.$axios.interceptors.request.use((config)=>{
console.log(config)
return config;
},function(err){
return Promise.reject(err);
}
});
this.$axios.interceptors.response.use((response)=>{
//对响应数据做点什么
console.log(response)
return response;
},function(error) {
//对响应错误做点什么
return Promise.reject(error);
});
this.$axios.get('http: /7127.0.0.1:8888/')
.then(res=>{
console.log(res);
})
.catch(err=>{
console.log(err);
})
}
}
五、 webpack
5.1 下载安装使用
npm install webpack@xxx.xxx.xxx -D
xxx:版本
-D 安装在生产环境上
程序里使用:
// esModule的模块导入
import Vue from './vue.js'
import App from './App.js'
//抛出对象
export default app;
打包:
webpack main.js build.js
打包 从哪里 【空格】 到哪里
抛出:
//声明并导出
export var num1工 2;//作为一整个对象key导出
//声明再导出
var num2 = 3;
export {num2};
//export default app;
export function add(x,y){
return console.log(x+y);
}
// html
import{num1,num2,add} from './App.js '
console.log (num1);
console.log(num2);
add(3,5);