Vux复习一(基础)

计算属性

  computed: {
    getName: {
      // 查询
      get(){
        return this.firstName+this.lastName
      },
      // 就是 this.getName='xxx' 会触发这个方法
      set(newval) {
       this.firstName=newval;
      }
    },
    reversedMessage() {
      // 计算属性是基于他们的响应式依赖进行缓存的
      return this.num1.split('').reverse().join('')
    }
  },
 methods: {
    add() {
      this.getName='3333';
    }
  },

监听属性

  data() {
    return {
      num1: '',
      ans: '正在加载数据',
      fn1: null,
    }
  },
  methods: {
    //这是一个请求
    add() {
      console.log(1);
    }
  },
  watch: {
    num1(newValue, oldValue) {
      this.fn1()
    },
    // 方法名   
    b:'someMethod'
    // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深 
    c: {
      handler: function (val, oldVal) { /* ... */ },
      deep: true
    },   
     // 该回调将会在侦听开始之后被立即调用
    d: {
      handler: 'someMethod',
      immediate: true
    },
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ },
  // 你可以传入回调数组,它们会被逐一调用
    e: [
      'handle1',
      function handle2 (val, oldVal) { /* ... */ },
      {
        handler: function handle3 (val, oldVal) { /* ... */ },
        /* ... */
      }
    ],
  },
  created() {
    this.fn1 = _.debounce(this.add, 1000)
  }
}

不应该使用箭头函数来定义 watcher 函数

理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,

条件渲染分组

v-if v-else

<ng-container>的替换方案是<template>

   <div>
      <button @click="add">Click</button>
      <span v-if="num1">true</span>
      <span v-else>false</span>
    </div>

  data() {
    return {
      num1: true,
    }
  },
  methods: {
    //这是一个请求
    add() {
        this.num1=!this.num1
    }
  },

v-if v-else-if v-else

    <div>
      <button @click="add">Click</button>
	  <template v-if="num1===1">A</template>
      <template v-else-if="num1===2">B</template>
      <template v-else-if="num1===3">C</template>
      <template v-else>最后默认的</template>
    </div>

  add() {
      if (this.num1 === 1) {
        this.num1 = 2
      } else if (this.num1 === 2) {
        this.num1 = 3
      } else if (this.num1 === 3) {
        this.num1 = 4
      } else if (this.num1 === 4) {
        this.num1 = 1
      }
    }

注意,v-show 不支持 <template> 元素,也不支持 v-else

动态路由的变化

watch: {
  '$route.params': function (params) {
        
  }
}

v-for of 代替 in

    <div v-for="(item,index) of arr" :key="index">{{item}}</div>

v-for 在对象中使用

        <li v-for="(val,key) in obj" :key="key">{{val}}--{{key}}</li>
				/* index 是索引*/
        <li v-for="(val,key,index) in obj" :key="index">{{val}}--{{key}}--{{index}}</li>

  obj: {
        name: '333',
        age: 12,
        sex: '男'
      },

双重 v-for

 <ul>
        <li v-for="(item,index) in arr1" :key="index">
          <span v-for="(itemKey,keyIndex) in events(item)" :key="keyIndex">
            {{ itemKey }}
          </span>
        </li>
</ul>

 data() {
    return {
      arr1: [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
      ],
  },
  methods: {
    events(num) {
      return num.filter(val => val % 2 === 0)
    },
  }       

v-for 里使用值范围

v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数

<div v-for="(item,index) in 10" :key="index">{{item}}</div>

v-for template 规范

 <ul>
      <template v-for="(item,index) in [1,2,3,4]" >
        <li :key="index">{{ item }}</li>
      </template>
 </ul>

事件处理

        <button @click="greet">++</button>
					// 也可以这样 greet('xxx')  传递参数
					// 如果默认传递参数 就是 $event
		// 默认第一个参数,拿到event事件
		greet(event){
                console.log(event.target);
            }

表单

单个值得true , false

<input type="checkbox" v-model="toggle">
   自定义选择的值
			<input
                    type="checkbox"
                    v-model="toggle"
                    true-value="yes"   
                    false-value="no"
            >
	true =>

.lazy

失去焦点触发

<input v-model.lazy="msg">

.number 数字

.trim 首尾空白

子传父

父
        <One title="333" @add="clickAdd"/>
            
        clickAdd(e){
              console.log(e);
          }
子 触发父
						// 第一个参数是事件,第二个参数是传递的参数
                this.$emit('add',{age:12})

v-model

<input v-model="searchText">
等价
<input
                :value="searchText"
                @input="searchText = $event.target.value">

动态组件

        <component :is="num"></component>

	 data(){
            return{
                num:Three,
            }
        },
        components:{
          Two,
          Three
        },

第一次创建缓存起来

<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

<!-- 基本 -->
<keep-alive>
  <component :is="view"></component>
</keep-alive>

<!-- 多个条件判断的子组件 -->
<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>

组件名

my-component-name
MyComponentName

  components: {
    'component-a': ComponentA,
    'component-b': ComponentB,
     ComponentC   
  }

props

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
// 验证
props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // 或任何其他构造函数
}

  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
 }
      
