首页 web前端 js教程 vue项目中watch的immediate使用

vue项目中watch的immediate使用

Jun 09, 2018 am 11:38 AM
vue 技术分享

这次给大家带来vue项目中watch的immediate使用,vue项目中watch的immediate使用注意事项有哪些,下面就是实战案例,一起来看一下。

这一点我在项目中也是这么写的。例如有请求需要再也没初始化的时候就执行一次,然后监听他的变化,很多人这么写:

created(){
  this.fetchPostList()
},
watch: {
  searchInputValue(){
    this.fetchPostList()
  }
}
登录后复制

上面的这种写法我们可以完全如下写:

watch: {
  searchInputValue:{
    handler: 'fetchPostList',
    immediate: true
  }
}
登录后复制

二、组件注册,值得借鉴

一般情况下,我们组件如下写:

import BaseButton from './baseButton'
import BaseIcon from './baseIcon'
import BaseInput from './baseInput'
export default {
 components: {
  BaseButton,
  BaseIcon,
  BaseInput
 }
}
<BaseInput v-model="searchText" @keydown.enter="search" />
<BaseButton @click="search"> <BaseIcon name="search"/></BaseButton>
登录后复制

步骤一般有三部,

第一步,引入、

第二步注册、

第三步才是正式的使用,

这也是最常见和通用的写法。但是这种写法经典归经典,好多组件,要引入多次,注册多次,感觉很烦。

我们可以借助一下webpack,使用 require.context() 方法来创建自己的(模块)上下文,从而实现自动动态require组件。

思路是:在src文件夹下面main.js中,借助webpack动态将需要的基础组件统统打包进来。

代码如下:

