vue的一些基本知识

配置webpack及vue脚手架工具

vue-cli 2
  npm install webpack webpack-cli -g
  npm install vue-cli -g
  搭建脚手架 vue init webpack 项目文件夹名字
  cd 项目文件夹名字
  安装脚手架所需的npm包 npm install
  在本地服务器运行该项目 npm run dev/npm start
  打包上线 npm run build

vue-cli 3.0 ---需要nodejs>=8.9

 npm uninstall vue-cli -g

 npm/cnpm install -g @vue/cli      查看vue是不是>=3.0

 vue create 项目文件夹名字

 cd 项目文件夹名字

 运行本地 npm run serve

 打包上线 npm run build

转译html <span v-html="rawHtml"></span>

v-bind绑定那些后来需要更改的属性:

v-bind:class v-bind:style v-bind:id v-bind:href 缩写 :href

v-bind:class="{ active: isActive, 'text-danger': hasError }"

v-bind:class="[isActive ? activeClass : '', errorClass]"

<div v-bind:class="[{ activeClass: isActive }, errorClass]"></div>

v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"

<div v-bind:style="[styleObject, styleObject2]"></div>

data: { styleObject: { color: 'red', fontSize: '13px' } }

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

 

v-bind单项数据绑定 <input v-bind:value= "picked">

v-model双向数据绑定 <input v-model= "picked">同步更改data里面的picked值(只能运用在表单元素中)  v-model相当于value的效果

利用ref获取dom <input type="text" ref="input1"/>  this.$refs.input1.value 用ref代替获取dom的消耗,可以获取可以赋值

v-on 指令它用于监听 DOM 事件 v-on:click 缩写@click

1.对自身使用

@click.stop阻止冒泡 .prevent阻止默认行为 .once 触发一次

.passive滚动事件的默认行为 (即滚动行为) 将会立即触发, 而不会等待 `onScroll` 完成,尤其能够提升移动端的性能。

<div v-on:scroll.passive="onScroll">...</div>

.enter按键修饰符 .page-down等任意按键<input v-on:keyup.enter="submit">

.ctrl系统修饰键.alt .shift .meta 点击鼠标的前置按键触发<div v-on:click.ctrl="doSomething">Do something</div>

.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。有且只有触发

.lazy 在“change”时而非“input”时更新 <input v-model.lazy="msg">

.trim 自动过滤用户输入的首尾空白字符,<input v-model.trim="msg">

2.对影响到的父元素使用

 .self当点击自身时才触发

.capture捕获(从影响到的节点上的事件从上往下触发),内部元素触发的事件先在此处理,然后才交由内部元素进行处理 

<div v-on:click.capture="doThis">...</div>

点击时绑定的dom元素 e.currentTarget 点击时直接点击的dom元素 e.target

$event作为原始的数据传参 @click="warn('Form cannot be submitted yet.', $event)"

v-if/v-show条件渲染

<h1 v-if="Math.random() > 0.5">Yes</h1> <h1 v-else-if="error">B</h1> <h1 v-else>No</h1>

添加一个具有唯一值的 key 属性来表达“这两个元素是完全独立的,不要复用它们”
<input v-if="" placeholder="Enter your username" key="username-input">
<input v-else placeholder="Enter your email address" key="email-input">
如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

v-for循环 <li v-for="item in items" :key= "index"> {{item.text}} </li> <li v-for="(item,index) in items">{{item.text}}</li>

      下面的元素的使用:显示字符串用 {{item.xxx}}   显示src、class用 :src="item.xxx"  显示value用 v-model="item.xxx"

vue对象的属性  data(){}数据  computed:{}实时计算data的某个属性  watch:{}当data的某个属性变化执行的函数  methods页面的函数

watch:{

  data(newVal, oldVal) {
         console.log(newVal,oldVal)
    }
    
 data: {
        handler(newVal) {
            do something
        },
        deep: true
 }
 data: 'changeData' // 值可以为methods的方法名

immediate和handler
这样使用watch时有一个特点,就是当值第一次绑定时,不会执行监听函数,只有值发生改变时才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。
deep
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,此时就需要deep属性对对象进行深度监听。
每个属性值的变化都会执行handler。如果只需要监听对象中的一个属性值,则可以做以下优化
'data.doc_id': {
        handler(newVal, oldVal) {
             ......
        },
     deep: true
 } 

}

