vue路由

vue-router

基本使用

  • 下载 npm i vue-router --save
  • 1: 在main.js中引入该对象 import VueRouter from 'vue-router';
  • 2:安装插件 Vue.use(VueRouter);
  • 3: 配置路由规则(创建一个关于当前实例的路由对象)
    • let router = new VueRouter(构造选项);
  • 构造选项: { routes:[ {锚点值,显示什么} ,{锚点值,显示什么} ] }
  • 4:让Vue运行实例能拿到router配置(路由配置)传递给new Vue
  • 5:留坑 <router-view></router-view>
1
2
3
4
5
6
7
8
9
10
11
12
//安装插件
Vue.use(VueRouter); // 到底做了什么
//创建路由对象,配置路由规则
let router = new VueRouter({
routes:[
{// #/home
//路是哪(必须) //显示什么
path:'/home', component:Home
}
]
});
  • 使用方法: <router-link to="/xxxx">电影</router-link>
  • 当这个元素的锚点值与当前的锚点值匹配以后,vue-router就会为其自动加上
  • router-link-active样式 可以方便我们设置用户点中后的效果,以及锚点匹配后的效果
  • 查询字符串
    • 1:去哪里
    • <router-link :to="{name:'bj',query:{id:1} }">查询字符串</router-link>
    • 2:导航(路由规则)
    • {name:'bj' ,path:'/beijing'} -> 生成: href="#/beijing?id=1"
    • 3:去了干嘛
    • this.$route.query.id
  • path的方式
    • 1:去哪里
    • <router-link :to="{name:'bj',params:{id:1} }">查询字符串</router-link>
    • 2:导航(路由规则)
    • {name:'bj' ,path:'/beijing/:id'} -> 生成: href="#/beijing/1"
    • 3:去了干嘛
    • this.$route.params.id

vue-router中的对象

  • 路由信息对象 $route
  • 路由功能对象 $router
  • 安装插件的时候,挂载的相关属性
  • 如果需要在vue中挂载全局的属性供所有组件使用
    • Vue.prototype.xxx = config;
    • this.xxx; //获取配置