function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}
      
  props: {
    author: Person
  }

传入一个数字

        <One  :date="2"/>
		因为是静态的,传入的是一个数字

继承关系inheritAttrs: false

inheritAttrs: false;
如果你不希望组件的根元素继承特性,你可以在组件的选项中设置

允许组件绑定的未注册属性渲染到组件根节点上的

渲染显示的问题

注意 inheritAttrs: false 选项不会影响 styleclass 的绑定。

页面上
<div class="form-control"></div>
设置 inheritAttrs: false
页面上
<div  title="333" name="age" class="form-control"></div>

v-model 封装表单

父
        <Three v-model="bool" @change="clickMethod"></Three>
  
 		data(){
            return{
                bool:true,
            }
        },
        methods:{
            clickMethod(e) {
                console.log(e);
            }
        },

子
            <input type="checkbox" :checked="checked" @change="$emit('change',$event.target.checked)">

  model:{
          prop:'checked',
          event:'change'
        },
        props:{
            checked:Boolean
        }                

原生事件绑定在组件上

<base-input v-on:focus.native="onFocus"></base-input>

$listeners 不用事件委托执行父亲的方法

父
        <One  @add="clickMethod1"/>
    
       clickMethod1(){
                console.log(1);
            }
子执行父亲的方法

            this.$listeners.add()

 v-on="$listeners"  就是类似于 父=>孙

.async 简便父传子的方法

就是子可以直接改父的这个值

:title 只是一个触发的自定义变量
父
<Two age="sex" :title.sync="bool" ></Two>
子改父
 this.$emit('update:title','3333')

传入多个
父
        <Two age="sex"  v-bind.sync="obj"></Two>

 			obj:{
                    name1:'333',
                    name2:'444',
                },
子
                this.$emit('update:name1','5555')

插槽

1 正常的使用

父
 		<Two >
            <h1>angular</h1>
        </Two>
子
        <slot></slot>

2 默认插槽

默认父的插入数据,就展示默认的
<slot>默认插槽</slot>

3 命名插槽

父
 		<Two>
            <h1>angular</h1>
            <template v-slot:a>
                <h1>111</h1>
            </template>
            <template v-slot:b>
                <h1>222</h1>
            </template>
            <template v-slot:c>
                <h1>bbb</h1>
            </template>
        </Two>
子
        <slot name="a"></slot>
        <slot name="c"></slot>
        <slot name="b"></slot>
        <slot></slot>

父也可以这样写

    	<Two>
            <h1>angular</h1>
            <template #a>
                <h1>111</h1>
            </template>
            <template #b>
                <h1>222</h1>
            </template>
            <template #c>
                <h1>bbb</h1>
                <span>{{obj.name1}}</span>
            </template>
        </Two>

异步组件

 components: {
    'my-component': () => import('./my-async-component')
  }

处理状态

const AsyncComponent = (AsyncView) => ({
  // 需要加载的组件 (应该是一个 `Promise` 对象)
  component: AsyncView,
  // 异步组件加载时使用的组件
  loading: LoadingComponent,
  // 加载失败时使用的组件
  error: ErrorComponent,
  // 展示加载时组件的延时时间。默认值是 200 (毫秒)
  delay: 200,
  // 如果提供了超时时间且组件加载也超时了,
  // 则使用加载失败时使用的组件。默认值是:`Infinity`
  timeout: 3000
})

 components: {
    'my-component': () => AsyncComponent(import('@/my-async-component'))
  }

依赖注入 provide/inject

provide 选项允许我们指定我们想要提供给后代组件的数据/方法
		父=>子孙后代
provide(){
    return{
        name:'1',
        change:val=>val+1
    }
}
子或者后代
export default {
  inject: ['name','change'],
  mounted () {
    console.log(this.name);  // Aresn
    console.log(this.change(10))
  }
}

