>  기사  >  웹 프론트엔드  >  Vuejs 기술 스택에 대한 지식 요약

Vuejs 기술 스택에 대한 지식 요약

零下一度
零下一度원래의
2017-06-27 09:41:152083검색

머리말

이전 회사의 프로젝트는 주로 jQuery와 Angular1을 사용하다가 React를 배웠습니다. 이 회사에 와서 갑자기 Vue를 시작하게 될 줄은 몰랐는데, Vue는 여전히 시작하기 쉽습니다. . 다음은 공식 웹사이트에서 가져온 vue 기술 스택의 일부 요약입니다. 이는 주로 vue 기술 스택에 대한 지식 포인트를 모아 놓은 것입니다. CLI부터 패키징, 온라인 구현까지의 기술 스택

Vue

독립 빌드 및 런타임 빌드

독립 빌드와 런타임 빌드의 두 가지 빌드 방법이 있습니다. 차이점은 전자에는 템플릿 컴파일러가 포함되어 있고 후자에는 포함되어 있지 않다는 것입니다.

템플릿 컴파일러의 책임은 템플릿 문자열을 순수 JavaScript 렌더링 함수로 컴파일하는 것입니다. 컴포넌트에서 템플릿 옵션을 사용하려면 컴파일러가 필요합니다.

Life Cycle

공식 홈페이지의 순서도를 구체적으로 살펴보세요. 생성된 것과 마운트된 것의 차이점은 VM 인스턴스가 생성되었지만 마운트되지 않았음을 의미하므로 일부 DOM 작업이 필요합니다. 마운트에 배치했습니다. 비동기식 요청이 생성됨 또는 마운트됨에 차이가 없습니다. 차이점을 아시는 분은 댓글을 달아주세요.

계산된 속성

템플릿의 표현식에는 너무 많은 논리가 포함되어서는 안 됩니다. 복잡한 논리의 경우 계산된 속성을 사용해야 합니다.

계산된 속성과 메서드의 차이점은 계산된 속성이 종속성에 따라 캐시된다는 것입니다.

계산 속성과 계산 속성, 일반적으로 더 좋은 아이디어는 명령형 감시 콜백 대신 계산 속성을 사용하는 것입니다. 대부분의 경우 계산된 속성이 더 적합하지만 때로는 사용자 지정 감시자가 필요합니다. 이는 데이터 변경에 대한 응답으로 비동기식 또는 비용이 많이 드는 작업을 수행하려는 경우 유용합니다.

배열 업데이트 감지

배열의 돌연변이 방법(이러한 방법으로 호출된 원래 배열을 변경하는 돌연변이 방법)은 다음과 같은 7가지가 있습니다:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

비 돌연변이 방법을 사용하는 경우, 새로운 배열로 교체할 수 있습니다. 이전 배열이거나 Vue.set 메소드를 사용할 수 있습니다.

객체 업데이트

이전 객체를 새 객체로 바꾸거나 Vue.set 메소드를 사용할 수 있습니다

Vue.set(vm.someObject, 'foo', 'bar')

this.someObject = Object.assign({}, this.someObject, { a:1, b:2 })

Event handler

Vue.js는 v-on

Form 컨트롤 바인딩을 위한 이벤트 수정자와 키 수정자를 제공합니다.

v-model 지시문을 사용하여 양식 제어 요소에 대한 양방향 데이터 바인딩을 만들 수 있습니다. 일반적인 수정자에는 .lazy, .number 및 .trim이 포함됩니다.

사용자 정의 이벤트와 함께 양식 입력 구성 요소를 사용할 수도 있습니다.

Components

Vue 구성 요소의 API는 소품, 이벤트, 슬롯의 세 부분으로 구성됩니다.

  • Props를 사용하면 외부 환경에서 구성 요소에 데이터를 전달할 수 있습니다.

  • Event를 사용하면 구성 요소가 부작용을 유발할 수 있습니다. 외부 환경

  • 슬롯을 사용하면 외부 환경이 추가 콘텐츠를 구성 요소에 결합할 수 있습니다.

1) 컴포넌트의 데이터 속성은 함수여야 합니다.

2) 부모-자식 컴포넌트

Vue.js에서 부모-자식 컴포넌트 간의 관계는 props down, events up으로 요약할 수 있습니다. 상위 컴포넌트는 props를 통해 하위 컴포넌트에 데이터를 전달하고, 하위 컴포넌트는 이벤트를 통해 상위 컴포넌트에 메시지를 보냅니다.

prop는 단방향 바인딩입니다. 상위 구성 요소의 속성이 변경되면 하위 구성 요소로 전송되지만 그 반대 방향으로는 전송되지 않습니다. 이는 하위 구성 요소가 상위 구성 요소의 상태를 실수로 수정하여 애플리케이션의 데이터 흐름을 이해하기 어렵게 만드는 것을 방지하기 위한 것입니다.

또한 상위 구성 요소가 업데이트될 때마다 하위 구성 요소의 모든 props가 최신 값으로 업데이트됩니다. 즉, 하위 구성 요소 내부의 소품을 변경하면 안 됩니다. 이렇게 하면 Vue가 콘솔에 경고를 표시합니다.