多视图(命名视图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//用以下三个组件替代home一个组件更灵活,便于维护
import HomeHeaderVue from './c/HomeHeaderVue.vue';
import HomeBodyVue from './c/HomeBodyVue.vue';
import HomeFooterVue from './c/HomeFooterVue.vue';
// import Home from './Home.vue'; //头、尾、中 替换成3个组件来完成渲染
//安装插件
Vue.use(VueRouter);
//创建路由对象,配置路由规则
let router = new VueRouter({
routes:[
{
name:'home',path:'/home',
components:{
homeHeader:HomeFooterVue,
default:HomeBodyVue,
homeFooter:HomeHeaderVue,
}
}
]
});

嵌套路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//子路由的视图显示的组件
import Music from './Music.vue';
import Movie from './Movie.vue';
//安装插件
Vue.use(VueRouter);
//创建对象配置路由规则
let router = new VueRouter();
//router-view包含router-view
router.addRoutes([
{ name:'home',path:'/home',component:Home,
children:[
{ name:'home.music',path:'music',component:Music},
{ name:'home.movie',path:'movie',component:Movie},
] }//路由规则存在子路由
]);
--------------------------------------------------------------
//home
<div class="d">我是广告</div>
<router-link :to="{name:'home.music'}">音乐</router-link>
<router-link :to="{name:'home.movie'}">电影</router-link>
<!-- 用户显示子视图个性化数据 -->
<router-view></router-view>

重定向及404

{path:’/‘,redirect:{name:’xxx’} }-> 跳转到另一个路由

1
2
3
4
5
6
7
8
9
let router = new VueRouter({
routes:[
// {path:'/',redirect:'/home'}, 默认的页面
{path:'/',redirect:{name:'home'} }, //维护成本更低
{ name:'home',path:'/myhome',component:Home },
{ path:'*',component:NotFound}, //路由规则是从上到下匹配的
]
});

编程式导航

  • 获取信息对象$route
  • 具备操作行为的对象$router
  • 编程式导航更为灵活,可以以各种事件来触发,并且前后可以加入操作的代码
  • 跳转: this.$router.push({ name:’home’,query:{id:1})
  • 前进和后退: this.$router.go(-1) 后退 go(1)前进

scoped

  • 在style标签上 加上scoped属性
  • 让当前的style样式只对同文件中的template有效

前端权限控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
router.beforeEach((to, from, next) => {
//假如后台返回 当前用户 只有goods类的权限,说明当前用户就不能进入photo
let permissions = 'goods';//假如服务器返回权限
console.log('to',to);
console.log(to.name.startsWith(permissions));
console.log('from',from);
//next(); //放行 行为: 1:放行 ,2:不放行 3:重定向
if(to.name.startsWith(permissions)){
next();
}else{
alert('您好,您不具备权限访问该页面');
next(false);
}
});

vue组件

vue组件

组件内使用子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
APP.vue
-------------------------------------------
<template>
<div>
<!-- 要使用header.vue -->
<header-vue></header-vue>
<!-- 要使用body.vue -->
<body-vue></body-vue>
<!-- 要使用footer.vue -->
<footer-vue></footer-vue>
</div>
</template>
---------------------------------------------
<script>
// 1:引入组件对象
import HeaderVue from './header.vue'; //声明 var HeaderVue
import BodyVue from './body.vue';
import FooterVue from './footer.vue';
//在options中声明依赖
export default {
data(){ //属性
return {
}
},
methods:{ //行为
},
components:{ //对象
// 名 : 组件对象
HeaderVue:HeaderVue, // 在vue中,大写字母也可以
BodyVue,
FooterVue
}
}
</script>

全局组件

(注册一次,大家都能随意使用)Vue.component('组件名',组件对象);

1
2
//用谁来注册全局组件 -Vue
Vue.component('ShowVue',ShowVue); //使用<show-vue></show-vue>

父传子组件

传递参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
父用子组件,父向子组件传递参数
<son-vue text="呵呵哈哈" text2="212121"></son-vue>
------------------------------------------------------
子组件接收参数放到页面中
<script>
export default {
data(){
return {
}
},
//向外接受的一些值 props:['text']
props:['text','text2']
}
</script>

子向父通信

同一个实例 new Vue

connect.js

1
2
3
import Vue from 'vue';
export default new Vue();

1:父组件先$on(‘事件名’,回调函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Connector.$on('call',(place) => { //默认是只要emit就触发 //place 是子组件向父组件传递的参数
//console.log(this.num);
//判断触发次数,手动关闭事件
if(this.num >2){
//手动关闭
Connector.$off('call');
}
this.num ++;
console.log('儿子打电话了,我要冲出去找他!',place);
});
//只接受1次
// Connector.$once('call',function(place){
// console.log('儿子打电话了,我要冲出去找他!',place);
// });

2:子组件$emit(‘事件名’,数据参数)

1
Connector.$emit('call','上海');

3:重要on还是emit 必须是同一个对象 Vue的实例

  • this组件(vueComponent)对象本身是继承于new Vue的
  • $once 只执行一次
  • $off 清除事件

vue过滤器

vue过滤器

vue1.x中,默认还是提供一些过滤器的

vue2.x中,1个都没有了,而是通过简单的过滤器创建方式来替代

组件内的filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在options中加入属性filters,是一个对象
- 和methods类似
- key:过滤器名
- value:过滤器具体实现
- 使用方式 {{xxx| 过滤器名}}
<template>
<div>
请输入: <input type="text" name="" v-model="text">
反转后内容:{{text|reverseData}}
</div>
</template>
<script>
// 将当前输入的内容反转
export default {
data(){ //属性
return {
num:1,
text:'',
}
},methods:{}
,filters:{//组件内的过滤器
reverseData(value){ //value 是形参
// 过滤器名 过滤器实现
// 以上等同 reverseData:function(value){}
return value.split('').reverse().join('');
}
}
}
</script>

全局的filter

1
2
3
4
5
6
7
- Vue.filter('过滤器名',fn)
- fn(value形参){ return 显示值}
Vue.filter('reverseData',function(value){
return value;
});

method构造filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
// 将当前输入的内容反转
export default {
methods:{
//当v-for涉及到的值发生改变,能否触发重新渲染
myFilter(heros){
console.log(this);
let tmp = [];
heros.forEach((ele) =>{
//this.range的改变,影响v-for重新计算
if(ele.score >= this.range){// this.range:19/59/89
tmp.push(ele);
}
});
return tmp;
}
}
}
</script>

vue函数

数据观察

看文档的对象分类

  • 全局配置
    • Vue.config.xxx
  • 全局API
    • Vue.xxxx
  • 选项(options)
    • new Vue(options)
    • export default options
  • 实例
    • 在组件内使用的this VueComponent对象
    • new Vue() Vue$3对象

生命周期钩子

用于发送ajax请求,或获取dom上的元素

  • beforeCreate 未完成数据观察,给组件数据赋值无效
  • (常用)created 已完成数据观察,发起请求获取动态数据,给data属性赋值
  • beforeMount 装载数据之前,此时DOM还未生成
  • (常用)mounted 装载数据之后,此时操作DOM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
export default {
data(){
return {
text:'text' // 2
}
},
beforeCreate:function(){ //完成数据观察之前
//操作不了组件数据,做一些相关配置性的东西
this.text = 'abc';// 1
console.log('beforeCreate');
},
created(){//已经完成了数据观察
// 发起请求获取后台数据,将数据进行初始化
this.text = 'created';// 3
console.log('created');
},
beforeMount(){ // 将this.text等属性,装载到DOM上,之前
console.log('beforeMount');
},
mounted(){
console.log('mounted');
}
}
</script>

触发多次(结合计算属性或者监视来完成就可以)

  • beforeUpdate 数据发生改变,更新DOM之前
  • updated 数据发生改变,更新DOM之后

路由钩子

用于判断离开当前路由和进入当前路由所做的事情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
beforeRouteEnter (to, from, next) {
在渲染该组件的对应路由被 confirm 前调用
不!能!获取组件实例 `this`
因为当钩子执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
导航离开该组件的对应路由时调用
可以访问组件实例 `this`
next(vm=>{ //最终都是放行
// 通过vm访问实例
vm.title = title;
});
}

获取元素

  • 1:在dom元素上写上ref=”名称”
  • 2:获取元素 this.$refs.名称
1
2
3
4
5
6
<span ref="s"></span>
---------------------------
created(){ //完成数据观察,通过ajax对数据进行操作
console.log(this.$refs.s);
console.log('created11');
},

监视watch

  • 简单监视 针对 xxx=123; 改变了引用
  • options: watch:{ data中是属性:function(newV,oldV){} }
  • 深度监视 针对 xxx.xxx.xxx 改变了对象的属性的引用
  • options: watch:{ data中的属性:{ deep:true,handler:fn } }
  • 1:监视的属性是data中存在的属性
  • 2:对于要监视元素的属性改变,就使用深度监视
  • 3:其监视一个属性,就是一段监视代码,不能一次监视多个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{{persons}}
<button @click="change">改变人的数据</button>
-------------------------------------------------
export default {
data(){
return {
obj:{name:'jack'},
persons:[{name:'后羿'},{name:'芈月'}]
}
},
watch:{
obj:function(newV,oldV){
console.log('改变发生了');
console.log(newV,oldV);
},
//简单监视
// persons:function(newV,oldV){
// console.log('改变发生了');
// console.log(newV,oldV);
// }
// 深度监视
persons:{
deep:true,
handler:function(newV,oldV){
console.log('改变发生了');
console.log(newV,oldV);
}
}
},

计算属性(options->computed)

  • 监视的属性是data中存在的属性
  • computed:是一个对象 key:计算名称 value:计算的具体操作
  • 计算的具体操作: function 还具备返回值
  • 这个返回值还可以在页面中显示
  • 1:计算属性中,如果原值相同,会走缓存而不会触发函数调用
  • 2: 计算属性可以监视多个this.相关值的改变
  • 3: 计算属性可以返回多个参数,以对象的形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<template>
<div>
<input type="text" name="" v-model="n1"> +
<input type="text" name="" v-model="n2"> *
<input type="text" name="" v-model="rate">
结果 {{result.total}} 一共输入了几个数{{result.count}}
</div>
</template>
<script>
export default {
data(){
return {
n1:1,
n2:1,
rate:1,
}
},
computed:{
result:function(){;
console.log('触发了监视'); //当原值相同的时候,会走缓存
//this.xxx在这里使用过以后,就会产生监视
let sum = ((this.n1-0) + (this.n2-0) ) * this.rate;
//模拟计数3
let num = 3;
return {
total:sum,count:num
}
}
}
}
</script>

给vue添加的属性不做双向数据绑定

1
2
3
4
5
6
7
8
9
10
this.goodsList = res.data.message;
//给元素添加属性,是否选中,true ,商品数量,通过prods赋值
this.goodsList.forEach(ele => {
//非法操作,vue不做双向数据绑定(该对象不是响应式)
// ele.isChecked = true;
// ele.num = prods[ele.id]; //数量
//vue中直接添加属性,不能响应式的,需要特定的函数
this.$set(ele,'isChecked',true);
this.$set(ele,'num',prods[ele.id]);

vue前奏

vue前奏

vue介绍

  • weex 能够转换vue代码,成为移动端原生应用 ios Android PC
  • vuex 凡是大型项目必用

核心特点

  • 组件化,组件化比模块化更分
    • 组成部件
    • 组件: 模板template+ 动态效果script + 样式style + 逻辑(使用Math(模块))
    • 组件内使用模块,模块内不使用组件
  • 双向数据流(双向数据绑定的现象)
    • 内存(js对象的属性)发生改变影响页面
    • 页面发生改变影响内存(js对象的属性)
  • 数据驱动
    • 内存的属性发生改变,驱动页面显示做调整
  • 双向数据绑定实现原理
    • 数据劫持
  • IE9以下不支持
  • 善于开发单页应用SPA

vue文件相关操作

1-创建index.html 并且在页面中留下一块div(id),未来vue将生成好的代码放入进来

1
2
<!-- 1:留坑,主体部分显示 -->
<div id="app"></div>

2-在(入口)main.js中, 引入Vue对象(构造函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//1: 引入Vue
import Vue from 'vue';//逐级向上查找node_modules下面有没有vue文件夹
// require('ejs'); // 引入的时候。,逐级向上查找node_modules下面有没有ejs文件夹
//2:创建并引入App.vue
import App from './App.vue';
//3:构建vue 实例
new Vue({
//目的地
el:'#app', //将数据渲染到id为app的元素上 innerHTML
render:function(creater){ //想象成vue-template-compiler
return creater(App); // return <ul><li>哈哈呵呵</li></ul>
}
//render:<ul><li>哈哈呵呵</li></ul>
})

vue调试工具

  • 全局安装 webpack-dev-server
  • 命令 npm i -g webpack-dev-server
    • 由于全局安装未知原因导致无法直接改代码看效果(热替换)
  • 在当前项目中,安装一个跟项目走的webpack-dev-server
  • ..\\node_modules\\.bin\\webpack-dev-server --inline --hot --open --port 9999
  • 启动的时候 当前目录存在webpack-config.js文件
  • 命令 webpack-dev-server --inline --hot --open --port 9999
    • inline 自动刷新
    • hot 热替换 ,不重启(不刷新),
    • open 自动打开默认的浏览器
    • –port 端口号

package.json 配置热替换快捷键

1
2
3
4
"scripts": {
"dev": "node_modules\\.bin\\webpack-dev-server --inline --hot --open --port 9999", // npm run dev 开发
"build": "webpack" // npm run build 上线
},

vue指令

vue常用指令

v-text

元素的innerText

1
2
3
<div v-text="text"></div>
-------------------------------
text:'helllo,大家好!',

v-html

元素的innerHTML

1
2
3
<div v-html="htmlText"></div>
-------------------------------
htmlText:'<h1>哈哈呵呵</h1>',

v-if

flase的时候,元素不会被插入,true就会插入元素,空串代表flase

1
2
3
<div v-if="vIf">我是v-if</div>
-------------------------------
vIf:true,

v-show

false给元素加上display: none

1
2
3
<div v-show="vShow">我是v-show</div>
-------------------------------
vShow:true

v-model

双向数据绑定(将元素的value值与内存中变量的属性值做绑定)

1
<input type="text" name="" v-model="num">

v-bind

单向数据绑定(js变量到页面的输出)

1
<input type="text" :name="text" :value="text">

class结合v-bind使用

1
2
3
4
5
<div v-bind:class="class1">方块1</div>
<div :class="class2">方块2</div>
-------------------------------
class1:'green',
class2:'red'

methods和v-on的使用

1
2
3
4
5
6
7
<button @click="change">大的变化</button>
-------------------------------
methods:{ //组件所提供的函数,
change(){
//事件
}
}

v-for的使用

1
2
3
4
5
6
<ul>
<!-- v-for="任意名 in 组件数据(数组)" :key="唯一标识" -->
<li v-for="(hero,index) in heros" :key="index">
{{hero.name}} {{hero.age}} {{index}}
</li>
</ul>

webpack配置

webpack配置文件

生产配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
'use strict';
const path = require('path');
//html插件
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
//入口
entry:{
main:'./src/main.js'
},
output:{
//资源产出路径
path:path.join(__dirname,'dist'),
filename:'build.js'
},
module:{
loaders:[
{ //处理css
test:/\.css$/,
loader:'style-loader!css-loader!autoprefixer-loader'
},
{
test:/\.less$/,
loader:'style-loader!css-loader!autoprefixer-loader!less-loader'
},
{
//处理文件
test:/\.(jpg|png|svg|ttf|gif)$/,
loader:'url-loader',
options:{
limit:4096
}
},
//处理js
{
test:/\.js$/,
loader:'babel-loader',
//排除node_modules目录
exclude:/node_modules/,
//options就交给.babelrc文件来说明
},
//vue
{
test:/\.vue$/,
loader:'vue-loader'
},
//处理vue-preview中的ES6
{
test: /vue-preview.src.*?js$/,
loader: 'babel-loader'
}
]
},
plugins:[
new htmlWebpackPlugin({
template:'./src/index.html'
})
]
}

上线配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use strict';
const path = require('path');
const fs = require('fs');
const version =JSON.parse(fs.readFileSync('./package.json','utf8')).version;
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const webpack = require('webpack');
console.log(version);
//html插件
const htmlWebpackPlugin = require('html-webpack-plugin');
//压缩js插件
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
//入口(也可以是多入口)
entry:{
main:'./src/main.js',
vendors:['vue','axios','vue-router','vue-preview','moment']
},
output:{
//资源产出路径
path:path.join(__dirname,'dist_production'),
publicPath:'/',//对应请求的资源不走相对路径,
//再公司中,最终就是加上http://www.xxx.com/
// filename:'build.js?v='+version
// filename:'js/[name].[chunkhash].js', // main.312321.js
//根据文件的不同,该标识会不一样,文件发生修改,该值也会不一样,
//文件的指纹(数字签名)
},
module:{
loaders:[
{ //处理css
test:/\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader?minimize=true!autoprefixer-loader"
})
},
{
test:/\.less$/,
loader:'style-loader!css-loader!autoprefixer-loader!less-loader'
},
{
//处理文件
test:/\.(jpg|png|svg|ttf|gif)$/,
loader:'url-loader',
options:{
limit:4096,
name:'assets/[name].[hash].[ext]'
}
},
//处理js
{
test:/\.js$/,
loader:'babel-loader',
//排除node_modules目录
exclude:/node_modules/,
//options就交给.babelrc文件来说明
},
//vue
{
test:/\.vue$/,
loader:'vue-loader'
},
//处理vue-preview中的ES6
{
test: /vue-preview.src.*?js$/,
loader: 'babel-loader'
}
]
},
plugins:[
new UglifyJSPlugin(),//压缩js
new ExtractTextPlugin("css/[name].[contenthash:6].css"),
//manifest会单独产出一个文件,关联着和main之间的关系
new webpack.optimize.CommonsChunkPlugin({
names:['vendors','manifest']
}),
new htmlWebpackPlugin({
template:'./src/index.html'
})
]
}
console.log(process.argv);
//做判断,究竟当前运行的是npm run build 还是run dev
if(process.argv.length === 2){
//生产环境
module.exports.output.filename = 'js/[name].[chunkhash].js'; // main.312321.js
//让vue知道是生产环境不输出日志
module.exports.plugins.push(new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}));
}else{ //参数个数为7
//开发环境
//webpack-dev-server启动的时候,没有真实的生成文件,chunkhash就用不了
module.exports.output.filename = 'js/[name].js';
}

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
"name": "cms_project_sh9",
"version": "1.0.3",
"description": "我们的项目",
"main": "index.js",
"scripts": {
"dev": "node_modules\\.bin\\webpack-dev-server --inline --hot --open --port 9999",
"build": "webpack",
"test": "ipconfig /all && node -v"
},
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer-loader": "^3.2.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.5",
"extract-text-webpack-plugin": "^2.1.2",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.30.1",
"less": "^2.7.2",
"less-loader": "^4.0.5",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"vue-loader": "^13.0.4",
"vue-template-compiler": "^2.4.2",
"webpack": "^3.5.5",
"webpack-dev-server": "^2.7.1"
},
"dependencies": {
"axios": "^0.16.2",
"mint-ui": "^2.2.9",
"moment": "^2.18.1",
"vue": "^2.4.2",
"vue-preview": "^1.0.5",
"vue-router": "^2.7.0"
}
}