vue生命周期函数

  beforeCreate

  • 在实例初始化之后,数据观测(data observer)和event/watcher事件配置之前调用,里面的this指向实例

  created

  • 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置;数据观测(data observer),属性和方法的运算,watch/event事件回调。然而,挂载阶段还没开始,还未与页面关联起来,$el属性目前不可见。可在这阶段进行一些初始化的操作(如ajax获取数据之类的)

  beforeMount

  • 在挂载之前没调用,解析模板,把实例对象下的$el属性指向设置中的el参数指定的元素,这个解析后的模板还没有和$el进行绑定

  mounted

  • 挂载之后调用,把解析后的模板与页面元素进行绑定,用解析后的模板内容替换页面

  beforeUpdate

  • 在数据绑定之前被调用

  updated

  • 在数据改变之后被调用,可以进行依赖于dom的操作(可以在这个阶段进行dom操作)

  beforeDestroy(销毁前),
  destroyed(销毁后)

钩子

beforeRouteUpdate(to, from, next){} 导航守卫 路由变化时会执行 包括path后的参数

子模板solt的用法 

单个slot内容

 <el-main><slot></slot></el-main>  子模板加入slot就允许在子模板中插入想要的内容

父组件中直接在子模板的中间插入<Header><span>xxxx</span></Header>  内容就显示在slot中了

多个slot内容

 <div> <slot name="h1"></slot> <slot name="hh"></slot> <slot></slot> </div>  子模板 slot上加name

父组件:<Header> <span slot="h1">标题一</span> <span slot="h2">标题二</span> <span>标题三</span> </Header>  

组件之间的传值

父组件触发子组件事件 <child ref="childRef"></child>  this.$refs.childRef.childEvent();

父组件向子组件传值    父组件页面部分引入子组件<Son :val="im value"></Son>
子组件的js部分

数组形式
export default{
data(){},
props:['val']}能直接在页面上用{{val}} 在js中使用this.val

对象形式
props: {
  data1: {
    type: String,
    required: true,
    default: 'default value',
    validator (value) {
      return (value.length < 5)
  }},
  data2: {
    type: Array,
    required: true,
    default: () => ['', '', '']
  }
}

子组件向父组件传值

子组件页面部分<input @change='setVal'></input> 方法部分setVal(){this.$emit('loadVal',this.val)}

父组件页面部分<Son @loadVal="getVal"></Son> 数据部分data(){return name:""} 方法部分getVal(val){this.name=val}

props的双向绑定 

组件的跳转 <router-link to="/myRegister">注册</router-link>
函数内的跳转

router.go 已经被用来作为 后退/前进导航,router.push 用来导向特殊页面。

跳转:this.$router.push({name: '组件的名字', params: {obj: paicheNo}}) 获取参数:this.$route.params.obj

跳转:this.$router.push({path: '/组件的地址', query: {obj: paicheNo}}) 获取参数:this.$route.query.obj

导向一个新页面

let routeData = that.$router.resolve({ path:'/pos/admin/config/receiptsPrint',query: {id: that.pay.retail.id} });
window.open(routeData.href, '_blank');

新页面的样式修改

ar l=(screen.availWidth-800)/2;
var t=(screen.availHeight-800)/2;
window.open('http://www.baidu.com','_blank','width=800,height=800,top='+t+',left='+l+',menubar=no,toolbar=no,location=no,status=no')

VueX

1: State

const store = new Vuex.Store({
  state:{ 
    products: [
      {name: '鼠标', price: 20},
       {name: '键盘', price: 40},
       {name: '耳机', price: 60},
       {name: '显示屏', price: 80}
    ]
  }
})
export default {
    data () {
        return {
            products : this.$store.state.products //获取store中state的数据
     }
    }
}

2: Getters

getters:{ //添加getters
    saleProducts: (state) => {
        let saleProducts = state.products.map( product => {
            return {
                name: product.name,
                price: product.price / 2
            }
        })
        return saleProducts;
     }
  } 
export default {
    data () {
        return {
            products : this.$store.getters.saleProducts 
        }
    }
}

3: Mutations