우리는 왜 소품의 데이터를 수정하고 싶은 충동을 느끼나요? 일반적으로 두 가지 이유가 있습니다.

1.prop이 초기 값으로 전달되고 하위 구성 요소가 이를 로컬 데이터로 사용하려고 합니다.

2.prop이 초기 값으로 전달되고 하위 구성 요소가 이를 다른 데이터로 처리합니다. 데이터 출력.

이 두 가지 이유에 대한 올바른 응답은 다음과 같습니다.

1. 지역 변수를 정의하고 prop 값으로 초기화합니다.

props: ['initialCounter'],
data: function () {
  return { counter: this.initialCounter }
}

2. 계산된 속성을 정의하고 prop 값을 처리하여 반환합니다.

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

객체와 배열은 JavaScript의 참조 유형이며 동일한 메모리 공간을 가리킵니다. prop이 객체나 배열인 경우 하위 구성 요소 내에서 이를 변경하면 상위 구성 요소의 상태에 영향을 미칩니다.

3) 비상위 컴포넌트

때로는 두 컴포넌트도 통신해야 합니다(비상위 관계). 간단한 시나리오에서는 빈 Vue 인스턴스를 중앙 이벤트 버스로 사용할 수 있습니다. 복잡한 경우에는 전문적인 상태 관리 패턴을 사용하는 것을 고려해야 합니다.

4).sync modifier

어떤 경우에는 prop에 "양방향 바인딩"을 수행해야 할 수도 있습니다.

.sync는 2.0에서 제거되었고 Vue2.3.0+에서 다시 추가되었지만 이번에는 컴파일 타임 구문 설탕으로만 존재하며 상위 구성 요소 속성을 자동으로 업데이트하는 v-on으로 확장됩니다. 경청자. 다음 코드

<comp :foo.sync="bar"></comp>

는 다음으로 확장됩니다.

<comp :foo="bar" @update:foo="val => bar = val"></comp>

하위 구성 요소가 foo의 값을 업데이트해야 하는 경우 명시적으로 업데이트 이벤트를 트리거해야 합니다.

this.$emit('update:foo', newValue)

5) 콘텐츠 배포를 위해 슬롯 사용

범위 슬롯: 수신 하위 구성 요소에서 전달된 소품 개체입니다. 범위 슬롯의 보다 대표적인 사용 사례는 목록 구성 요소로, 구성 요소가 목록의 각 항목을 렌더링하는 방법을 사용자 정의할 수 있도록 합니다.

6) 동적 구성 요소는 속성 및 연결 유지 지시문

7) 하위 구성 요소 인덱스

尽管有props和events,但是有时仍然需要JavaScript中直接访问子组件。为此可以使用ref为子组件指定一个索引ID。

异步更新队列

虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

过渡效果

Vue在插入、更新或者移除DOM时,提供多种不同方式的应用过渡效果。包括以下工具:

  • 在CSS过渡和动画中自动应用class

  • 可以配合使用第三方CSS动画库,如Animate.css

  • 在过渡钩子函数中使用JavaScript直接操作DOM

  • 可以配合使用第三方JavaScript动画库,如Velocity.js

1)单元素/组件的过渡

Vue提供了transition的封装组件,在下列情形中,可以给任何元素和组件添加过渡

  • 条件渲染(使用v-if)

  • 条件展示(使用v-show)

  • 动态组件

  • 组件根节点

2)多个元素的过渡

对于原生标签可以使用 v-if/v-else

3)多个组件的过渡

多个组件的过渡我们可以使用动态组件。

4)列表过渡

Render函数和JSX

自定义指令

和Angular的指令类似,主要操作DOM,下面是一个滚动加载的指令,holder暂时没想到什么更好的处理方法:

let scrollCallback = function (callback) {
  let windowH = window.innerHeight
  let getDocumentHeight = function () {
    var body = document.body
    var html = document.documentElement
    return Math.max(
      body.offsetHeight,
      body.scrollHeight,
      html.clientHeight,
      html.offsetHeight,
      html.scrollHeight
    )
  }
  let scrollH = document.documentElement.scrollTop || document.body.scrollTop
  if (windowH + scrollH >= getDocumentHeight() - (this.holder || 20)) {
    callback()
  }
}

let callBackWarpped

export default {
  bind (el, binding, vnode) {
    let holder
    if (vnode.data && vnode.data.attrs && vnode.data.attrs['scroll-placeholder']) {
      holder = parseInt(vnode.data.attrs['scroll-placeholder'])
    } else {
      holder = 20
    }
    callBackWarpped = scrollCallback.bind({el, holder}, binding.value)
    window.addEventListener('scroll', callBackWarpped, false)
  },

  unbind: function () {
    window.removeEventListener('scroll', callBackWarpped, false)
  }
}

混合

混合是一种灵活的分布式复用Vue组件的方式。混合对象可以包含任意组件选项。以组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。

插件

1)创建插件