webpack跨域代理

webpack跨域代理

webpack.config.js配置

1
2
3
4
5
6
7
8
9
10
11
12
//配置跨域代理
devServer: {
proxy: {
"/v2": {
target: "https://api.douban.com",
//默认代理是自己,请求devserver的服务器去了
changeOrigin: true,
}
},
}

请求的代码

1
2
3
4
5
6
7
8
9
export default {
created(){
this.$ajax.get('/v2/book/1220562')
.then(res=>{
console.log(res);
})
}
}

Angular路由

Angular路由

ngRouter

语法

1
2
3
4
5
6
7
8
9
10
11
12
模块对象.config(function($routeProvider){
// $routeProvider 配置路由的对象 想象成 保安大爷
$routeProvider.when('锚点值',{
templateUrl:''
})
<div ng-view></div>
angular会在页面中查找拥有ng-view指令的元素 并且将获取过来的内容放到这个元素里面
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider
.when('/index',{
templateUrl:'./tpl/index.html',
//template:'<div>首页</div>',
controller:'indexCtrl'
})
.when('/list',{
templateUrl:'./tpl/list.html',
//template:'<div>列表页</div>',
controller:'listCtrl'
})
})
myApp.controller('indexCtrl',function($scope){
$scope.msg = "我是首页的内容";
})
myApp.controller('listCtrl',function($scope){
$scope.msg = "我是列表页的内容";
})

