最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 一文入门React与Vue(适用于只会两者其一的框架学习者)

    正文概述 掘金(山黎)   2020-12-17   664

    前言

    本人原本是一个React开发者,由于最近项目需要维护,技术栈需要会使用Vue,我在之前也从来没有看过Vue的文档,就花了一个周末的时间简单学习了一下Vue的知识点。这里分享一点Vue的快速入门笔记,本文也同样适用于目前只会Vue,但想快速学习React的同学。

    实例

    Vue实例

    每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始,分别添加Vue的周边生态:路由 vue-router 、国际化 vue-i18n 、状态管理 vuex ,和将要渲染的节点#app

    new Vue({   
      el: '#app',
      router,  //vue-router
      i18n,    //vue-i18n
      store,   //vuex
      render: h => h(App)
    })
    
    

    React实例

    React也是同理,但是它是将组件一层层包裹,通过context上下文和props来传递,添加React的周边生态:路由 react-router-dom 、国际化 react-i18next 、状态管理 react-redux ,同时使用 react-dom提供的ReactDom 来将页面渲染到相应的#app节点上。

    ReactDom.render(
        <StoreProvider>
            <I18n>
                <BrowerRouter>
                    {route}
                </BrowerRouter>
            </I18n>
        </StoreProvider>,
        document.getElementById('app'),
    )
    

    模板

    Vue模板

    Vue的一个页面构成比较简单明了,更像是原来的html结构

    emplate里编写标签来生成dom节点,script里编写JavaScript来处理逻辑style里编写css来处理样式。

    <template>
      <div class='text'> 
          {{msg}}
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       //定义成函数是为了组件复用
       data:function(){
            return{
                msg:'Hello Vue!'
            }
        },
    }
    </script>
    
    <style>
        .text{
            color:'red';
        }
    </style>
    

    React模板

    对于比React来看,它是纯JavaScript编写代码来渲染dom处理逻辑,定义state的值来控制页面的渲染renderreturn标签来生成dom节点

    //react的jsx语法
    class Hello extends React.Component{
        state = {
            msg:'hello React!'
        }
        render(){
            const {msg} = this.state;
            return(
                <div className = 'text'>
                    {msg}
                </div>
            )
        }
    }
    

    对比一下语法:

    • Vue可以直接在模板里使用 msg属性 而不是 this.data.msg 这样使用,模板里使用 双括号
    • React定义的 msg属性 放在 this.state 上的,但是却需要用 this.state.msg 取值,模板里使用 单括号

    具体Vue实例化为什么可以直接能获取到data内的数据,可以参考这个回答 为什么Vue实例化后,通过this.能获取到data内的数据

    常用指令

    v-if/v-else/v-else-if

    v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true值的时候被渲染, 也可以用 v-else-if 继续做判断,最后再用 v-else 做最后处理。

    //Vue的模板语法  这里只有v-else的文字会显示出来
    <template>
      <div id='app'> 
          <div v-if='flag === 0'>
              由于v-if里的条件判断结果是false,故现在不能看到文字
          </div>
          <div v-else-if = 'flag === 2'>
              v-else-if必须紧跟v-if后面,否则会无效
          </div>
          <div v-else>
               v-else必须紧跟v-if或者v-else-if后面,否则会无效
          </div>
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                flag:1
            }
        },
    }
    </script>
    
    <style>
    </style>	
    

    v-show

    另一个用于根据条件展示元素的选项是 v-show 指令。

    //Vue的模板语法
    <template>
      <div id='app'> 
          <div v-show='flag'>
              由于v-show里的条件判断结果是true,故现在可以看到文字
          </div>
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                flag:true
            }
        },
    }
    </script>
    
    <style>
    </style>
    

    这里就会发现 v-ifv-show 都可以达到隐藏文字和显示文字的作用,但是两者还是有区别的,使用 v-if 时当其值是false时,dom节点不会被渲染,但是使用 v-show 时无论其值是true还是false,dom节点都会被渲染。

    再讲一下 v-ifv-show 的原理:

    • v-if 就像if和else一样动态地创建元素,当v-if为false时会将 dom节点移除。所以当v-if控制的是组件,切换过程中条件块内的事件监听器和子组件会被 销毁和重建 ,会触发组件和子组件的生命周期。
    • v-show 初始化时为false时会添加 style:'display:none' ,为true时会移除 display:none,不管渲染条件是什么,元素总是会被渲染,然后再进行css的操作。

    React模拟v-if和v-show

    知道了原理再来看看React模拟 v-ifv-show 的实现,React对于 v-if 一般可以用 三目表达式 表示,对于 v-show 可以对 style 直接赋值切换

    //React
    class Hello extends React.Component{
        state = {
           flag:'1',
           show: false
        }
        render(){
            const { flag,show } = this.state;
            return(
                <div id='app'> 
                //对于v-if的模拟
                  {
                       flag === '0' ? 
                       (
                           <div>
                               类似于Vue里的v-if
                           </div>
                       )
                       : flag === '2' ?
                       (
                           <div>
                               类似于Vue里的v-else-if
                           </div>
                       )
                       :
                       (
                           <div>
                               类似于Vue里的v-else
                           </div>
                       )
                  }
                  //对于v-show的模拟
                  <div style={show ? {} : {display:'none'}}>
                      类似于Vue里的v-show
                  </div>
                </div>
            )
        }
    }
    

    v-bind

    一些指令能够接收一个 “参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 dom属性

    //Vue的模板语法
    <template>
      <div id='app'> 
          <a v-bind:href='url' >
              跳转到百度
          </a>
          //缩写
          <a  :href='url' >
              跳转到百度
          </a>
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                url:'www.baidu.com'
            }
        }
    }
    </script>
    
    <style>
    </style>
    

    其实 v-bind 类似于React中的绑定值

    class Hello extends React.Component{
        state = {
           url:'www.baidu.com'
        }
        render(){
            const {url} = this.state;
            return(
                <div id='app'> 
                  <a href={url}>
                      跳转到百度
                  </a>
                </div>
            )
        }
    }
    

    v-on

    用于指出一个指令应该以特殊方式绑定。例如,v-on:click.prevent 修饰符告诉 v-on 指令对于触发点击的事件时并调用 event.preventDefault(),常用修饰符除.prevent以外常用的还有:

    • .stop - 调用 event.stopPropagation();
    • .once - 只触发一次回调;
    //Vue的模板语法
    <template>
      <div id='app'> 
          <span>{{ num }}</span>
          <button v-on:click.prevent="add">增加</button>
    
          //缩写
          <button @click.prevent="add">增加</button>
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                num:0
            }
        },
       methods:{
           add(){
               this.num++;
           } 
       }
    }
    </script>
    
    <style>
    </style>
    

    但是在React里,事件驱动还是以on开头进行编写,如onClick、onChange等

    class Hello extends React.Component{
        state = {
           num:0
        }
        
        add = e => {
            e.preventDefault();
            this.setState((state)=>({
                num: state.num+1 
            }))
        }
        
        render(){
            const {num} = this.state;
            return(
                <div id='app'> 
                    <span>{{ num }}</span>
                    <button onClick={this.add}>
                      增加
                    </button>
                </div>
            )
        }
    }
    

    Vue的计算属性与侦听器

    Vue模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护,所以任何复杂逻辑,应当使用计算属性。

    <template>
      <div id='app'> 
      
          //bad example
          <div id='bad'>
              {{msg.split('').reverse().join('')}}  
          </div>
          
          //good example
          <div id='good'>
              {{reverseMsg}}
          </div>
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                msg:'Hello'
            }
        },
        computed:{
            reverseMsg: function(){
                return this.msg.split('').reverse().join('')
            }
        }
    }
    </script>
    

    绑定普通属性一样在模板中绑定计算属性,Vue 知道 reversedMsg 依赖于 this.msg ,因此当 this.message 发生改变时,所有依赖 reversedMsg 的绑定也会更新。

    Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性 watch ,可以用来监听值的变化来做一些事情,但是如果有一些数据要随着其他数据变动而变动时,应该使用 computed 而不是 watch

    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                a:{
                    b:{
                        c:5
                    }
                }
            }
        },
        watch: {
            c:{
                //属性变化时触发的事件
                handler:function(value,oldValue){
                    console.log('新数据:'+value,'原数据:'+oldValue)
                },
                //该回调会在任何被侦听的对象的属性改变时被调用,不论其被嵌套多深
                deep:true,
                //该回调将会在侦听开始之后立马被调用
                immediate:true
            }
        } 
    }
    </script>
    

    在React通过 state 里的值来进行做计算属性,可以将变量单独定义在 render 中。但是通过 state 的值来进行做 侦听 的事情,应当是在 更新阶段 执行,这里放到生命周期处再做介绍。

    列表渲染

    Vue的列表渲染

    我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

    //Vue的模板语法
    <template>
      <div id='app'> 
          <ul id="example">
              <li 
                  v-for="(item,index) in items" 
                  :key="item.message"
              >     
                  {{ item.message }} - {{index}}
              </li>
          </ul>
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       //定义成函数是为了组件复用
       data:function(){
            return{
                items: [       
                    { message: 'Foo' },       
                    { message: 'Bar' }     
                ]
            }
        },
    }
    </script>
    
    //React
    class Hello extends React.Component{
        state = {
           items: [       
                    { message: 'Foo' },       
                    { message: 'Bar' }     
                ]
        }
        
        render(){
            const {items} = this.state;
            return(
                <div id='app'> 
                    <ul id="example">
                        {
                            items.map((item,index)=>{
                                return(
                                <li  
                                  key={item.message}
                                >     
                                  { item.message } - {index}
                                 </li>
                                )
                            })
                        }
                    </ul>
                </div>
            )
        }
    }
    

    数组更新检测

    Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:push()pop()shift()unshift()splice()sort()reverse()

    //Vue的模板语法
    <template>
      <div id='app'> 
          <span>{{ arr }}</span>
          <button @click="arr.pop()">出栈</button>
       </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                arr:[1,2,3,4,5]        
            }
        },
    }
    </script>
    

    当点击按钮以后,数组每次就会 出栈一个元素,并且视图发生更新,但是当使用Array的filter()concat()slice() 等api时,它们将不会改变原数组,而是返回一个新数组,直接使用时不会更新视图,这里可以用新数组去替换原数组。

    //Vue的模板语法
    <template>
      <div id='app'> 
          <span>{{ arr }}</span>
          <button @click="filterArray">筛选大于等于3的元素</button>
       </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                arr:[1,2,3,4,5]        
            }
        },
        methods:{
            filterArray(){
                this.arr = this.arr.filter.filter(function(item){
                    return item >= 3
                })
            }
        }
    }
    </script>
    

    React的列表渲染

    React的 setState 机制是直接赋值,所以使用pushpop等改变原数组的操作时,需要先取 原始值 再赋值给 state

    class Hello extends React.Component{
        state = {
           arr:[1,2,3]
        }
        
        addArr = ()=>{
            //使用浅拷贝复制数组再执行添加
            const data = this.state.arr.concat();
            data.push(4)
            this.setState({
              arr: data
            })
    
        }
        
        filterArr = ()=>{
            //由于filter返回一个新数组,这里正好返回给arr
            this.setState((state)=>({
                arr: state.arr.filter(item => item > 2)
            }))
        }
        
        render(){
            const {arr} = this.state;
            return(
                <div id='app'> 
                    <span>{ arr }</span>
                    <button onClick={this.filterArr}>
                          添加数字
                    </button>
                    <button onClick={this.filterArr}>
                          筛选大于等于3的数
                    </button>
                </div>
            )
        }
    }
    

    组件传值与插槽

    Vue的组件传值与插槽

    Vue 实现了一套内容分发的 API,将 <slot> 元素作为承载分发内容的出口。

    Vue的子组件传递给父组件时,如果子组件触发的是 方法,则使用 this.$emit(eventName, args) 用来做自定义事件。如果子组件获取父组件的 属性值, 则使用 props 进行定义 类型默认值

    //Vue子组件
    <template>
        <div>
            <div @click="say">
                {{msg}}
                //插槽,类似于react里的{children}
                <slot></slot>
            </div>
        </div>
    </template>
    
    <script>
    export default {
        name:'Hello',
        //定义props里的值类型和默认值
        props:{
            msg:{
                type:String,
                default:''
            }
        },
        methods:{
            say(){
                console.log('触发子方法给父组件')
                //给父组件的自定义方法
                this.$emit('say')
            }
        }
    }
    </script>
    
    //Vue父组件
    <template>
        <div>
            <Hello :msg="msg" @say="say">
              <div>插槽文字</div>
            </Hello>
        </div>
    </template>
    
    <script>
    import Hello from "./Hello.vue";
    export default {
        name:'App',
        //定义props里的值类型和默认值
        data:function(){
            return{
                msg:'传递给子组件的值'
            }
        },
        //注册组件
        components: {
            Hello,
        },
        methods:{
            say(){
                console.log('Hello')
            }
        }
    }
    </script>
    

    React的组件传值与插槽

    React 的插槽比较简单,就是一个包裹 this.props.children 就可以了。具体原因主要是React的每个 JSX 元素只是调用 React.createElement(component, props, ...children) 的语法糖,相当于是自带插槽。

    React 的子组件向父组件传递时,无论是 触发方法 还是获取父组件传递下来的 属性值 ,都是使用 this.props.[protoitype] 的方式命名。

    class Child extends React.Component{
        
        say = ()=>{
            console.log('触发子方法');
            //直接定义say方法到父组件里提供调用
            this.props.say();    
        }
        
        render(){
            const {msg,children} = this.props;
            return(
                <div id='app'> 
                    <div onClick={this.say}>
                        {msg}
                        <div>
                            {children}
                        </div>
                    </div>
                </div>
            )
        }
    }
    
    class Parent extends React.Component{
    
        state = {
            msg: '传递给子组件的值'
        }
        
        say = ()=>{
            console.log('父组件里触发方法');    
        }
        
        render(){
            const {msg} = this.state;
            return(
                <div> 
                    <Child msg={msg} say={this.say}>
                        <div>
                            插槽文字
                        </div>
                    </Child>
                </div>
            )
        }
    }
    

    生命周期

    Vue生命周期

    一文入门React与Vue(适用于只会两者其一的框架学习者) Vue的生命周期比较于React来说相对简单点,Vue大体划分四个阶段:

    • 初始化:beforeCreate、created
    • 渲染:beforeMount、mounted
    • 更新:beforeUpdate、updated
    • 卸载:beforeDestroy、destroy

    还有三个生命周期较少使用,在updated后触发:

    • activated ( keep-alive 组件激活时调用 )
    • deactivated ( keep-alive 组件停用时调用 )
    • errorCaptured (当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。)
    <script>
            new Vue({
                el:'#app',
                data:{
                    title:'hello word',
                },
                methods:{
                    top(){
                        this.
                    }
                },
                beforeCreate(){
                    //不能获得实例化data里的值
                    //页面加载出来就会执行
                    console.log(this.title)
                    console.log('创建之前')
                    //页面没加载出来,可以写加载的loading图
                },
                created(){
                    console.log(this.title)
                    console.log('创建之后')
                },
                beforeMount(){
                    //把当前实例化的Vue挂载到绑定的DOM元素上
                    //this.$el是获取当前实例化内的所有DOM节点
                    //此时DOM中的变量没有被渲染
                    //页面加载出来就会执行
                    console.log(this.$el)
                    console.log('挂载之前')
                },
                mounted(){
                    //此时DOM内的变量已经被渲染
                    console.log(this.$el)
                    console.log('挂载之后') 
                },
                beforeUpdate(){
                //数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
                    //你可以在这个钩子中进一步地更改状态,
                    //这不会触发附加的重渲染过程。
                    //改变的是DOM元素里的数据变更
                    //data里的数据变更不会触发
                    //页面加载出来不会执行,当数据变更才会执行
        console.log(document.querySelector('#val').innerHTML)
                    console.log('更新之前')
                    //该钩子在服务器端渲染期间不被调用。
                },
                updated(){
                    //此时的DOM已经更新
                    //避免在此期间更改状态,因为这可能会导致更新无限循环。
        console.log(document.querySelector('#val').innerHTML)
                    console.log('更新之后'); 
                },
                beforeDestroy(){
                    //实例销毁之前调用。在这一步,实例仍然完全可用。
                    console.log('催毁之前'); 
                },
                destroy(){
            //Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定
             // 所有的事件监听器会被移除,所有的子实例也会被销毁。
                    console.log('摧毁之后')
                }
            })
        </script>
    

    关于网络请求放在哪个生命周期里?

    可以放置于created、beforeMount、mounted中进行,因为这三个生命周期里 this.data 已经被创建,可以将服务端返回数据进行赋值。

    但是目前Vue的项目多用于 ssr服务端渲染ssr 不支持 beforeMount、mounted生命周期函数,故推荐在 created 里调用请求,并且它能更快获取到服务端数据,减少loading时间。

    React生命周期

    一文入门React与Vue(适用于只会两者其一的框架学习者) React(16.4+)的生命周期大体划分三个阶段:

    • 挂载:constructor、getDerivedStateFromProps、render、componentDidMount
    • 更新:getDerivedStateFromProps、shouldComponentUpdate、render、getSnapshotBeforeUpdate、componentDidUpdate
    • 卸载:componentWillUnmount

    具体生命周期实例参考官网

    React的网络请求一般放置于 componentDidMount 生命周期中,在 render渲染 完成以后执行。

    回到 侦听计算属性,React可以直接在render中定义 计算属性,因为 state 发生更新以后,整个 render 会重新渲染。侦听 可以获取上一个值和最新的值,可以在 componentDidUpdate 中手动处理。

    class Child extends React.Component{
    
        state = {
            msg:'hello',
            num:0
        }
        
        componentDidUpdate(prevProps,prevState){
        	if(prevState.num !== this.state.num){
            	console.log(prevState.num,'原来的值')
            	console.log(this.state.num, '最新的值')
            }  
        }
                
        render(){
            const {msg} = this.state;
            
            const reverseMsg = msg.split('').reverse().join('')
            return(
                <div> 
                    <div>
                        {reverseMsg}
                    </div>
                </div>
            )
        }
    }
    
    

    Vue的v-modal机制

    可以用 v-model 指令在表单 input、textareaselect 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

    v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

    • texttextarea 元素使用 value propertyinput 事件;
    • checkboxradio 使用 checked propertychange 事件;
    • select 字段将 value 作为 prop 并将 change 作为事件。
    //Vue的模板语法
    <template>
      <div id='app'> 
          <input v-model="message" placeholder="edit me">
          <p>Message is: {{ message }}</p>   
      </div>
    </template>
    
    <script>
    export default {
       name:'hello',
       data:function(){
            return{
                message:''        
            }
        },
    }
    </script>
    

    修饰符: .lazy、.number、.trim

    <!-- 在“change”时而非“input”时更新 -->
    <input v-model.lazy="msg">
    
    <!-- 自动将用户的输入值转为数值类型 -->
    <input v-model.number="age" type="number">
    
    <!-- 自动过滤用户输入的首尾空白字符 -->
    <input v-model.trim="msg">
    

    自定义 v-modal,前面已经知道了父子组件的传值与触发方法和v-modal的原理,现在来自己写一个自定义组件使用v-modal的例子

    //Vue子组件
    <template>
        <input       
            type="checkbox"       
            v-bind:checked="checked"       
            v-on:change="$emit('change', $event.target.checked)"                    
         />   
    </template>
    
    <script>
    export default {
        name:'base-checkbox',
        //允许一个自定义组件在使用 v-model 时定制 prop 和 event
        model:{
            prop:'checked',
            event:'change'
        },
        //定义props里的值类型和默认值
        props:{
            checked: Boolean
        },
    }
    </script>
    
    //使用
    <base-checkbox v-model="lovingVue"></base-checkbox>
    

    Vue自定义指令

    除了核心功能默认内置的指令 (v-model 和 v-show)Vue 也允许 注册自定义指令,看一个官方的例子

    Vue.directive 里会携带多个钩子函数:

    • bind :只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
    • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    • unbind:只调用一次,指令与元素解绑时调用。

    再来看看钩子函数的参数

    • el:指令所绑定的元素,可以用来直接操作 DOM。
    • binding:一个对象,包含以下 property:
      1. name:指令名,不包括 v- 前缀。
      2. value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
      3. oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用,无论值是否改变都可用。
      4. expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
      5. arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
      6. modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为{ foo: true, bar: true }。
      7. vnode:Vue 编译生成的虚拟节点。
    • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。
    <div v-demo:foo.a.b="message"></div>
    
    Vue.directive('demo', {  
      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(', ')
      }
    })
    

    显示结果如下: 一文入门React与Vue(适用于只会两者其一的框架学习者)

    再写一个input框防抖的例子

    Vue.directive('debounce', {  
      inserted: function (el, binding) {
        let timer;
        el.addEventListener('click',()=>{
            if(timer) clearTimeout(timer)
            timer = setTimeout(()=>{
                binding.value()
            },1000)
        })
      }
    })
    
    <template>
        <button v-debounce="debounceClick">防抖</button>
    </template>
    <script>
    export default {
      methods: {
        debounceClick () {
          console.log('只触发一次')
        }
      }
    }
    </script>
    

    起源地下载网 » 一文入门React与Vue(适用于只会两者其一的框架学习者)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元