监听

通过 $on(eventName, eventHandler) 侦听一个事件
通过 $once(eventName, eventHandler) 一次性侦听一个事件
通过 $off(eventName, eventHandler) 停止侦听一个事件


清空插件的时间管理器

mounted: function () {
    // 每个新的实例都程序化地在后期清理它自己
  this.attachDatepicker('startDateInput')
  this.attachDatepicker('endDateInput')
},
methods: {
  attachDatepicker: function (refName) {
    var picker = new Pikaday({
      field: this.$refs[refName],
      format: 'YYYY-MM-DD'
    })
	// 组件销毁前 清空
    this.$once('hook:beforeDestroy', function () {
      picker.destroy()
    })
  }
}

递归组件

使用    <app-circle count="10"></app-circle>
递归组件

<template>
    <div>
        1
//			这里写相对于写了循环条件
        <app-circle v-if="count>1" :count="count-1"></app-circle>
    </div>
</template>

<script>
    export default {
        name: "app-circle",
        props:['count'],
        methods: {

        }
    }
</script>

组件之间的循环引用

    <div v-for="(item,index) in dataArr"  :key="index">
      <Two v-if="item.children"/>
      <span v-else>暂无</span>
    </div>

 dataArr: [
        {children: true},
        {children: false},
        {children: true},
        {children: true},
      ]

强制刷新

this.$forceUpdate()
迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

过渡

https://cn.vuejs.org/v2/guide/transitions.html

混入

合并 , mixins 的优先级高于正常的

let min={
        data(){
            return {
                num:123
            }
        }
    };

 export default {
        mixins:[min],
        data() {
            return {
                num:234,
                sex:'xxx'
            }
        },
        created() {
            console.log(this.$data);
            // {num: 234, sex: "xxx"}
        }
    }

$data 的数据, mixins 优先级高于本身的

生命周期的话, 混入对象先被调用

 let min={
        methods:{
            add(){
                console.log('add');
            }
        }
    };
    export default {
        mixins:[min],
        methods:{
            add(){
                console.log('add1');
            }
        },
        created() {
            this.add()
            // add1
        }
    }

methodscomponentsdirectives,将被合并为同一个对象。两个对象键名冲突时,取自身的对象。

Vue.extend()也是同样的策略合并

指令

directives

参数

  • el:指令所绑定的元素,可以用来直接操作 DOM。

  • binding
    

    :一个对象,包含以下 property:

    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

  data() {
            return {
                num:234,
            }
        },
   directives:{
       // 不关系钩子就这样写
            colors(el,attr) {
                console.log(attr.value);
                // 333
                
                // el 拿到dom
                el.style.color='red'
               console.log(el.getAttribute('num'));
				// 234
            }
        }

        <div  v-colors="333">12211212</div>

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

钩子函数

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

VNodes 的细节

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 elbindingvnodeoldVnode)。

   directives:{
       // 不关系钩子就这样写
            colors:{
                bind(el){
                    
                }
            }
        }

api

$root  根组件
$parent  父组件, 你怎么知道哪个是父组件,如果多个呢? 慎用
$refs   访问子组件或者子元素
	  组件  <base-input ref="usernameInput"></base-input>
		this.$refs.usernameInput

生命周期

// 初始化前 data都没加载上去 
beforeCreate

// 初始化  data props 方法 watch 都挂在了
created

// 挂在前: 相关的render 函数首次被调用
beforeMount

// dom操作   $el 挂载到页面上
	// 注意mounted 不会保证所有子组件挂载上
mounted

         mounted: function () {
          this.$nextTick(function () {
            // Code that will run only after the
            // entire view has been rendered
          })
        }

// 数据更新时前
	// 手动移除已添加的事件监听器。
// 该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行
beforeUpdate

// 数据更新时调用
	// 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watch取而代之。
updated
	// 注意 updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕
    updated: function () {
      this.$nextTick(function () {
        // Code that will run only after the
        // entire view has been re-rendered
      })
    }

// 被 keep-alive 缓存的组件激活时调用。
activated

// 被 keep-alive 缓存的组件停用时调用。
deactivated
	
// 实例销毁之前调用
beforeDestroy

// 实例销毁后调用
destroyed

// 在捕获错误时
errorCaptured

eslint

https://eslint.vuejs.org/

Vue/cli

https://cli.vuejs.org/config/

posted @ 2021-02-11 20:08  猫神甜辣酱  阅读(286)  评论(0编辑  收藏  举报