路由传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<ul>
<li>
<a href="#!/article/1/我是第1篇文章">我是第1篇文章</a>
</li>
<li>
<a href="#!/article/2/我是第2篇文章">我是第2篇文章</a>
</li>
<li>
<a href="#!/article/3/{a:1,b:2}">我是第3篇文章</a>
</li> // 跳转的页面写上实际参数
</ul>
/*
1.向被传参页面的路由中写 参数占位符
2.在跳转链接中将实际参数 写上
3.在被传参页面的控制器中获取 传递过来的参数
*/
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider
.when('/index',{
templateUrl:'./tpl/index.html',
controller:'indexCtrl'
})
.when('/list',{
templateUrl:'./tpl/list.html',
controller:'listCtrl'
})
.when('/article/:id/:title',{ // 参数占位符
templateUrl:'./tpl/article.html',
controller:'articleCtrl'
})
})
myApp.controller('indexCtrl',function($scope){
})
myApp.controller('listCtrl',function($scope){
})
myApp.controller('articleCtrl',function($scope,$routeParams){
// $routeParams 对象类型 里面存储的是 当前路由的参数
// console.log($routeParams.id)
// console.log($routeParams['id'])
console.log( $routeParams )
$scope.id = $routeParams.id;
})

ui-router

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
body ng-app="myApp">
<!--
在A标签中可以直接以#!/的形式书写 但是不建议
-->
<a href="#!/index">首页</a>
<a href="#!/list">列表页</a>
<br/>
<!--
在ui-router中 提供了一个ui-sref指令
将路由的name值填在这里即可
ui-router会自动查找name至对应的锚点链接
并生成对应的链接地址
-->
<a ui-sref="index">首页</a>
<a ui-sref="list">列表页</a>
<div ui-view></div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="node_modules/angular-ui-router/angular-ui-router.min.js"></script>
<script>
/*
路由模块的名字是ui.router 把这个名字作为主模块的依赖模块
*/
angular.module('myApp',['ui.router'])
/*
ui-router中提供了一个$stateProvider对象,用来配置路由
state方法负责具体的配置
参数以对象的形式存在
name:当前路由的名字(状态)
url:当前路由的url锚点值
template:当前路由的模板
这里也有templateUrl属性 和ngRoute中的意思一样
*/
.config(['$stateProvider',function($stateProvider){
$stateProvider
.state({
name:'index',
url:'/index',
template:'<div>首页</div>'
})
.state({
name:'list',
url:'/list',
template:'<div>列表页</div>'
})
}])
</script>
</body>

