zoukankan      html  css  js  c++  java
  • vue组件、自定义指令、路由

    1.vue组件 

       组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树。

    注册一个全局组件语法格式如下:

    Vue.component(tagName, options)

    tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:

    <tagName></tagName>

    1. 组件名大小写:

     定义组件名的方式有两种:

    (1)使用 kebab-case

    Vue.component('my-component-name', { /* ... */ })

      当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>。

    (2)使用 PascalCase

    Vue.component('MyComponentName', { /* ... */ })

      当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name> 和 <MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

    2.全局组件

      所有实例都能用全局组件。

            <div id="app">
                <vue></vue>
            </div>
            <script>
                // 注册
                Vue.component('vue', {
                    template: '<h1>自定义组件!</h1>'
                })
                // 创建根实例
                new Vue({
                    el: '#app'
                })
            </script>

    结果:

    3.局部组件

      我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用。

            <div id="app">
                <vue></vue>
            </div>
    
            <script>
                var Child = {
                    template: '<h1>自定义组件!</h1>'
                }
    
                // 创建根实例
                new Vue({
                    el: '#app',
                    components: {
                        // <vue> 将只在父模板可用
                        'vue': Child
                    }
                })
            </script>

      对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。

      注意:组件的定义data必须为Function。

    4.Prop

      prop 是父组件用来传递数据的一个自定义属性。父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop"。

            <div id="app">
                <child message="hello!"></child>
            </div>
    
            <script>
                // 注册
                Vue.component('child', {
                    // 声明 props
                    props: ['message'],
                    // 同样也可以在 vm 实例中像 "this.message" 这样使用
                    template: '<span>{{ message }}</span>'
                })
                // 创建根实例
                new Vue({
                    el: '#app'
                })
            </script>

    结果:

    5.动态 prop

      类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件。

            <div id="app">
                <div>
                    <input v-model="parentMsg">
                    <br>
                    <child v-bind:message="parentMsg"></child>
                </div>
            </div>
    
            <script>
                // 注册
                Vue.component('child', {
                    // 声明 props
                    props: ['message'],
                    // 同样也可以在 vm 实例中像 "this.message" 这样使用
                    template: '<span>{{ message }}</span>'
                })
                // 创建根实例
                new Vue({
                    el: '#app',
                    data: {
                        parentMsg: '父组件内容'
                    }
                })
            </script>

    结果:

    以下实例中将 v-bind 指令将 todo 传到每一个重复的组件中:

            <div id="app">
                <ol>
                    <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
                </ol>
            </div>
    
            <script>
                Vue.component('todo-item', {
                    props: ['todo'],
                    template: '<li>{{ todo.text }}</li>'
                })
                new Vue({
                    el: '#app',
                    data: {
                        sites: [{
                                text: 'Baidu'
                            },
                            {
                                text: 'Google'
                            },
                            {
                                text: 'Taobao'
                            }
                        ]
                    }
                })
            </script>

    结果:

    注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。

    6.Prop 验证

      组件可以为 props 指定验证要求。为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="utf-8" />
            <title></title>
            <script src="js/vue.min.js"></script>
        </head>
    
        <body>
            <div id="app">
                <!--v-bind:可以缩写为:-->
                <example :propA="age" v-bind:propB="name" :propc="'C的值'"></example>
            </div>
    
            <script>
                Vue.component('example', {
                    template: '<span>{{ propa }} - {{ propb }} - {{ propc }} - {{ propd    }} - {{ prope }} - {{ propf }}</span>',
                    props: {
                        // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
                        propa: Number,
                        // 多个可能的类型
                        propb: [String, Number],
                        // 必填的字符串
                        propc: {
                            type: String,
                            required: true
                        },
                        // 带有默认值的数字
                        propd: {
                            type: Number,
                            default: 100
                        },
                        // 带有默认值的对象
                        prope: {
                            type: Object,
                            // 对象或数组默认值必须从一个工厂函数获取
                            default: function() {
                                return {
                                    message: 'hello'
                                }
                            }
                        },
                        // 自定义验证函数
                        propf: {
                            validator: function(value) {
                                // 这个值必须匹配下列字符串中的一个
                                return ['success', 'warning', 'danger'].indexOf(value) !== -1
                            }
                        }
                    }
                })
                new Vue({
                    el: '#app',
                    data: {
                        age: 28,
                        name: '25'
                    }
                })
            </script>
        </body>
    
    </html>

    注意:

    (1)当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。type 可以是下面原生构造器:

    String、Number、Boolean、Array、Object、Date、Function、Symbol

    (2)type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。

    例如:

            <div id="app">
                <!--v-bind:可以缩写为:-->
                <example :author="new Person('三丰', '张')"></example>
            </div>
    
            <script>
                function Person(firstName, lastName) {
                    this.firstName = firstName
                    this.lastName = lastName
                }
    
                Vue.component('example', {
                    template: '<span>{{ author.firstName }}</span>',
                    props: {
                        // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
                        author: Person
                    }
                })
                new Vue({
                    el: '#app'
                })
            </script>

    结果:

    7.自定义事件

      组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

      我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

        使用 $on(eventName) 监听事件

        使用 $emit(eventName) 触发事件

      另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

    以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。

            <div id="app">
                <div id="counter-event-example">
                    <p>{{ total }}</p>
                    <button-counter v-on:increment="incrementTotal"></button-counter>
                    <button-counter v-on:increment="incrementTotal"></button-counter>
                </div>
            </div>
    
            <script>
                Vue.component('button-counter', {
                    template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
                    data: function() {
                        return {
                            counter: 0
                        }
                    },
                    methods: {
                        incrementHandler: function() {
                            this.counter += 1
                            this.$emit('increment')
                        }
                    },
                })
                new Vue({
                    el: '#counter-event-example',
                    data: {
                        total: 0
                    },
                    methods: {
                        incrementTotal: function() {
                            this.total += 1
                        }
                    }
                })
            </script>

    结果:

    如果你想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:

    <my-component v-on:click.native="doTheThing"></my-component>

    8.data 必须是一个函数

      上面例子中,可以看到 button-counter 组件中的 data 不是一个对象,而是一个函数。

      这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例。

                var buttonCounter2Data = {
                    count: 0
                }
                Vue.component('button-counter2', {
                    /*
                    data: function () {
                        // data 选项是一个函数,组件不相互影响
                        return {
                            count: 0
                        }
                    },
                    */
                    data: function() {
                        // data 选项是一个对象,会影响到其他实例
                        return buttonCounter2Data
                    },
                    template: '<button v-on:click="count++">点击了 {{ count }} 次。</button>'
                })
                new Vue({
                    el: '#components-demo3'
                })
            </script>

    结果:

    三个按钮会同步变化

    2.自定义指令

       除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。

    1.注册全局指令

      该指令的功能是在页面加载时,元素获得焦点。

            <div id="app">
                <p>页面载入时,input 元素自动获取焦点:</p>
                <input v-focus>
            </div>
            <script>
                // 注册一个全局自定义指令 v-focus
                Vue.directive('focus', {
                        // 当绑定元素插入到 DOM 中。
                        inserted: function(el) {
                            // 聚焦元素
                            el.focus()
                        }
                    })
                    // 创建根实例
                new Vue({
                    el: '#app'
                })
            </script>

    2.注册局部指令

      在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用

            <div id="app">
                <p>页面载入时,input 元素自动获取焦点:</p>
                <input v-focus>
            </div>
    
            <script>
                // 创建根实例
                new Vue({
                    el: '#app',
                    directives: {
                        // 注册一个局部的自定义指令 v-focus
                        focus: {
                            // 指令的定义
                            inserted: function(el) {
                                // 聚焦元素
                                el.focus()
                            }
                        }
                    }
                })
            </script>

    3.钩子

    1.钩子函数

    指令定义函数提供了几个钩子函数(可选):

    bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

    inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

    update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。

    componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

    unbind: 只调用一次, 指令与元素解绑时调用。

    2.钩子函数参数

    钩子函数的参数有:除了 el 之外,其它参数都应该是只读的,切勿进行修改。

    • el: 指令所绑定的元素,可以用来直接操作 DOM 。
    • binding: 一个对象,包含以下属性:
      • name: 指令名,不包括 v- 前缀。
      • value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2
      • oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
      • expression: 绑定值的表达式或变量名。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"
      • arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"
      • modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }
    • vnode: Vue 编译生成的虚拟节点。
    • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

      

    例如:

            <div id="app" v-vue:hello.a.b="message">
            </div>
    
            <script>
                Vue.directive('vue', {
                    bind: function(el, binding, vnode) {
                        var s = JSON.stringify
                        el.innerHTML =
                            'name: ' + s(binding.name) + '<br>' +
                            'value: ' + s(binding.value) + '<br>' +
                            'expression: ' + s(binding.expression) + '<br>' +
                            'argument: ' + s(binding.arg) + '<br>' +
                            'modifiers: ' + s(binding.modifiers) + '<br>' +
                            'vnode keys: ' + Object.keys(vnode).join(', ')
                    }
                })
                new Vue({
                    el: '#app',
                    data: {
                        message: 'vue 6A!'
                    }
                })
            </script>

    结果:

    3.简写

      在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:

            <div id="app" v-color-swatch:clor="color">
                123
            </div>
    
            <script>
                Vue.directive('color-swatch', function(el, binding) {
                    el.style.backgroundColor = binding.value
                })
                new Vue({
                    el: '#app',
                    data: {
                        color: 'red'
                    }
                })
            </script>

    结果:

    4.对象字面量

      如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。

            <div id="app">
                <div v-vue="{ color: 'green', text: 'vue 6A!' }"></div>
            </div>
            <script>
                Vue.directive('vue', function(el, binding) {
                    // 简写方式设置文本及背景颜色
                    el.innerHTML = binding.value.text
                    el.style.backgroundColor = binding.value.color
                })
                new Vue({
                    el: '#app'
                })
            </script>

    结果:

    3.路由

      Vue.js 路由允许我们通过不同的 URL 访问不同的内容。通过 Vue.js 可以实现多视图的单页Web应用(single page web application,SPA)。Vue.js 路由需要载入 vue-router 库。

    1.简单实例

      Vue.js + vue-router 可以很简单的实现单页应用。<router-link> 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="utf-8" />
            <title></title>
            <script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
            <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
        </head>
    
        <body>
            <div id="app">
                <h1>Hello App!</h1>
                <p>
                    <!-- 使用 router-link 组件来导航. -->
                    <!-- 通过传入 `to` 属性指定链接. -->
                    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
                    <router-link to="/foo">Go to Foo</router-link>
                    <router-link to="/bar">Go to Bar</router-link>
                </p>
                <!-- 路由出口 -->
                <!-- 路由匹配到的组件将渲染在这里 -->
                <router-view></router-view>
            </div>
    
            <script>
                // 0. 如果使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)
                // 1. 定义(路由)组件。
                // 可以从其他文件 import 进来
                const Foo = {
                    template: '<div>foo</div>'
                }
                const Bar = {
                    template: '<div>bar</div>'
                }
                // 2. 定义路由
                // 每个路由应该映射一个组件。 其中"component" 可以是
                // 通过 Vue.extend() 创建的组件构造器,
                // 或者,只是一个组件配置对象。
                // 我们晚点再讨论嵌套路由。
                const routes = [{
                    path: '/foo',
                    component: Foo
                }, {
                    path: '/bar',
                    component: Bar
                }]
                // 3. 创建 router 实例,然后传 `routes` 配置
                // 你还可以传别的配置参数, 不过先这么简单着吧。
                const router = new VueRouter({
                    routes // (缩写)相当于 routes: routes
                })
                // 4. 创建和挂载根实例。
                // 记得要通过 router 配置参数注入路由,
                // 从而让整个应用都有路由功能
                const app = new Vue({
                    router
                }).$mount('#app')
                // 现在,应用已经启动了!
            </script>
        </body>
    
    </html>

    结果:点击过的导航链接都会加上样式 class ="router-link-exact-active router-link-active"。$mount('#app')相当于绑定元素,也就是el为#app。

    2.<router-link> 相关属性

    (1) to  表示目标路由的链接。 当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

    <!-- 字符串 -->
    <router-link to="home">Home</router-link>
    <!-- 渲染结果 -->
    <a href="home">Home</a>
    
    <!-- 使用 v-bind 的 JS 表达式 -->
    <router-link v-bind:to="'home'">Home</router-link>
    
    <!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
    <router-link :to="'home'">Home</router-link>
    
    <!-- 同上 -->
    <router-link :to="{ path: 'home' }">Home</router-link>
    
    <!-- 命名的路由 -->
    <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
    
    <!-- 带查询参数,下面的结果为 /register?plan=private -->
    <router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

    (2)replace  设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。

    <router-link :to="{ path: '/abc'}" replace></router-link>

    (3)append  设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

    <router-link :to="{ path: 'relative/path'}" append></router-link>

    (4) tag 有时候想要 <router-link> 渲染成某种标签,例如 <li>。 于是我们使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航。

    <router-link to="/foo" tag="li">foo</router-link>
    <!-- 渲染结果 -->
    <li>foo</li>

    (5)active-class 设置 链接激活时使用的 CSS 类名。可以通过以下代码来替代。

    <style>
       ._active{
          background-color : red;
       }
    </style>
    <p>
       <router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
       <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
    </p>

      注意这里 class 使用 active_class="_active"。

    (6)exact-active-class  配置当链接被精确匹配的时候应该激活的 class。可以通过以下代码来替代。

    <p>
       <router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
       <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
    </p>

    (7)event  声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。

    <router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>

      以上代码设置了 event 为 mouseover ,及在鼠标移动到 Router Link 1 上时导航的 HTML 内容会发生改变。

    3.路由总结

    1.路由的to属性默认是根据path进行跳转。也可以通过指定name根据name进行跳转

                    <!--指定跳到name为newsListName-->
                    <router-link :to="{name: 'newsListName'}">News</router-link>

    2.一级路由  path:'/'    默认为显示。也可以通过一级路由重定向到二级路由。例如:

    (1)默认显示:

                const routes = [{
                    path: '/',
                    name: 'index',
                    component: Home
                }, {
                    path: '/home',
                    name: 'home',
                    component: Home
                }, {
                    path: '/list',
                    name: 'newsListName',
                    component: NewsList
                }]

    (2)有了redirect属性会覆盖掉component对应的组件:

                const routes = [{
                    path: '/',
                    name: 'index',
                    component: Home,
                    redirect: '/list'
                }, {
                    path: '/home',
                    name: 'home',
                    component: Home
                }, {
                    path: '/list',
                    name: 'newsListName',
                    component: NewsList
                }]

    3.也可以通过点击事件切换路由

    <button type="button" @click="goToLink">到首页</button>
    
                    methods : {
                        goToLink() {
                            // 可以做一些前置处理
                            this.$router.replace('/home')
                        }
                    }

    4.关于子路由的使用如下:

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="utf-8" />
            <title></title>
            <script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
            <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
        </head>
    
        <body>
            <div id="app">
                <h1>Hello App!</h1>
                <p>
                    <!-- 使用 router-link 组件来导航. -->
                    <!-- 通过传入 `to` 属性指定链接. -->
                    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    
                    <!--默认根据path属性进行跳转-->
                    <router-link to="/home">首页</router-link>
                    <!--指定跳到name为newsListName-->
                    <router-link :to="{name: 'newsListName'}">News</router-link>
                    
                    <button type="button" @click="goToLink">到首页</button>
                </p>
    
                <!-- 路由出口 -->
                <!-- 路由匹配到的组件将渲染在这里 -->
                <router-view></router-view>
            </div>
    
            <script>
                // 0. 如果使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)
                // 1. 定义(路由)组件。
                // 可以从其他文件 import 进来
                const Home = {
                    template: "<div>欢迎您!</div>"
                }
                const NewsList = {
                    template: "<div>NewsList<br/><router-link to='/list/add'>add</router-link><br/><router-link to='/list/detail'>detail</router-link><router-view></router-view></div>"
                }
    
                // 子路由
                const NewsAdd = {
                    template: "<div>添加新闻</div>"
                }
                const NewsDetail = {
                    template: "<div>新闻详情</div>"
                }
                
                // 2. 定义路由
                // 每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,或者,只是一个组件配置对象。
                const routes = [{
                    path: '/',
                    name: 'index',
                    component: Home,
                    redirect: '/list'
                }, {
                    path: '/home',
                    name: 'home',
                    component: Home
                }, {
                    path: '/list',
                    name: 'newsListName',
                    component: NewsList,
                    children: [{
                        path: 'add',
                        name: 'newsListAdd',
                        component: NewsAdd
                    }, {
                        path: 'detail',
                        name: 'newsListDetail',
                        component: NewsDetail
                    }]
                }]
                // 3. 创建 router 实例,然后传 `routes` 配置
                // 你还可以传别的配置参数, 不过先这么简单着吧。
                const router = new VueRouter({
                    routes // (缩写)相当于 routes: routes
                })
                // 4. 创建和挂载根实例。
                // 记得要通过 router 配置参数注入路由,
                // 从而让整个应用都有路由功能
                const app = new Vue({
                    router,
                    methods : {
                        goToLink() {
                            // 可以做一些前置处理
                            this.$router.replace('/home')
                        }
                    }
                }).$mount('#app')
                // 现在,应用已经启动了!
            </script>
        </body>
    
    </html>

    补充:vue路由的两种模式:history和hash模式 (现在基于ajax的路由插件也有。ajax异步请求的URL不会改变,现在也有jquery插件解决这种问题。)

      默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。是用 url#/xxx/xxx这种形式。例如:http://localhost:8080/#/test

    const router = new VueRouter({
      mode: 'hash',
      routes: [...]
    })

      原理:url 中常会出现 #,一可以表示锚点(如回到顶部按钮的原理),二是路由里的锚点(hash)。Web 服务并不会解析 hash,也就是说 # 后的内容 Web 服务都会自动忽略,但是 JavaScript 是可以通过 window.location.hash 读取到的,读取到路径加以解析之后就可以响应不同路径的逻辑处理。 

      如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

    例如:

    const router = new VueRouter({
      mode: 'history',
      routes: [...]
    })

      当使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!

      不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

    原理:history.pushState 和 history.replaceState 。两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新,pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录。

  • 相关阅读:
    凹凸函数
    HashMap数据类型使用注意不能使用基本数据类型
    Tomcat部署发布JSP应用程序的三种方法
    Ubuntu忘记密码,进不了系统的解决方法
    matlab之运算符及其优先级
    java和tomcat配置
    MySQL中 MySQL X.X Command Line Client 一闪而过
    Pearson(皮尔逊)相关系数
    CG, DCG, NDCG
    C#中ListBox中SelectedItem使用注意
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/11901837.html
Copyright © 2011-2022 走看看