栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

Vue简单知识点(上)

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vue简单知识点(上)

vue-loader
const docsLoader = require.resolve('./doc-loader')
module.exports = (isDev) => {
  return {
    preserveWhitepace: true, // 去除html中多余的空格
    extractCSS: !isDev, // 讲css单独打包到一个文件
    cssModules: {
      localIdentName: isDev ? '[path]-[name]-[hash:base64:5]' : '[hash:base64:5]', // 避免class命名冲突,而且可以定义class名称
      camelCase: true // 横杠式命名转化成小驼峰命名,帮助JS更容易解析
    },
    // hotReload: false, // 根据环境变量生成,热重载 (样式热重载是通过vue-style-loader来实现的,而不是vue-loader给component进行热重载的功能。但是html更新就是通过刷新更新)
    loaders: { // 给自定义的模块指定loader,更多用在给组件库指定文档的时候使用
	    'docs' : docsLoader,
	    'js': 'cooffe-loader' // 也可以给js,html,css指定不同的loader 
    },
    preLoader: { // 解析loader之前的解析,也就是先解析},
    postLoader: {// 之后解析}
  }
}
css属性添加module,然后调用的使用使用:class="$style.cssName" 其实这种使用方式相当于,

"precommit": "npm run lint-fix",

为了缩短 Lint 的反馈链条,把 Lint 挪到本地是最有效的办法。常见做法是使用 husky 或者 pre-commit 在本地提交之前做 Lint。不过要保证项目已经git init ,否则git hook无法生效

Vue Instance
  • $data
  • $props
  • $el
  • $options 当我创建vue对象所有的options,还有默认的options,但是不是同一个对象,也就是无法修改$options上的值,但是我们可以这样调用$options.render
  • root(app.root (app.root(app.root === app) 通过这种方式挂载
  • $chiildren
  • $slots 插槽
  • $scopedSlots 插槽
  • $refs 模板的引用,快速定位模板中的某一个节点或者是组件,如果是html,他会返html中的对象,如果是组件,返回实例
  • $isServer 判断服务端渲染
  • $watch
  • $once (多次调用$once)
  • $forceUpdate 强制组件重新渲染,小心使用,容易影响性能
  • $set 赋值 app.$set(app.obj, 'a', i)
  • $delete 删除元素
  • $nextTick 将回调延迟到下次DOM更新循环之后执行。调用callback
    • 更新值,但是DOM节点没有变化的时候调试
不过只有在下一次渲染的时候才会生效
app.$options.render = (h) => {
	return h('div',{},'new render function')
	}
const unWatch = app.$watch('text', (newText, oldText) => {
  console.log(`${newText} : ${oldText}`)
})
unWatch() 注销,防止内存溢出
不冒泡,必须绑定到同一个对象上
app.$once('test', (a, b) => {
  console.log(`test emited ${1} ${b}`)
})
app.$emit('test', 1, 2)

Vue lifecycle
  • beforeCreate和create肯定会执行(如果没有绑定节点或者是mounted,绑定节点 ),拿不到$this.$el
    • beforeCreate,事件OK,但是reactivity还没有ok
  • update beforeUpdate需要等到数据更新时执行
  • beforeDestory destroyed解除所有的事件监听和watch
  • renderError() 开发时更方便的进行调错
  • errorCapured 帮助我们收集线上的错误,可以冒泡
render (h) {
    throw new TypeError('render error')
  },
  renderError (h, err) {
    return h('div', {}, err.stack)
  },

data-binding
new Vue({
  el: '#root',
  // template: `
  //   
  //     

// // `, template: `

{{getJoinedArr(arr)}}

`, data: { isActive: false, arr: [1, 2, 3], html: '123', aaa: 'main', styles: { color: 'red', appearance: 'none' // 自动加兼容前缀 }, styles2: { color: 'black' } }, methods: { handleClick () { alert('clicked') // eslint-disable-line }, getJoinedArr (arr) { return arr.join(' ') } } })

computed and watch
  • computed相比方法的性能开销比较小
    • 有缓存
    • 只有依赖的值变化,他才会重新计算并且缓存起来
    • 不到万不得已,不要使用set方法
  • 改变变量时,整个DOM要重新渲染,如果我们使用了方法,该方法就会被重新调用,但是computed不会
  • watch 最初绑定的时候不会执行,当然可以使用handler+immediate:true解决
    • 适合监听数据变化,然后执行指定操作,但是不适用于显示某个数据,这个时候,computed就比较合适了
    • 当我们修改内部属性时,无法触发handler,但是我们加deep参数,深入观察,当然,这样性能开销就很大了
  • 不要在computed和watch 中修改你依赖的值,无限循环
import Vue from 'vue'

new Vue({
  el: '#root',
  template: `
    
      

Name: {{name}}

Name: {{getName()}}

Number: {{number}}

FullName: {{fullName}}

FirstName:

LastName:

Name:

Obj.a:

`, data: { firstName: 'Jokcy', lastName: 'Lou', number: 0, fullName: '', obj: { a: 0 } }, computed: { name: { get () { console.log('new name') return `${this.firstName} ${this.lastName}` }, set (name) { const names = name.split(' ') this.firstName = names[0] this.lastName = names[1] } } }, watch: { 'obj.a': { handler () { console.log('obj.a changed') this.obj.a += 1 }, immediate: true // deep: true } }, methods: { getName () { console.log('getName invoked') return `${this.firstName} ${this.lastName}` } } })

directive
new Vue({
  el: '#root',
  template: `
    
      Text: {{text}}
      Else Text: {{text}}
      else content
      
      
      
      
 
 
 
      
      
 
 
      
      
  • {{item}}:{{index}}
  • {{val}}:{{key}}:{{index}}
`, data: { arr: [2, 3], obj: { a: '123', b: '456', c: '789' }, picked: '', text: 0, active: false, html: 'this is html' } })
  • v-on
  • v-bind
  • v-model 一般用在input等交互标签
    • 可以在后面加上number,trim,lazy等修饰符
    • v-pre不解析
    • v-cloak 防止页面加载时出现 vuejs 的变量名
    • v-once 数据只绑定一次,节省性能(不更新数据)
    • v-props 作为一个子节点不应该主动去修改主节点的值
  • 数据经常变化,如果每次变化,view会重新渲染列表,再把它放进Dom中去,性能开销就会比较大
  • :key减少性能开销,变化,如果在缓存列表中拿到同样的key,就把这行的dom节点复用了,就不用生成新的dom节点
  • 一般不推荐使用index,一般用item,唯一值

vue原生指令
  • v-show
  • v-html
  • v-text
  • v-if 如果只是单纯的控制隐藏显示,推荐使用v-show.因为v-if是会动态增删节点,性能差很多(Dom重绘和重新排版)
  • v-for="(item,index) in arr"
  • v-for="(val,key) in obj"
  • :key 数据中唯一ID值 因为数据经常变化,性能开销大 ,但是如果定义key之后,如果key没有变化,直接复用Dom节点,不建议用index做
  • @click
  • v-model.number .lazy(在 “change” 而不是 “input” 事件中更新)
  • v-pre
  • v-cloak
  • v-once 数据绑定内容只执行一次

component
const compoent = {
  props: {
    active: {
      // type: Boolean,
      // required: true,
      validator (value) {
 return typeof value === 'boolean'
      }
    },
    propOne: String
  },
  template: `
    
      
      {{propOne}}
      see me if active
    
  `,
  data () { // data必须是通过function定义,不能是全局的
    return {
      text: 0
    }
  },
  methods: {
    handleChange () {
      this.$emit('change')
    }
  }
}

// Vue.component('CompOne', compoent) 全局注册组件

new Vue({
  components: {
    CompOne: compoent
  },
  data: {
    prop1: 'text1'
  },
  methods: {
    handleChange () {
      this.prop1 += 1
    }
  },
  mounted () {
    console.log(this.$refs.comp1) 拿到vue的实例
  },
  el: '#root',
  template: `
    
      
      
    
  `
})

Component extend
const compoent = {
  props: {
    active: Boolean,
    propOne: String
  },
  template: `
    
      
      {{propOne}}
      see me if active
    
  `,
  data () {
    return {
      text: 0
    }
  },
  mounted () {
    console.log('comp mounted')
  },
  methods: {
    handleChange () {
      this.$emit('change')
    }
  }
}

const parent = new Vue({
  name: 'parent'
})

const componet2 = {
  extends: compoent,
  data () {
    return {
      text: 1
    }
  },
  mounted () {
    console.log(this.$parent.$options.name)
  }
}

// const CompVue = Vue.extend(compoent)

// new CompVue({
//   el: '#root',
//   propsdata: { 
//     propOne: 'xxx'
//   },
//   data: { 合并或覆盖
//     text: '123'
//   },
//   mounted () { components mounted先被调用,然后该mounted被调用
//     console.log('instance mounted')
//   }
// })
// 第二种方式 ,可以在子组件内部通过$partent直接调用父组件(子组件必须是通过new出来的,而不是模板编译)
new Vue({
  parent: parent,
  name: 'Root',
  el: '#root',
  mounted () {
    console.log(this.$parent.$options.name)
  },
  components: {
    Comp: componet2
  },
  data: {
    text: 23333
  },
  template: `
    
      {{text}}
      
    
  `
})

Component 自定义双向绑定
import Vue from 'vue'

const component = {
  model: {
    prop: 'value1',
    event: 'change'
  },
  props: ['value1'],
  template: `
    
      
    
  `,
  methods: {
    handleInput (e) {
      this.$emit('change', e.target.value)
    }
  }
}

new Vue({
  components: {
    CompOne: component
  },
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  template: `
    
      
    
  `
})
这里的也可以这样写

组件高级属性
import Vue from 'vue'

const ChildComponent = {
  template: 'child component: {{data.value}}',
  inject: ['yeye', 'data'],
  mounted () {
    // console.log(this.yeye, this.value)
  }
}

const component = {
  name: 'comp',
  components: {
    ChildComponent
  },
  // template: `
  //   
  //     
  //
  //     
  //     
  //
  //     
  //   
  // `,
  template: `
    
      
      
    
  `,
  data () {
    return {
      style: {
 width: '200px',
 height: '200px',
 border: '1px solid #aaa'
      },
      value: 'component value'
    }
  }
}

new Vue({
  components: {
    CompOne: component
  },
  provide () { // 解决跨层级关系,提供上下文的关系
    const data = {}
	// provide默认不提供Reactive (Hack方法)
    Object.defineProperty(data, 'value', {
      get: () => this.value,
      enumerable: true
    })

    return {
      yeye: this,
      data
    }
  },
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp.value, this.$refs.span)
  },
  template: `
    
      
 {{props.value}} {{props.aaa}} {{value}}
      
      
    
  `
})

Vue render
import Vue from 'vue'

const component = {
  props: ['props1'],
  name: 'comp',
  // template: `
  //   
  //     
  //   
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
      // on: {
      //   click: () => { this.$emit('click') }
      // }
    }, [
      this.$slots.header,
      this.props1
    ])
  },
  data () {
    return {
      style: {
 width: '200px',
 height: '200px',
 border: '1px solid #aaa'
      },
      value: 'component value'
    }
  }
}

new Vue({
  components: {
    CompOne: component
  },
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp.value, this.$refs.span)
  },
  methods: {
    handleClick () {
      console.log('clicked')
    }
  },
  // template: `
  //   
  //     {{value}}
  //   
  // `,
  render (createElement) {
    return createElement(
      'comp-one',
      {
 ref: 'comp',
 props: {
   props1: this.value
 },
 // on: {
 //   click: this.handleClick
 // },
 nativeOn: {
   click: this.handleClick
 }
      },
      [
 createElement('span', {
   ref: 'span',
   slot: 'header',
   // domProps: {
   //   innerHTML: '345'
   // }
   attrs: {
     id: 'test-id'
   }
 }, this.value)
      ]
    )
  }
})

Vue Router

服务端渲染

报错解决

解决 https://github.com/vuejs/vue-loader/issues/470
npm install vue-template-compiler --save-dev

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/241010.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号