精华内容
下载资源
问答
  • Vue3.0官方文档

    万次阅读 2020-09-22 14:11:02
    Vue3.0 中文文档地址 https://v3.cn.vuejs.org/

    Vue3.0 中文文档地址

    https://vue3js.cn/docs/zh/

    // 快速创建vite项目
    npm init vite-app <project-name>
    yarn create vite-app <project-name>
    
    // 可以创建vue ts项目
    npm init @vitejs/app
    yarn create @vitejs/app
    
    展开全文
  • 学习vue必须要看的中文文档
  • 学习Vue3.x方便c Vue 3 新增内容的整理文档(经过验证的) 重点内容: ViteComposition API新的响应式机制计算属性和侦听器teleport (传送)Fragment(碎片)自定义事件($emit 验证)组件的 v-model 升级 ...

    本博客会长期更新(在 Vue 的中文官方文档没有发布前)。

    博客的边界:本博客只会带来 Vue 3 新增内容的整理文档(经过验证的)


    重点内容:

    • Vite
    • Composition API
    • 新的响应式机制
    • 计算属性和侦听器
    • teleport (传送)
    • Fragment(碎片)
    • 自定义事件($emit 验证)
    • 组件的 v-model 升级

    利用 vite 创建下一代的 Vue 项目

    两个重要的点:

    1. Vue CLI v4.5 之上的版本
    2. Vite

    Vue CLI

    想要构建 Vue 3.x 项目,那么需要使用 Vue CLI v4.5 之上的版本

    yarn global add @vue/cli@next
    # or
    npm install -g @vue/cli@next
    
        
    • 1
    • 2
    • 3

    如果想要在现有的项目中(Vue 2.x),升级构建工具,则需要执行以下代码

    vue upgrade --next
    
        
    • 1

    Vite

    Vite 是一个想要用来代替 webpackWeb 开发构建工具,也是官方推荐使用的构建工具,使用 vite 将脱离 webpack

    // ----------npm----------
    npm init vite-app <project-name>
    cd <project-name>
    npm install
    npm run dev
    // ----------yarn----------
    yarn create vite-app <project-name>
    cd <project-name>
    yarn
    yarn dev
    
        

    Composition API

    简介

    为什么会有 Composition API

    创建Vue组件使我们能够将接口的可重复部分及其功能提取到可重用的代码段中。就维护性和灵活性而言,仅此一项就可以使我们的应用程序发展得相当远。

    但是,经过大量的开发经验证明,仅凭这一项可能还不够,特别是当你的应用程序变得非常大时。

    想象一下数百个组件的项目,在处理如此大的应用程序时,共享和重用代码变得尤为重要。

    摘要自:https://v3.vuejs.org/guide/composition-api-introduction.html#why-composition-api

    但是因为 Vue 2.x 中,以 组件 为最小颗粒的原因(PS:mixin 虽然可以达到复用的效果,但是它依然缺少独立性。比如:命名冲突、隐式依赖的问题),导致组件中的逻辑无法被进行 共享重用

    Composition API 概念

    Composition API组合式 API) 是一个概念,而非具体的实现。

    在组件中,实际使用 Composition API 的地方,是 setup 函数。在它内部,我们可以描述一个组件所需要的 所有逻辑

    setup

    简介

    setup 函数是Composition API 的入口函数,也是它的核心函数。

    但是要注意:setup 函数执行时,尚未创建组件实例,所以 this 中没有任何内容。这意味着,除了props,你将无法访问通过 this 来访问组件中声明的任何属性、本地状态、计算属性、方法。

    参数

    setup 函数有两个参数:

    1. {Data} props
      1. props 是响应式的
      2. 由于props是反应性的,你不能使用ES6解构,详见 对象的响应式
    2. {SetupContext} context
      1. context 是普通的 js 对象,所以他不是响应式的
      2. context 下有三个属性:
        1. attrs:包含父组件属性绑定、未识别出的为组件属性或自定义事件的事件
        2. slots:插槽
        3. emit:通知(发出的事件)

    下面是官方的示例代码:

    // Data 为  key:value 结构的对象
    interface Data {
      [key: string]: unknown
    }
    // context 为上下文,包含:
    // attrs:包含父组件属性绑定、未识别出的为组件属性或自定义事件的事件
    // slots:插槽
    // emit:通知
    interface SetupContext {
      attrs: Data
      slots: Slots
      emit: (event: string, ...args: unknown[]) => void
    }
    function setup(props: Data, context: SetupContext): Data
    
        

    可访问的组件属性

    setup被执行时,该组件实例尚未建立。如此一来,您将只能访问以下属性:

    • props
    • attrs
    • slots
    • emit

    换句话说,您将无权访问以下组件选项:

    • data
    • computed
    • methods

    模板使用 setup 中的数据

    如果setup返回对象,则可以在组件的模板中访问对象的属性(注意代码中的备注):

    <!-- MyBook.vue -->
    <template>
      <div>{
         { readersNumber }} {
         { book.title }}</div>
    </template>
    <script>
      import { ref, reactive } from 'vue'
      export default {
        setup() {
          // 通过 ref 或 reactive 创建响应式数据,现在你可以先不需要理解什么是 ref 和 reactive。
          // 你只需要知道此时 readersNumber 和 book 为响应式的
          const readersNumber = ref(0)
          const book = reactive({ title: 'Vue 3 Guide' })
    	 // return 的对象,可以直接在 模板中直接访问(不需要 .value)
          return {
            readersNumber,
            book
          }
        }
      }
    </script>
    
        

    渲染功能的实现

    setup 还可以返回一个渲染函数,该函数可以直接使用在同一作用域中(setup 函数中)声明的反应状态 :

    import { h, ref, reactive } from 'vue'
    export default {
      setup() {
        const readersNumber = ref(0)
        const book = reactive({ title: 'Vue 3 Guide' })
        // Please note that we need to explicitly expose ref value here
        return () => h('div', [readersNumber.value, book.title])
      }
    }
    
        

    this 指向问题

    setup 函数中,thisundefined 而不是 组件的引用。因为 setup 函数执行时,尚未创建组件实例。所以 thissetup 中无法正常使用。

    setup 函数和其他的 Options API 一起使用时,可能会出现无法预知的错误,所以一定要谨慎。

    生命周期钩子

    setup 中,可以通过 onX 的方式注册 生命周期钩子

    import { onMounted, onUpdated, onUnmounted } from 'vue'
    const MyComponent = {
      setup() {
        onMounted(() => {
          console.log('mounted!')
        })
        onUpdated(() => {
          console.log('updated!')
        })
        onUnmounted(() => {
          console.log('unmounted!')
        })
      }
    }
    
        

    Options API(Vue 2.x) 生命周期选项和 Composition API(Vue 3.x) 之间的映射

    • beforeCreate ->使用 setup()
    • created ->使用 setup()
    • beforeMount -> onBeforeMount
    • mounted -> onMounted
    • beforeUpdate -> onBeforeUpdate
    • updated -> onUpdated
    • beforeUnmount -> onBeforeUnmount
    • unmounted -> onUnmounted
    • errorCaptured -> onErrorCaptured
    • renderTracked -> onRenderTracked
    • renderTriggered -> onRenderTriggered

    提供 provide / 注入 inject

    首先必须要明确:提供 provide / 注入 inject 的功能都只能在 setup 函数中进行使用。

    如果你希望在 父组件 中提供一个值,然后在 子组件 中可以使用。那么你就应该考虑 提供 provide / 注入 inject 的功能。

    // 父组件
    setup() {
        // 为子组件提供一个值,并且这个值是响应式的(ref)
        // 则代表:子组件可以修改该值(book.value),并且会 响应式的 作用于父组件的变量中
        let book = ref('父组件的book');
        // 为子组件提供一个值,并且这个值不是响应式的
        // 则代表:子组件获取到了 非响应式的 数据。
        // 此时:子组件可以通过 ref(inject('book', '默认值')) 的方式,把该数据变为 响应式的 ,但是要注意,此时的响应式仅在 子组件中生效
        let book = '父组件的book';
        provide('book', book);
        return {
            book,
        };
    },
    // 子组件
    setup () {
        // 利用 inject 函数,获取父组件提供的值
        let book = inject('book', '默认值');
        // 利用 inject 函数,获取父组件提供的值,同时把它变为响应式的。但是要注意,此时的响应式仅在 子组件中生效
        let book = ref(inject('book', '默认值'))
    }
    
        

    新的响应式

    代理对象

    当我们把 JavaScript 对象作为 data 选项传递给 Vue 实例的时候,Vue 会遍历对象的所有属性,并且会把它们转化成带有 gettersetter 函数的 Proxies(代理对象)

    同时为了兼顾低版本的浏览器,对于较久的版本,Vue 依然使用 Object.defineProperty 来进行支持。

    两者之间在使用中并没有区别,只不过 代理对象 会提供更好的性能。

    响应式数据的声明 - reactive 函数

    想要在 setup函数中 创建响应式数据,可以使用 reactive方法(注意:需要主动导入 reactive

    <template>
      <div>
      	<h1>Vue 3</h1>
      	<button @click="state.count++">count is: {
         { state.count }}</button>  
      </div>
    </template>
    <script>
    import { reactive } from 'vue';
    export default {
      name: 'HelloWorld',
      setup() {
         // 创建的响应式数据对象
        const state = reactive({
          count: 0,
        });
        return {
          // 直接放回创建的响应式对象
          state,
        };
      },
    };
    </script>
    

    注意:Vue 3 中并没有取消 data 声明,也就是说,我们依然可以使用 data 函数来创建响应式数据。以下两种写法在响应式效果 中等效

    // setup() {
      //   const state = reactive({
      //     count: 0,
      //   });
      //   return {
      //     state,
      //   };
      // },
      // 效果等效
      data() {
        return {
          state: {
            count: 0,
          },
        };
      },
    
     

    将一个非响应式数据转化为响应式数据 - ref 函数

    Vue 3 对 ref 函数进行了改变,使 ref 具备了两种能力:

    1. 使用 ref 获取 元素 或 组件实例
    2. 可以把一个非响应式的数据改变为响应式的

    我们在这里探讨的就是 ref 函数的第二个能力:

    <template>
      <h1>Vue 3</h1>
      <button @click="count++">count is: {
      { count }}</button>
    </template>
    <script>
    import { ref } from 'vue';
    export default {
      setup() {
        // ----- 利用 setup 函数返回 ------
        let count = 0;
         return {
          count,
        };
        // ----- 利用 reactive 函数 ------
        const state = reactive({
          count: 0,
        });
        return {
          // count 值的改变,将不会影响视图的变化,原因请查看 《对象的响应式》  
          count: state.count,
        };
        // ----- 利用 ref 函数 ------
        let count = ref(0);
        return {
          count,
        };
      }
    };
    </script>
    

    以上三种方式,貌似可以达到同样的效果。

    那么 ref 的作用是什么呢?再来回顾一下:ref 函数可以将一个非响应式数据转化为响应式数据。即:当数据发生了变化的时候,视图也理应发生变化。我们来看下面的代码:

    setup() {
        // ----- 利用 setup 函数返回 ------
        let count = 0;
        setTimeout(() => {
        // 视图并没有发生变化
          count = 1;
        }, 1000);
        return {
          count,
        };
        // ----- 利用 reactive 函数 ------
        et state = reactive({
          count: 0,
        });
        setTimeout(() => {
        // 视图并没有发生变化
           state.count = 1;
        }, 1000);
        return {
          count: state.count,
        };
        // ----- 利用 ref 函数 ------
        let count = ref(0);
        setTimeout(() => {
          // 访问 count 的值,需要使用 value 属性
          // 注意:在模板中,我们不需要手动写入 value
          // 视图发生了变化
          count.value = 1;
        }, 1000);
        return {
          count,
        };
      },
    
     

    在上面的代码中,我们通过 setTimeout 延迟 1 秒钟之后改变数据源 count 的值,从结果中,我们可以发现,只有被 ref 函数声明的 count 才会直接影响视图的变化。

    对象的响应式

    通常情况下,我们希望利用 解构赋值 的方式来获取到响应式数据:

    <template>
      <h1>Vue 3</h1>
      <button @click="count++">count is: {
      { count }}</button>
    </template>
    <script>
    import { reactive } from 'vue';
    export default {
      setup() {
        // ----- 利用 reactive 函数 ------
        let state = reactive({
          count: 0,
        });
        let { count } = state;
        setInterval(() => {
          // 视图并没有发生变化
          count++;
        }, 1000);
        return {
          count,
        };
      },
    };
    </script>
    

    但是很遗憾,这种方式将会让 count 失去响应性

    如果我们想要解决这个问题,那么需要借助一个函数 toRefs。同样的,我们需要先 导入 这个函数。

    // 不要忘记,我们需要导入 toRefs
    import { toRefs } from 'vue';
    let state = reactive({
        count: 0,
    });
    // 借助 toRefs 函数,让数据保持响应性
    let { count } = toRefs(state);
    setInterval(() => {
        // 同样需要是使用 value 来访问到数据源
        count.value++;
    }, 1000);
    return {
        count,
    };
    
     

    只读的响应式数据

    有时我们希望 数据为响应式 的同时,该数据不被其他的组件所修改 (即:我们想要其他组件 享受 响应数据(refreactive )的变化,同时也想要防止其他的组件修改响应式数据),那么我们需要给其他组件 只读的响应式数据 - readonly

    <!-- state.count 发生改变,readonlyState.count 会同步跟随变化 -->
    <button @click="state.count++">count is: {
      { state.count }}</button> 
    <!-- 如果想要直接修改 readonlyState.count 的值,那么会得到一个警告:Set operation on key "count" failed: target is readonly -->
    <button @click="readonlyState.count++">count is: {
      { readonlyState.count }}</button>
    <script>
    import { reactive, readonly } from 'vue';
    export default {
    setup() {
          // 响应式数据对象 state
          const state = reactive({
            count: 0
          })
          // 只读数据 readonlyState
          // state 称为 readonlyState 源数据
          const readonlyState = readonly(state)
          return {
            state,
            readonlyState
          }
        }
    </script>
    
     

    这样我们就获得了一个只读的响应式数据 readonlyState 和它的源数据 state 。如果我们想要修改 readonlyState 的值,那么唯一的方式是 修改state

    对于 readonly 来说,源数据的变化会响应式的作用于 readonly

    计算属性与侦听器

    计算属性

    基本用法

    Vue 计划使用 computed 函数 来定义 计算属性 (这并不代表 Options API 被完全丢弃),看下面的示例:

    <template>
      <input type="text" v-model="str" />
      <h2>{
      { comStr }}</h2>
    </template>
    <script>
    import { ref, computed } from 'vue';
    export default {
      setup() {
        const str = ref('Hello');
        // Vue 3 中推荐写法,完全等效于 computed 属性中函数定义
        const comStr = computed(() => str.value.split('').reverse().join(''));
        return {
          str,
          comStr,
        };
      },
      /*  Vue 2.x 的写法并没有被废弃,只是不再被推荐使用。
      以下写法完全等效于 Vue 3 中的 computed 函数 */
      computed: {
        comStr() {
          return this.str.split('').reverse().join('');
        },
      },
    };
    </script>
    

    set 和 get

    computed 函数 包含了 getset 方法:

    const count = ref(1)
    // 此代码等于使用了 getter 函数
    const plusOne = computed(() => count.value++)
    // 当我们获取 plusOne 的值时,等于调用了 get
    console.log(plusOne.value) // 2
    // 但是因为没有实现 setter 函数,所以无法设置新值
    // err:setter is not a function
    plusOne.value++ 
    
     

    我们可以使用具有 getset 功能的对象来创建可写的 ref 对象

    const count = ref(1)
    const plusOne = computed({
      get: () => count.value + 1,
      set: val => {
         count.value = val - 1;
      }
    })
    plusOne.value = 1;
    console.log(count.value); // 0
    
     

    此时对 plusOneset 操作会回调到 传入对象的 set 方法中。

    监听函数:watchEffect

    如果你想要监听响应式数据的变化,那么可以使用 watchEffect 函数

    watchEffect 函数 的运行时机有两个:

    1. 调用函数时,立刻运行
    2. 依赖项的数据发生变化时,会立刻运行
    const count = ref(0);
    // 立刻打印:0
    watchEffect((v) => {
        // 依赖数据发生变化时,依次打印 1.2.3.4....
        console.log(count.value);
    });
    setInterval(() => {
        count.value++;
    }, 1000);
    return {
        count,
    };
    
     

    如果你想要停止 watcher 的话,那么可以返回方法进行停止

    const stop = watchEffect(() => {
      /* ... */
    })
    // 调用返回的停止函数
    stop()
    
     

    watch

    watch API完全等同于组件 watch 属性。

    watch需要查看特定的数据源,并在单独的回调函数中应用副作用。

    默认情况下,它也是惰性的。即仅在监视的源已更改时才调用回调。

    参数:

    • {string | Function} source
    • {Function | Object} callback
    • {Object} [options]
      • {boolean} deep
      • {boolean} immediate

    监听单一的数据源变化

    watcher 的数据源可以有两种:

    1. 返回值的 getter 函数
    2. ref
    // 监听 返回值的 getter 函数
    const state = reactive({ count: 0 })
    watch(
      () => state.count,
      (count, prevCount) => {
        /* ... */
      }
    )
    // 监听 ref
    const count = ref(0)
    watch(count, (count, prevCount) => {
      /* ... */
    })
    
     

    监听多个数据源的变化

    使用数组的方式可以监听多个数据源

    watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
      /* ... */
    })
    
     

    options 参数对象

    options 参数对象主要有两个属性:

    1. deep:监听对象内部嵌套值的改变。注意:你不需要制定 deep 既可以监听到 Array 的变化
    2. immediate:立刻触发回调

    teleport (传送)

    在 Vue 的技术体系中,我们一直以来都是根元素中做事情(<div id="app" ></div>),这个逻辑是没有问题的。

    但是在 Vue 3 中提出了一个新的概念 teleport

    它是一个组件,使用它可以让我们的渲染区 脱离 根元素。这也是 传送 所代表的意思:将视图传送出渲染区(同时视图将保持响应式的渲染)

    <body>
      <!-- 渲染区 -->
      <div id="app">
      </div>
      <!-- 
        转移区。
        注意:目标元素必须在组件挂在前就已经存在。
        即目标不能由组件本身渲染,并且理想情况下应位于整个Vue组件树之外。 
      -->
      <div id="endofbody"></div>
    </body>
    <script>
      const app = Vue.createApp({
        template: `
        <h1>根组件</h1>
        <parent-component />
      `
      })
      app.component('parent-component', {
        template: `
        <h2>父组件</h2>
        <teleport to="#endofbody">
          <child-component :name="name" />
        </teleport>
      `,
        data() {
          return {
            name: '张三'
          }
        },
        created: function () {
          setTimeout(() => {
            this.name = '李四'
          }, 1000)
        }
      })
      app.component('child-component', {
        props: ['name'],
        template: `
        <h4>被转移的子组件,它将出现在 app 之外</h4>
        <h4>同时享受响应式数据改变带来的视图变化,不信?你刷新页面,等一秒钟看一下</h4>
        <div>Hello, {{ name }}</div>
      `
      })
      app.mount('#app')
    </script>
    
     

    并且,你需要知道,传送是可以支持多个的。即:可以存在多个 teleport 组件指向同一个 目标区域

    <teleport to="#modals">
      <div>A</div>
    </teleport>
    <teleport to="#modals">
      <div>B</div>
    </teleport>
    <!-- 结果-->
    <div id="modals">
      <div>A</div>
      <div>B</div>
    </div>
    
     

    Fragment

    组件不再强制单个根元素,这个特性 Vue 3 称为 Fragment(碎片)

    以下代码可以正常运行(虽然会有 ESLint 警告)

    <template>
      <header>...</header>
      <main v-bind="$attrs">...</main>
      <footer>...</footer>
    </template>
    
     

    自定义事件

    Vue 3 建议对组件中所有发出的事件 emit 进行记录 emits 。如果你声明了 emits 选项,并且发送的事件没有被 emits 记录,则会收到一个警告:

    app.component('custom-form', {
        template: `
          <form>
    		<!-- 此处会收到警告:
        [Vue warn]: Component emitted event "submit" but it is neither declared in the emits option nor as an "onSubmit" prop 
    -->
            <input type="button" value="submi" @click="$emit('submit')"/>
          </form>
        `,
        emits: {
        }
      })
    
     

    记录的形式分为两种:

    1. 数组:如果使用数组进行记录,那么可以只可以进行声明,而不可以进行验证(参考 prop 机制)
    2. 对象:对象语法可以对 发送的事件 进行验证

    以下为对象验证:

      app.component('custom-form', {
        template: `
          <form>
            <input type="button" value="submi" @click="$emit('submit', {email: 'aa@163.com', password: 'aaa'})"/>
          </form>
        `,
        emits: {
          // 无验证
          click: null,
          // 为 submit 事件添加验证规则
          // 如果不符合验证规则,你会收到一个警告
          submit: ({ email, password }) => {
            if (email && password) {
              console.log('验证通过');
              return true
            } else {
              console.warn('这是一个无效的提交事件!')
              return false
            }
          }
        }
      })
    
     

    组件中的 v-model

    Vue2.2.0 的版本中新增了 自定义组件的 v-model2.3.0 中新增了 .sync 修饰符。 在功能上 sync 更像是 自定义组件的 v-model 的增强。

    Vue 3 中,自定义组件的 v-model 进行了进一步的增强,使其更像是 v-bind:foo.sync 的另一种写法:

    // 子组件声明
    app.component('my-component', {
      props: {
        foo: String
      },
      template: `
        <input 
          type="text"
          :value="foo"
          @input="$emit('update:foo', $event.target.value)">
      `
    })
    // 父组件调用
    <my-component v-model:foo="bar"></my-component>
    
     

    同时,自定义组件的 v-model 支持了 多重绑定

    // 子组件声明
    app.component('user-name', {
      props: {
        firstName: String,
        lastName: String
      },
      template: `
        <input 
          type="text"
          :value="firstName"
          @input="$emit('update:firstName', $event.target.value)">
        <input
          type="text"
          :value="lastName"
          @input="$emit('update:lastName', $event.target.value)">
    })
    // 父组件调用
    <user-name
      v-model:first-name="firstName"
      v-model:last-name="lastName"
    ></user-name>
    
     
    展开全文
  • Vue.js 3.0官方文档

    千次阅读 2020-07-31 02:17:33
    随着Vue3.0 RC版本的发布,官方也给随之发布了测试版的文档《Vue.js 3.0官方文档(测试版)》。虽然文档还没有更新完,但是这个时候可以先看一波迁移指南。 另外更多消息可以关注news.vuejs.org官方博客 ...

    随着Vue3.0 RC版本的发布,官方也随之发布了测试版的文档《Vue.js 3.0官方文档(测试版)》。虽然文档还没有更新完,但是这个时候可以先看一波迁移指南

    迁移指南截图

    另外更多消息可以关注news.vuejs.org官方博客

    -------------------------------------------------

    2021.03.24

    Vue3.0官方文档(正式版)

    展开全文
  • vue3.0搭建项目文档

    2020-10-31 18:22:08
    vue3.0项目安装文档,很详细,适用于初学vue的小伙伴们,只需一遍搭建环境,啦啦啦啦啦。。。。。。
  • vue3.0学习文档

    2020-09-21 17:38:32
    vue2.X版本 eventBus.js const eventHub = new Vue() export default eventHub childComponent.vue // ChildComponent.vue import eventHub from './eventHub' export default { mounted() { //

    删除的api

    • o n , on, onoff,$once

    $on$off$once被删除实例方法。应用程序实例不再实现事件发射器接口

    vue2.X版本

    eventBus.js

    const eventHub = new Vue()
    export default eventHub
    

    childComponent.vue

    // ChildComponent.vue
    import eventHub from './eventHub'
    export default {
      mounted() {
        // adding eventHub listener
        eventHub.$on('custom-event', () => {
          console.log('Custom event triggered!')
        })
      },
      beforeDestroy() {
        // removing eventHub listener
        eventHub.$off('custom-event')
      }
    }
    

    parentComponent.vue

    import eventHub from './eventHub'
    export default {
      methods: {
        callGlobalCustomEvent() {
          eventHub.$emit('custom-event') // if ChildComponent is mounted, we will have a message in the console
        }
      }
    }
    

    vue3.0版本

    我们删除$on,$off,$once从完全的实例方法。$emit仍然是现有API的一部分,因为它用于触发由父组件声明式附加的事件处理程序

    • 过滤器
      过滤器已从Vue 3.0中删除,不再受支持

    vue2.X语法

    <template>
      <h1>Bank Account Balance</h1>
      <p>{{ accountBalance | currencyUSD }}</p>
    </template>
    <script>
      export default {
        props: {
          accountBalance: {
            type: Number,
            required: true
          }
        },
        filters: {
          currencyUSD(value) {
            return '$' + value
          }
        }
      }
    </script>
    

    vue3.X语法

    在3.x中,过滤器已删除,不再受支持。相反,我们建议将它们替换为方法调用或计算的属性

    <template>
      <h1>Bank Account Balance</h1>
      <p>{{ accountInUSD }}</p>
    </template>
    
    <script>
      export default {
        props: {
          accountBalance: {
            type: Number,
            required: true
          }
        },
        computed: {
          accountInUSD() {
            return '$' + this.accountBalance
          }
        }
      }
    </script>
    
    • 多根节点

    vue2.X语法

    在2.x中,不支持多根组件,并且在用户意外创建组件时会发出警告。结果,许多组件被包装在一个

    中,以解决此错误。

    <template>
      <div>
        <header>...</header>
        <main>...</main>
        <footer>...</footer>
      </div>
    </template>
    

    vue3.X语法

    <!-- Layout.vue -->
    <template>
      <header>...</header>
      <main v-bind="$attrs">...</main>
      <footer>...</footer>
    </template>
    
    • setup(vue3.X语法)
    <template>
      <div>{{count}}: {{double}}</div>
      <button @click="increment">+1</button>
    </template>
    
    <script>
      import { ref, computed } from 'vue'
      export default {
        setup() {
          let count = ref('abc')
          let double = computed(() => count.value + 'de')
          function increment() {
            count.value = count.value + 'f';
          }
          return {
            count,
            double,
            increment
          }
        }
      }
    </script>
    

    在这里插入图片描述

    • 代码复用
      useCount.js
    import { ref, computed } from 'vue'
    function useCount() {
        let count = ref(0)
        let double = computed(() => count.value * 2)
        function increment() {
            count.value++
        }
        return {
            count,
            double,
            increment
        }
    }
    export default useCount
    

    app.vue

    import useCount from './useCount.js'
    export default {
        setup() {
            let { count, double, increment } = useCount()
            return { 
                count,
                double,
                increment
            }
        }
    }
    
    • 生命周期(vue3.0语法)

    App.vue

    <template>
      <img alt="Vue logo" src="./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3.0 + Vite" @count="fnCount">
        <div>我是slots1</div>
        <div>我是slots2</div>
        <div>我是slots3</div>
        <div>我是slots4</div>
        <div>我是slots5</div>
      </HelloWorld>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
      name: 'App',
      setup(props,context){
        function fnCount(count){
          console.log(count); // 1,2,3,4,5...
        }
        return {
          fnCount
        }
      },
      components: {
        HelloWorld
      }
    }
    </script>
    

    HelloWorld.vue

    <template>
      <div>props值:{{msgProps}}</div>
      <div>{{count}}: {{double}}</div>
      <button @click="increment">改变count</button>
      <slot></slot>
    </template>
    
    <script>
      import useCount from './useCount.js'
      import { ref, computed, onMounted  } from 'vue'
      export default {
        props: {
          msg: {
            type: String,
            defalut: ''
          }
        },
        setup(props,context) {
          let { count, double, increment, msgProps } = useCount(props, context)
          onMounted(() => {
            console.log(context.slots.default()); //获取到父级slot插槽中内容
          })
          return {
            count,
            double,
            increment,
            msgProps
          }
        }
      }
    </script>
    

    在这里插入图片描述

    <template>
      <div>props值:{{msgProps}}</div>
      <div>{{count}}: {{double}}</div>
      <button @click="increment">改变count</button>
      <!-- 点击fnChange改变,我是改变后的title -->
      {{state.title}}
      <button @click="fnChange">改变title</button>
      <slot></slot>
    </template>
    
    <script>
      import useCount from './useCount.js'
      import { ref, computed, onMounted, reactive  } from 'vue'
      export default {
        props: {
          msg: {
            type: String,
            defalut: ''
          }
        },
        setup(props,context) {
          let { count, double, increment, msgProps } = useCount(props, context)
          const state = reactive({ title: '原title' })
          function fnChange(){
            state.title = '我是改变后的title'
          }
          onMounted(() => {
            console.log(context.slots.default())
          })
          return {
            count,
            double,
            increment,
            msgProps,
            fnChange,
            state
          }
        }
      }
    </script>
    
    • 渲染函数(vue3.0)
    import { h, ref, reactive } from 'vue'
    export default {
      setup() {
        const readersNumber = ref(0)
        const book = reactive({ title: 'Vue 3 Guide' })
        // Please note that we need to explicitly expose ref value here
        return () => h('div', [readersNumber.value, book.title])
      }
    }
    
    • provide & inject(vue3.0)
      类似于vue2中provide与inject, vue3提供了对应的provide与inject API,实现组件传参。
      provide 函数允许你通过两个参数定义 property:
    1. property 的 name ( 类型)
    2. property 的 value

    myMap.vue

    <script>
        import {provide} from 'vue'
        import myMarker from './myMarker.vue'
        export default {
            name: "myMap",
            components:{
                myMarker
            },
            setup(){
                provide('location', 'North Pole')
                provide('geolocation', {
                    longitude: 90,
                    latitude: 135
                })
            }
        }
    </script>
    

    myMarker.vue

    <template>
        {{userLocation}} {{userGeolocation.longitude}}
    </template>
    
    <script>
        import { inject } from 'vue'
        export default {
            setup() {
                const userLocation = inject('location', 'The Universe')
                const userGeolocation = inject('geolocation')
                return {
                    userLocation,
                    userGeolocation
                }
            }
        }
    </script>
    <style scoped>
    
    </style>
    
    • watch & computed(vue3.0语法)

    watch:侦听器,接受三个参数

    1. 一个响应式引用或我们想要侦听的 getter 函数
    2. 一个回调
    3. 可选的配置选项
    import { ref, watch } from 'vue'
    export default {
        setup() {
            const counter = ref(0)
            watch(counter, (newValue, oldValue) => {
                console.log('The new counter value is: ' + counter.value)
            })
        },
        // setup中的相当于以下
        data() {
            return {
                counter: 0
            }
        },
        watch: {
            counter(newValue, oldValue) {
                console.log('The new counter value is: ' + this.counter)
            }
        }
    }
    

    或者如下代码:

    <template>
        {{obj.a}}
        {{count}}
        <button @click="fnChangeCount">改变count</button>
    <!--    <myMarker/>-->
    </template>
    
    <script>
        import {provide, watch, ref, reactive} from 'vue'
        // import myMarker from './myMarker.vue'
        export default {
            name: "myMap",
            // components:{
            //     myMarker
            // },
            setup(){
                let count = ref(0);
                let obj = ref({a: 1})
                function fnChangeCount(){
                    count.value++;
                    obj['value']['a'] = 2;
                }
    
                function getProxy(obj) {
                    return new Proxy(obj, {
                        get: function(target, property) {
                            if (property in target) {
                                return target[property];
                            } else {
                                throw new ReferenceError("Property \"" + property + "\" does not exist.");
                            }
                        }
                    });
    
                }
    
                watch(count, (newVal, oldVal) => {
                    console.log(newVal,oldVal)
                })
                watch(obj, (newVal, oldVal) => {
                    console.log(getProxy(newVal).a, getProxy(oldVal).a)
                },{
                    deep: true,     // 深度监听
                    lazy: true,     // vue中的immediate,默认挂载后执行
                    flush: '',      // 三个值:'post'(默认), 'pre', 'sync'
                                    // 'pre': 表示在状态更新时同步调用
                                    // 'sync':表示在组件更新之前调用
                    onTrack(){},    // 在reactive属性或ref被追踪为依赖时调用。
                    onTrigger(){
                        
                    }   // 在watcher的回调因依赖改变而触发时调用。
                })
                return {
                    obj,
                    count,
                    fnChangeCount
                }
                // provide('location', 'North Pole')
                // provide('geolocation', {
                //     longitude: 90,
                //     latitude: 135
                // })
            }
        }
    </script>
    <style scoped>
    
    </style>
    

    watch第三个参数:

    {
        deep: true,     // 深度监听
        lazy: true,     // vue中的immediate,默认挂载后执行
        flush: '',      // 三个值:'post'(默认), 'pre', 'sync'
                        // 'pre': 表示在状态更新时同步调用
                        // 'sync':表示在组件更新之前调用
        onTrack(){},    // 在reactive属性或ref被追踪为依赖时调用。
        onTrigger(){}   // 在watcher的回调因依赖改变而触发时调用。
    }
    
    • computed
      与vue2中computed功能一致,它接收一个函数并返回一个value为getter返回值的不可改变的响应式ref对象。
    const count = ref(1)
    const plusOne = computed(() => count.value + 1)
    console.log(plusOne.value) // 2
    plusOne.value++ // 错误,computed不可改变
    
    // 同样支持set和get属性
    onst count = ref(1)
    const plusOne = computed({
        get: () => count.value + 1,
        set: val => { count.value = val - 1 }
    })
    plusOne.value = 1
    console.log(count.value) // 0
    
    
    展开全文
  • vue3.0(包含中文官方文档)

    千次阅读 2020-08-03 01:09:03
    npm i -g @vue/cli cnpm install -g @vue/cli 需要以前安装淘宝镜像: npm install -g cnpm --registry=http://registry.npm.taobao.org
  • Vue3.0 学习资源文档Vue3.0 中文文档:https://www.vue3js.cn/docs/zh/ Vue3.0 组合API使用:http://www.liulongbin.top:8085/#/ Vue3.0 Vuex 替代方案: https://zhuanlan.zhihu.com/p/114783130 B站视频学习...
  • vue-cli3.0完整项目demo

    2018-09-20 10:48:57
    vue-cli3.0完整项目demo,路由配置以及vuex多store配置以及调用,不错的学习资料。
  • element_vue3.0 / VE-Admin 项目简介 基于vue3和element-plus开发的企业后台管理模板。 功能特性 项目使用了最新的vue3全家桶+元件加+ mockjs + Axios公司+ eChart5。项目继成了mockServe,可脱离后端自主开发测试...
  • vue3.0 案例小demo

    2021-08-20 17:53:41
    vue3.0 + ts + ant-design-vue + stylus 技术栈 选择 Vue 作为框架 用了 vue-router 和 vuex 选择了 Ant Design Vue UI框架 工具库选择 lodash 选择了CSS 预处理器 stylus 全局样式 目录:@/styles : global.scss:...
  • Vue3.0 10分钟上手体验-官方Demo

    千次阅读 2020-09-29 11:27:56
    vue3.0RC 版本已经发布有一阵子了,是时候上手体验一波了~ 尤雨溪:Vue 3.0 计划掘金译文 有三种方式体验Vue3.0: 1 Clone官方demo体验 2 通过vue-cli 4体验 3 通过Vite体验 下面介绍通过第一种方式体验Vue3.0...
  • vue 3.0文档

    千次阅读 2020-08-29 13:58:48
    https://juejin.im/post/6858558735695937544#heading-150
  • ???? Element UI for Vue 3.0 来了! 第一个使用 TypeScript + Vue 3.0 Composition API 重构的组件库 Element Plu...
  • vue 3.0+ antd

    千次阅读 2020-05-13 17:03:12
    因为之前react一直使用antd,转vue后,还是想用顺手的样式,所以又开始连接antd 我连了一天,把vue.config.js配置了一...emmm这个文件在vue3.0里面没有,所以大家可以自己在根目录下面建一个 vue-cli配置指南官网 cons
  • Vue3.0 +TS ,使用新版Vuex 和 Vue-Router 全家桶让你学会一个基本的组件库的开发思路和技巧。接入真实后端API,提供抓住前后端分离开发痛点 - 权限管理,路由控制,全局Store 结构设计,前端缓存实现等
  • vue3.0 国际化 i18n

    2021-01-15 09:31:15
    vue3.0 国际化插件i18n
  • vue3.0---路由跳转

    2021-06-07 11:39:06
    <template> <div> <button @click="beginFn">...import { defineComponent } from 'vue' import {useRouter} from 'vue-router' export default defineComponent({ name:'home',
  • 目前版本基于 vue-cli + Vue 3.0 + Element Plus 进行构建,参考 做了简单的升级适配 Vue 3.0 和 Element Plus,所以绝大部分还是 的味道。 相关文档 Build Setup # 克隆项目 git clone ...
  • Vue 3.0中jsx语法的使用

    2021-01-21 10:54:12
    Vue 3.0 正式发布了,喜大普奔:beaming_face_with_smiling_eyes:。新的语法又要学习一阵阵,不过需要在生产环境下大面积使用,可能需要等到它的周边工具:vuex,vue-router 等等全部升级完毕。 Vue 3.0 中尤大使用的...
  • vue3.0+ 3.x config配置

    千次阅读 2019-06-30 23:12:08
    参考官方文档:https://cli.vuejs.org/zh/config baseUrl 从 Vue CLI 3.3 起已弃用,请使用publicPath。 publicPath Type: string Default: ‘/’ 这个值也可以被设置为空字符串 (’’) 或是相对路径 (’./’),这样...
  • vue3.0文档

    2020-09-27 15:23:38
    https://v3.vuejs.org/guide/installation.html yue.cli文档 https://cli.vuejs.org/guide/installation.html
  • 平台是个超简易的入手平台,vue-elm-admin 扩展的一大堆功能统统抛弃,越庞大对新手越不友好,连我这老鸟看着多头痛,从简单做起。然后要什么在从官方DEMOCOPY模块过来!值得你拥有。 全用TS实现写的,有助于团队合作...
  • 我使用的是最新的Vue3.0,照着Element的文档引入,结果页面出现白版,F12打开开发者工具一片飘红,一顿操作。原来是从Vue3.0不支持Element UI,而是改成了Element Plus。又经过一顿操作,页面出来了,心情瞬间大好。...
  • Vue3.0快速使用 vite创建Vue3.0

    千次阅读 2020-04-17 22:43:45
    vue3.0 API文档地址:https://vue-composition-api-rfc.netlify.app/ 1.vue/cli 3以上 2.新建一个项目 vue create vue3-2020-4-17(该项目仍然是2.0) 3.使用vue add vue-next命令,将项目升级为3.0(如果报错...
  • vue3.0,ts,仿知乎专栏企业级项目 破解码,13章
  • vue3.0 nextTick

    2021-05-29 20:34:09
    import { createApp, nextTick } from 'vue' 方式一: const app = createApp({ setup() { const changeMessage = async newMessage => { ... await nextTick() 会返回一个Promise对象,所以可以使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,210
精华内容 2,884
关键字:

vue3.0官方文档

vue 订阅