import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
// Require in a base component context
const requireComponent = require.context(
 ‘./components', false, /base-[\w-]+\.vue$/
)
requireComponent.keys().forEach(fileName => {
 // Get component config
 const componentConfig = requireComponent(fileName)
 // Get PascalCase name of component
 const componentName = upperFirst(
  camelCase(fileName.replace(/^\.\//, '').replace(/\.\w+$/, ''))
 )
 // Register component globally
 Vue.component(componentName, componentConfig.default || componentConfig)
})
登录后复制

这样我们引入组件只需要第三步就可以了:

<BaseInput
 v-model="searchText"
 @keydown.enter="search"
/>
<BaseButton @click="search">
 <BaseIcon name="search"/>
</BaseButton>
登录后复制

三、精简vuex的modules引入

对于vuex,我们输出store如下写:

import auth from './modules/auth'
import posts from './modules/posts'
import comments from './modules/comments'
// ...
export default new Vuex.Store({
 modules: {
  auth,
  posts,
  comments,
  // ...
 }
})
登录后复制

要引入好多modules,然后再注册到Vuex.Store中~~

精简的做法和上面类似,也是运用 require.context()读取文件,代码如下:

import camelCase from 'lodash/camelCase'
const requireModule = require.context('.', false, /\.js$/)
const modules = {}
requireModule.keys().forEach(fileName => {
 // Don't register this file as a Vuex module
 if (fileName === './index.js') return
 const moduleName = camelCase(
  fileName.replace(/(\.\/|\.js)/g, '')
 )
 modules[moduleName] = {
        namespaced: true,
        ...requireModule(fileName),
       }
})
export default modules
登录后复制

这样我们只需如下代码就可以了:

import modules from './modules'
export default new Vuex.Store({
 modules
})
登录后复制

四、路由的延迟加载

这一点,关于vue的引入,我之前在 vue项目重构技术要点和总结 中也提及过,可以通过require方式或者import()方式动态加载组件。

{
 path: '/admin',
 name: 'admin-dashboard',
 component:require('@views/admin').default
}
登录后复制

或者

{
 path: '/admin',
 name: 'admin-dashboard',
 component:() => import('@views/admin')
}
登录后复制

加载路由。

五、router key组件刷新

下面这个场景真的是伤透了很多程序员的心...先默认大家用的是Vue-router来实现路由的控制。 假设我们在写一个博客网站,需求是从/post-haorooms/a,跳转到/post-haorooms/b。然后我们惊人的发现,页面跳转后数据竟然没更新?!原因是vue-router"智能地"发现这是同一个组件,然后它就决定要复用这个组件,所以你在created函数里写的方法压根就没执行。通常的解决方案是监听$route的变化来初始化数据,如下:

data() {
 return {
  loading: false,
  error: null,
  post: null
 }
}, 
watch: {
 '$route': {
  handler: 'resetData',
  immediate: true
 }
},
methods: {
 resetData() {
  this.loading = false
  this.error = null
  this.post = null
  this.getPost(this.$route.params.id)
 },
 getPost(id){
 }
}
登录后复制

bug是解决了,可每次这么写也太不优雅了吧?秉持着能偷懒则偷懒的原则,我们希望代码这样写:

data() {
 return {
  loading: false,
  error: null,
  post: null
 }
},
created () {
 this.getPost(this.$route.params.id)
},
methods () {
 getPost(postId) {
  // ...
 }
}
登录后复制

解决方案:给router-view添加一个唯一的key,这样即使是公用组件,只要url变化了,就一定会重新创建这个组件。

<router-view :key="$route.fullpath"></router-view>
登录后复制

注:我个人的经验,这个一般应用在子路由里面,这样才可以不避免大量重绘,假设app.vue根目录添加这个属性,那么每次点击改变地址都会重绘,还是得不偿失的!

六、唯一组件根元素

场景如下:

(Emitted value instead of an instance of Error)
  Error compiling template:

 


 

  - Component template should contain exactly one root element.
    If you are using v-if on multiple elements, use v-else-if
    to chain them instead.

模板中p只能有一个,不能如上面那么平行2个p。

例如如下代码:

<template>
 <li
  v-for="route in routes"
  :key="route.name"
 >
  <router-link :to="route">
   {{ route.title }}
  </router-link>
 </li>
</template>
登录后复制

会报错!

我们可以用render函数来渲染

functional: true,
render(h, { props }) {
 return props.routes.map(route =>
  <li key={route.name}>
   <router-link to={route}>
    {route.title}
   </router-link>
  </li>
 )
}
登录后复制

七、组件包装、事件属性穿透问题

当我们写组件的时候,通常我们都需要从父组件传递一系列的props到子组件,同时父组件监听子组件emit过来的一系列事件。举例子:

//父组件
<BaseInput 
  :value="value"
  label="密码" 
  placeholder="请填写密码"
  @input="handleInput"
  @focus="handleFocus>
</BaseInput>
//子组件
<template>
 <label>
  {{ label }}
  <input
   :value="value"
   :placeholder="placeholder"
   @focus=$emit(&#39;focus&#39;, $event)"
   @input="$emit(&#39;input&#39;, $event.target.value)"
  >
 </label>
</template>
登录后复制

这样写很不精简,很多属性和事件都是手动定义的,我们可以如下写:

<input
  :value="value"
  v-bind="$attrs"
  v-on="listeners"
>
computed: {
 listeners() {
  return {
   ...this.$listeners,
   input: event => 
    this.$emit('input', event.target.value)
  }
 }
}
登录后复制

$attrs包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定,并且可以通过 v-bind="$attrs" 传入内部组件。

$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

脚手架与热刷新、热加载

Vue怎样进行局部作用域 & 模块化

以上是vue项目中watch的immediate使用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

vue中怎么用bootstrap vue中怎么用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分为五个步骤:安装 Bootstrap。在 main.js 中导入 Bootstrap。直接在模板中使用 Bootstrap 组件。可选:自定义样式。可选:使用插件。

vue怎么给按钮添加函数 vue怎么给按钮添加函数 Apr 08, 2025 am 08:51 AM

可以通过以下步骤为 Vue 按钮添加函数:将 HTML 模板中的按钮绑定到一个方法。在 Vue 实例中定义该方法并编写函数逻辑。

vue中的watch怎么用 vue中的watch怎么用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 选项允许开发者监听特定数据的变化。当数据发生变化时,watch 会触发一个回调函数,用于执行更新视图或其他任务。其配置选项包括 immediate,用于指定是否立即执行回调,以及 deep,用于指定是否递归监听对象或数组的更改。

vue多页面开发是啥意思 vue多页面开发是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多页面开发是一种使用 Vue.js 框架构建应用程序的方法,其中应用程序被划分为独立的页面:代码维护性:将应用程序拆分为多个页面可以使代码更易于管理和维护。模块化:每个页面都可以作为独立的模块,便于重用和替换。路由简单:页面之间的导航可以通过简单的路由配置来管理。SEO 优化:每个页面都有自己的 URL,这有助于搜索引擎优化。

vue.js怎么引用js文件 vue.js怎么引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三种:直接使用 &lt;script&gt; 标签指定路径;利用 mounted() 生命周期钩子动态导入;通过 Vuex 状态管理库进行导入。

vue返回上一页的方法 vue返回上一页的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一页有四种方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 组件window.history.back(),方法选择取决于场景。

vue遍历怎么用 vue遍历怎么用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍历数组和对象有三种常见方法:v-for 指令用于遍历每个元素并渲染模板;v-bind 指令可与 v-for 一起使用,为每个元素动态设置属性值;.map 方法可将数组元素转换为新数组。

vue的div怎么跳转 vue的div怎么跳转 Apr 08, 2025 am 09:18 AM

Vue 中 div 元素跳转的方法有两种:使用 Vue Router,添加 router-link 组件。添加 @click 事件监听器,调用 this.$router.push() 方法跳转。

See all articles