ui-router传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<body ng-app="myApp">
<!--
在路由名字的后面加上一个小括号 -> 类似于函数小括号
在小括号中写一个对象 并把参数写在对象中 -> 类似于给函数传递了一个对象类型的值
-->
<a ui-sref="index">首页</a>
<a ui-sref="list({pagenumber:1,pagesize:10})">列表页</a>
<div ui-view></div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="node_modules/angular-ui-router/angular-ui-router.min.js"></script>
<script>
angular.module('myApp',['ui.router'])
.config(['$stateProvider',function($stateProvider){
$stateProvider
.state({
name:'index',
url:'/index',
template:'<div>首页</div>'
})
.state({
name:'list',
// 路由配置中参数的配置和ngRoute一样
url:'/list/:pagesize/:pagenumber',
template:'<div>列表页</div>',
controller:'listCtrl'
})
}])
.controller('listCtrl',['$stateParams',function($stateParams){
/*
在获取的参数的时候 ui-router提供了一个 $stateParams 对象
*/
}])
</script>
</body>
angular.module("uiRouter", ["ui.router"])
.config(function ($stateProvider,$urlRouterProvider) {
$stateProvider
.state({
url: "/index",
name: "index",
templateUrl: "indexTpl",
// controller: ""
})
.state({
url: "/list",
name: "list",
templateUrl: "listTpl",
// abstract:true,
// controller: "listCtrl"
})
.state({
url: "/article/:id",
name: "article",
// params:{id:1}, params可以传参
templateUrl: "articleTpl",
controller: "articleCtrl"
})
$urlRouterProvider.otherwise('article');
})
.controller("articleCtrl",["$scope","$stateParams",function($scope,$stateParams){
console.log($stateParams)
}])
</script>
<script type="text/ng-template" id="indexTpl">
<span>我是首页</span>
</script>
<script type="text/ng-template" id="listTpl"> templateUrl可以是模板id
<a ui-sref="article({id:2})">跳转详情</a> 模板中可以传参
<!-- 我是列表 -->
</script>
<script type="text/ng-template" id="articleTpl">
<ul>
<li>文章</li>
<li>而已</li>
</ul>
</script>