Vue.js的插件应当有一个公开方法install。这个方法的第一个参数是Vue构造器 , 第二个参数是一个可选的选项对象。

2)使用插件

通过全局方法Vue.use()使用插件:

// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)

也可以传入一个选项对象:

Vue.use(MyPlugin, { someOption: true })

vue-router

两种导航方式

1)router-link声明式导航

<router-link to="/foo">Go to Foo</router-link>

router-link对应的路由匹配成功,将自动设置class属性值.router-link-active。

2)编程式导航

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

重命名(redirect)和别名(alias)

两种路由模式

vue-router默认hash模式,也可以设置为路由的history模式。

导航钩子

vue-router提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的。

路由meta

一个路由匹配到的所有路由记录会暴露为$route对象(还有在导航钩子中的route对象)的$route.matched数组。因此,我们需要遍历$route.matched来检查路由记录中的meta字段。

过渡动效

router-view是基本的动态组件,所以我们可以用transition组件给它添加一些过渡效果。

数据获取

有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:

导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示『加载中』之类的指示。

导航完成之前获取:导航完成前,在路由的enter钩子中获取数据,在数据获取成功后执行导航。

滚动行为(scrollBehavior)

注意: 这个功能只在HTML5 history模式下可用。

路由懒加载

当打包构建应用时,Javascript包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

结合Vue的异步组件和Webpack的code splitting功能,轻松实现路由组件的懒加载。

const Foo = resolve => require(['./Foo.vue'], resolve)

const router = new VueRouter({
  routes: [
    { path: '/foo', component: Foo }
  ]
})

router-link

可以设置tag、append、active-class、exact等属性

有时候我们要让 "激活时的CSS类名" 应用在外层元素,而不是a标签本身,那么可以用router-link渲染外层元素,包裹着内层的原生a标签:

<router-link tag="li" to="/foo">
  <a>/foo</a>
</router-link>

在这种情况下,a将作为真实的链接(它会获得正确的 href 的),而"激活时的CSS类名"则设置到外层的li。

Router构造配置

routes、mode、base、linkActiveClass、scrollBehavior

对组件注入

1)注入的属性

通过在Vue根实例的router配置传入router实例,下面两个属性成员会被注入到每个子组件。

$router:router实例

$route:当前激活的路由信息对象。这个属性是只读的,里面的属性是immutable(不可变)的,不过你可以watch(监测变化)它。

2)允许的额外配置:beforeRouteEnter、beforeRouteLeave

vuex

state

1)单一状态树

Vuex使用单一状态树--是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个『唯一数据源(SSOT)』而存在。这也意味着,每个应用将仅仅包含一个store实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

2)在Vue组件中获得Vuex状态

最好在根实例中注册store选项,该store实例会注入到根组件下的所有子组件中,且子组件能通过this.$store访问到。而不是在每个需要使用state的组件中需要频繁地导入。

3)mapState辅助函数

当一个组件需要获取多个状态时候,可以使用mapState辅助函数帮助我们生成计算属性,这样可以简化代码书写。mapState函数会返回一个对象,然后可以使用对象展开运算符将它与局部计算属性混合使用。

4)不要滥用vuex

使用Vuex并不意味着你需要将所有的状态放入Vuex。虽然将所有的状态放到Vuex会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。

getters

getters用来从store中的state中派生出一些状态,例如对列表进行过滤并计数:

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length
  }
}

getters可以认为是store的计算属性。和state类似,有mapGetters辅助函数。

mutations

更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutations非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数

1)提交载荷(Payload)

你可以向store.commit传入额外的参数,即mutation的载荷(payload):

// ...
mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

2)Mutations需遵守Vue的响应规则

3)使用常量替代Mutation事件类型

4)mutation必须是同步函数

5)在组件中提交Mutations

你可以在组件中使用this.$store.commit('xxx')提交mutation,或者使用mapMutations辅助函数将组件中的methods映射为store.commit调用(需要在根节点注入store)。

actions

actions类似于mutation,不同在于:

  • actions提交的是mutation,而不是直接变更状态。

  • actions可以包含任意异步操作。

1)在组件中分发Action

你在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions辅助函数将组件的methods映射为store.dispatch调用(需要先在根节点注入store)

2)组合Actions

Action通常是异步的,那么如何知道action什么时候结束呢?更重要的是,我们如何才能组合多个action,以处理更加复杂的异步流程?

首先,你需要明白store.dispatch可以处理被触发的action的回调函数返回的Promise,并且store.dispatch仍旧返回Promise。

使用async/await会更加简单:

// 假设 getData() 和 getOtherData() 返回的是 Promise

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

Modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变得相当臃肿。

为了解决以上问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

插件

Vuex的store接受plugins选项,这个选项暴露出每次mutation的钩子。Vuex插件就是一个函数,它接收store作为唯一参数。

严格模式

开启严格模式,仅需在创建store的时候传入strict:true

在严格模式下,无论何时发生了状态变更且不是由mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更--请确保在发布环境下关闭严格模式,以避免性能损失。

表单处理

测试

热重载

위 내용은 Vuejs 기술 스택에 대한 지식 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.