... 2025-7-10 大约 4 分钟

编程式导航 别名、重定向 嵌套路由 导航高亮 路由解耦 路由导航守卫

Vue.directive 自定义指令 自定义指令钩子

插槽、具名插槽 组件嵌套

component 标签 放置组件 和直接书写组件名↓ 配合is 实现动态组件 动态组件 异步组件 递归组件 混入

keepalive

解除 CSDN 复制限制

Vue Bus 总线 浅谈emitemit和on的用法 (opens new window)

<main id="app">
  {{msg}}
  <app-one></app-one>
  <app-two></app-two>
</main>

<script src="./vue.js"></script>
1
2
3
4
5
6
7
let hub = new Vue()

Vue.component('app-one', {
  data() {
    return {
      num: 0,
    }
  },
  template: `<div><button @click ='add'>one</button>{{num}}</div>`,
  methods: {
    add() {
      hub.$emit('two', 2)
    },
  },
  mounted() {
    hub.$on('one', (val) => {
      this.num += val
    })
  },
})

Vue.component('app-two', {
  data() {
    return {
      num: 0,
    }
  },
  template: `<div><button @click ='add'>two</button>{{num}}</div>`,
  methods: {
    add() {
      hub.$emit('one', 5)
    },
  },
  mounted() {
    hub.$on('two', (val) => {
      this.num += val
    })
  },
})