ui-router 多view用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<body ng-app="myApp">
<a ui-sref="index">首页</a>
<a ui-sref="list">列表页</a>
<!--
在ui-router中可以存在多个 ui-view
为了区分 可以给每个ui-view起一个不同的名字
-->
<div ui-view="view-a"></div>
<div ui-view="view-b"></div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="node_modules/angular-ui-router/angular-ui-router.min.js"></script>
<script>
angular.module('myApp',['ui.router'])
.config(['$stateProvider',function($stateProvider){
/*
当页面中有多个ui-view时,在路由配置中可以使用views属性配置
views属性的值是对象的形式,属性名是view的名字,其值又是一个对象
是当前view的具体配置 比如templateUrl controller等等
*/
$stateProvider
.state({
name:'index',
url:'/index',
views:{
'view-a':{
template:'<div>首页a</div>'
},
'view-b':{
template:'<div>首页b</div>'
}
}
})
.state({
name:'list',
url:'/list',
views:{
'view-a':{
template:'<div>列表页A</div>'
},
'view-b':{
template:'<div>列表页B</div>'
}
}
})
}])
</script>
</body>

ui-router路由嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<body ng-app="myApp">
<!-- html入口文件的ui-view -->
<div ui-view></div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="node_modules/angular-ui-router/angular-ui-router.min.js"></script>
<script>
angular.module('myApp',['ui.router'])
.config(['$stateProvider',function($stateProvider){
$stateProvider
.state({
url:'/tab',
name:'tab',
// 此参数代表当前路由需要和其他路由配合使用
// 不能单独使用
// 当前模板会被插入到html入口文件中的ui-view指令所在标签
abstract:true,
template:'<a ui-sref="tab.index">首页</a>\
<a ui-sref="tab.list">列表页</a>\
<a ui-sref="article">文章页</a>\
<div ui-view></div>' // tab模板中的ui-view 和当前路由配合使用的路由模板被插入到这里
})
.state({
url:'/index',
// tab.index表示当前路由需要和tab路由配合使用
// 当前路由的模板被插入到tab模板中的ui-view指令所在标签
name:'tab.index',
template:'<div>首页</div>'
})
.state({
url:'/list',
// tab.list表示当前路由需要和tab路由配合使用
// 当前路由的模板被插入到tab模板中的ui-view指令所在标签
name:'tab.list',
template:'<div>列表页</div>'
})
.state({
url:'/article',
// 当前路由可以独立使用
// 模板被插入到html入口文件中的ui-view指令所在标签
name:'article',
template:'<div>列表页</div>'
})
}])
</script>
</body>

ui-router $urlRouterProvider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<body ng-app="myApp">
<a ui-sref="index">首页</a>
<a ui-sref="list">列表页</a>
<div ui-view></div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="node_modules/angular-ui-router/angular-ui-router.min.js"></script>
<script>
angular.module('myApp',['ui.router'])
.config(['$stateProvider','$urlRouterProvider',function($stateProvider,$urlRouterProvider){
$stateProvider
.state({
name:'index',
url:'/index',
template:'<div>首页</div>'
})
.state({
name:'list',
url:'/list',
template:'<div>列表页</div>'
})
// 当以上路由都不能匹配的时候 跳转到index页面
$urlRouterProvider.otherwise('index');
}])
</script>
</body>

Angular的watch与apply

Angular的watch与apply

watch

1
2
3
4
5
6
7
8
9
$scope.$watch('要监听的数据',function(newValue,oldValue){
// newValue 最新修改的值
// oldValue 上一次的值
});
可以实时监听值的变化
页面一上来的时候 会执行一次

apply

1
2
3
4
$scope.$apply() 通知angular更新视图
当使用了原生JS (点击事件 定时器) 改变了$scope下面的数据以后 我们需要通知
当使用第三方库发生异步请求 并且在成功回调内容改变了 $scope的值 需要通知