const store = new Vuex.Store({
  mutations:{ //添加mutations
      minusPrice (state, payload ) {
          let newPrice = state.products.forEach( product => {
            product.price -= payload
          })
      }
  }
})
export default {
    data () {
        return {
            products: this.$store.state.products
        }
    },
    methods: {
        minusPrice() {
            this.$store.commit('minusPrice', 2); //提交`minusPrice,payload为2不接受异步
        }
    }
}

4: Actions

const store = new Vuex.Store({
  actions:{ //添加actions
    minusPriceAsync( context, payload ) {
        setTimeout( () => {
          context.commit( 'minusPrice', payload ); //context提交
       }, 2000)
     }
  }
})
export default {
    data () {
        return {
            products: this.$store.state.products
        }
    },
    methods: {
        minusPriceAsync() {
            this.$store.dispatch('minusPriceAsync', 5); //分发actions中的minusPriceAsync这个异步函数
        }
    }
}

5: Modules

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

keep-alive   

activated 与 deactivated

被keep-alive包含的组件/路由中,会多出两个生命周期的钩子:activated 与 deactivated。
文档:在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 树内的所有嵌套组件中触发。
activated在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用。
activated 调用时机:
第一次进入缓存路由/组件,在mounted后面,beforeRouteEnter守卫传给 next 的回调函数之前调用:

beforeMount=> 如果你是从别的路由/组件进来(组件销毁destroyed/或离开缓存deactivated)=>mounted=> activated 进入缓存组件 => 执行 beforeRouteEnter回调

因为组件被缓存了,再次进入缓存路由/组件时,不会触发这些钩子:// beforeCreate created beforeMount mounted 都不会触发。

deactivated 组件被停用(离开路由)时调用
使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了。
这个钩子可以看作beforeDestroy的替代,如果你缓存了组件,要在组件销毁的的时候做一些事情,你可以放在这个钩子里。
如果你离开了路由,会依次触发:

组件内的离开当前路由钩子beforeRouteLeave => 路由前置守卫 beforeEach =>全局后置钩子afterEach => deactivated 离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由

项目中缓存使用方法:
1、在创建的router对象上加scrollBehavior方法,同上;
2、将需要缓存的组件加在include属性里

<keep-alive :include="['home','classify','search']">
      <router-view></router-view>
</keep-alive>

3、在beforeRouteEnter的next回掉函数里,对返回A页面不需要缓存的的情况初始化,即将本来需要写在created里的东西写在这里;注意一定要将所有的需要初始化的数据要写一遍,不然会有bug;所以不太推荐  

beforeRouteEnter (to, from, next) {
    next(vm => {
      // 通过 `vm` 访问组件实例
      if (from.path !== '/goods_detail') { // 一定是从A进到B页面才刷新
        vm.titleText = vm.$route.query.name
        vm.categoryUpper = vm.$route.query.categoryUpper
        vm.goods = []
        vm.page = 1
        vm.catsIndex = 0
        vm.is_search = false
        vm.getCats2()// 是本来写在created里面的各种
      }
    })
  }
4、将需要缓存的组件保存到全局变量,可以在路由的钩子函数里灵活的控制哪些组件需要缓存,那些不需要缓存;跟第3相比,不需要每次再重新初始化数据,但是需要在vuex中保存数据;
  • 在创建的router对象上加scrollBehavior方法,同上;
  • 将需要缓存的组件加在include属性里
<keep-alive :include="catch_components">
      <router-view></router-view>
</keep-alive>
  • 在store里加入需要缓存的的组件的变量名,和相应的方法;
export default new Vuex.Store({
  state: {
    catch_components: []
  },
mutations:{
    GET_CATCHE_COMPONENTS (state, data) {
      state.catch_components = data
    }
}
})
  • 在beforeRouteLeave钩子函数里控制需要缓存的组件  
beforeRouteLeave (to, from, next) { //要在离开该组件的时候控制需要缓存的组件,否则将出现第一次不缓存的情况
    this.busy = true
    if (to.path === '/goods_detail') { // 去往详情页的时候需要缓存组件,其他情况下不需要缓存
      this.$store.commit('GET_CATCHE_COMPONENTS', ['home'])
    else {
      this.$store.commit('GET_CATCHE_COMPONENTS', [])
    }
    next()
  },

UI框架 移动端 VUX、mint-ui    pc端 element UI

posted @ 2018-11-28 09:39  落落千鸟  阅读(705)  评论(0编辑  收藏  举报