let app = new Vue({
  el: '#app',
  data: {
    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
this指向
一般情况下 this最终指向的是调用它的对象
全局作用域或者普通函数中,this指向window
方法调用中,谁调用指向谁
构造函数中 this指向构造函数的实例

获取浏览器窗口大小

function getInfo() {
  var s = ''
  s = ' 网页可见区域宽:' + document.body.clientWidth
  console.log(s)
  s = ' 网页可见区域高:' + document.body.clientHeight
  console.log(s)
  s =
    ' 网页可见区域宽:' + document.body.offsetWidth + ' (包括边线和滚动条的宽)'
  console.log(s)
  s = ' 网页可见区域高:' + document.body.offsetHeight + ' (包括边线的宽)'
  console.log(s)
  s = ' 网页正文全文宽:' + document.body.scrollWidth
  console.log(s)
  s = ' 网页正文全文高:' + document.body.scrollHeight
  console.log(s)
  s = ' 网页被卷去的高(ff):' + document.body.scrollTop
  console.log(s)
  s = ' 网页被卷去的高(ie):' + document.documentElement.scrollTop
  console.log(s)
  s = ' 网页被卷去的左:' + document.body.scrollLeft
  console.log(s)
  s = ' 网页正文部分上:' + window.screenTop
  console.log(s)
  s = ' 网页正文部分左:' + window.screenLeft
  console.log(s)
  s = ' 屏幕分辨率的高:' + window.screen.height
  console.log(s)
  s = ' 屏幕分辨率的宽:' + window.screen.width
  console.log(s)
  s = ' 屏幕可用工作区高度:' + window.screen.availHeight
  console.log(s)
  s = ' 屏幕可用工作区宽度:' + window.screen.availWidth
  console.log(s)
  s = ' 你的屏幕设置是 ' + window.screen.colorDepth + '位彩色'
  console.log(s)
  s = ' 你的屏幕设置 ' + window.screen.deviceXDPI + '像素/英寸'
  console.log(s)
}
getInfo()
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
<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div id="app">
      <c @click.native="cl"></c>
      <d>登录</d>
      <e></e>

      <h1>{{msg}}</h1>

      <h1>{{$store.state.token}}</h1>

      <h1>{{$store.getters.numum}}</h1>
      <h1>{{$store.getters.nummmm}}</h1>

      <h1 @click="$store.commit('jian',$store)">{{$store.state.m1.x}}</h1>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script src="../vuex.js"></script>
  <script src="../vue-router.js"></script>
  <script>
    Vue.component('c', {
      //  @click="$emit('click')
      template: `<h1 @click='change' >{{$store.state.num}}</h1>`,
      methods: {
        change() {
          // 在严格模式下 这种操作 是会 报错的  所以 建议使用 mutation 对state 里面的值 进行修改
          // this.$store.state.num = 66
          this.$store.commit('add', 66)
        },
      },
    })
    Vue.component('d', {
      template: `<h1 @click='login' >{{$store.state.num}} <slot></slot> </h1>`,
      methods: {
        login() {
          this.$store.commit('SETTOKEN', 'skadjgaskjd23sa54d5asd')
        },
      },
    })
    Vue.component('e', {
      template: `<h1 @click='asyncChange' >{{$store.state.num}}异步处理</h1>`,
      methods: {
        asyncChange() {
          this.$store.dispatch('async_change', 666).then((res) => {
            console.log(res)
            res.dispatch('async_change', 888).then((res1) => {
              res1.dispatch('async_change', 999)
            })
          })
        },
      },
    })

    var app = new Vue({
      el: '#app',
      data: {
        msg: '',
      },
      methods: {
        cl() {
          this.msg = this.$store.state.num
        },
      },
      watch: {
        '$store.state.num': function () {
          console.log('state改了')
          this.cl()
        },
      },
      store: new Vuex.Store({
        state: {
          // 储存公共状态
          num: 0,
          token: '',
        },
        mutations: {
          // 简单到 只能修改state里面的 数据
          add(state, con) {
            console.log(con)
            state.num += con
          },
          SETTOKEN(state, token) {
            state.token = token
          },
          change(state, x) {
            state.num = x
          },
          reduce(state, x) {
            state.num -= x
          },
        },
        actions: {
          //异步操作 触发mutation 里面的方法
          // context 代表 上下文  其实它就类似于  箭头函数里面的this
          // payload 接受的参数
          // async_change(context, payload) {
          //     // console.log(context);
          //     setTimeout(() => {
          //         context.commit("change", 90)
          //     }, 2000)
          // }
          async_change(context, payload) {
            return new Promise((resolve, reject) => {
              setTimeout(() => {
                context.commit('change', payload)
                resolve(context)
              }, 2000)
            })
          },
        },
        getters: {
          // 类似于 计算属性 可以对state里面的值 进行处理之后 在输出
          numum(state) {
            return '$' + (state.num + 1) + '元'
          },
          nummmm(state, getters) {
            return getters.numum + ' 好吃不贵'
          },
        },
        modules: {
          // 模块化  当一个项目的公共仓库 过于繁杂的时候  为了便于维护 可以把 vuex  分割开
          m1: {
            state: {
              x: 789,
            },
            mutations: {
              jian(state, res) {
                console.log(state)
                res.commit('reduce', 2)
              },
            },
          },
        },
      }),
    })
  </script>
</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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div id="app">
      <test></test>

      <button @click="$store.commit('add',1)">add</button>
      <button @click="$store.dispatch('async_add',2)">async_add</button>
      <br />
      <button @click="add(1)">add</button>
      <button @click="async_add(2)">async_add</button>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script src="../vuex.js"></script>
  <script src="../vue-router.js"></script>
  <script>
    /*
        mapState , mapGetters 映射到 computed  计算属性上
        mapMutations ,mapActions 映射到 methods 上面
    */
    Vue.component('test', {
      template: `
            <div>
                <h1>{{$store.state.num}}</h1>
                <h2>{{$store.state.msg}}</h2> 
                <h3>{{res}}</h3>
                <div>---------------------------------</div>   
                <h1>{{num}}</h1>
                <h2>{{msg}}</h2>    
                <div>---------------------------------</div>  
                <h2>{{$store.getters.msg2}}</h2> 

                <h3>{{msg2}}</h3>
            </div>
        `,
      // 同名 且 不需要别的计算属性
      // computed: Vuex.mapState(["num", "msg"])
      // 同名 基础写法 不需要辅助函数 需要别的计算属性
      // computed: {
      //     num1() {
      //         return this.$store.state.num + "----------------"
      //     },
      //     msg1() {
      //         return this.$store.state.msg + "----------------"
      //     }
      // },
      // 不同名 不需要别的计算属性
      // computed: Vuex.mapState({
      //     num1: function (state) {
      //         return state.num + "*******"
      //     },
      //     msg1: function (state) {
      //         return state.msg + "*******"
      //     }
      // }),
      computed: {
        ...Vuex.mapState(['num', 'msg']),
        ...Vuex.mapGetters(['msg2']),
        // ...Vuex.mapState({
        //     num1: function (state) {
        //         return state.num + "*******"
        //     },
        //     msg1: function (state) {
        //         return state.msg + "*******"
        //     }
        // }),
        res() {
          return 'word'
        },
      },
    })

    var app = new Vue({
      el: '#app',
      data: {},
      methods: {
        ...Vuex.mapMutations(['add']),
        ...Vuex.mapActions(['async_add']),
      },
      store: new Vuex.Store({
        state: {
          num: 0,
          msg: 'hello',
        },
        getters: {
          msg2(state, getters) {
            return state.msg + '-----word'
          },
        },
        mutations: {
          add(state, x) {
            state.num += x
          },
        },
        actions: {
          async_add(context, payload) {
            return new Promise((res, rej) => {
              setTimeout(() => {
                context.commit('add', payload)
                res(context)
              }, 2000)
            })
          },
        },
      }),
    })
  </script>
</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
104
105
106
107
108
109
110
111
112
113
114
115
上次编辑于: 2025年7月10日 04:01
贡献者: HugStars