Vue基础知识学习笔记

使用Vue

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src= "https://unpkg.com/vue@next"></script>

mvvm设计模式

1.createApp表示创建一个Vue应用,存储到App变量中
2.传入的参数表示,这个应用最外层的组件,应该如何展示
3.mvvm 设计模式,m->model 数据,v->view 视图,vm->viewModel 视图数据连接层

    const app = Vue.createApp({
       data(){
           return{
               message:"hello world"
           } 
       },
       template:"<div>{{message}}</div>"
            
    });
    //vm代表的就是Vue应用的根组件
    const vm = app.mount('#root');

生命周期函数

vue生命周期函数:在某一时刻会自动执行的函数

      //实例生成之前会自动执行的函数
       beforeCreate() {
           console.log("beforeCreated");
       },
       //在实例生成之后会自动生成的函数
       created() {
        console.log("Created");
       },
       //在组件内容自动渲染到页面之前自动执行的函数
       beforeMount() {
        console.log( document.getElementById('root').innerHTML,"beforeMount");
       },
       //在组件内容被渲染到页面之后自动执行的函数
       mounted() {
        console.log(document.getElementById('root').innerHTML,"mounted");
       },
       //当数据发生变化时会立即自动执行的函数
       beforeUpdate() {
        console.log(document.getElementById('root').innerHTML,"beforeUpdate");   
       },
       //当数据发生变化,页面重新渲染后,会自动执行的函数
       updated() {
        console.log(document.getElementById('root').innerHTML,"Updated");
       },
      //组件即将销毁时触发的函数
       beforeUnmount() {
           console.log(document.getElementById('root').innerHTML,'beforeUnmount');
       },
      //组件销毁完毕触发的函数
       unmounted() {
        console.log(document.getElementById('root').innerHTML,'unmount');
       },
       //组件销毁时触发的函数
        beforeDestroy() {
           
       },
      //组件触发时,Vue示例解除了事件监听以及dom的绑定(无响应了),但dom节点依旧存在
        destroyed() {
           
       },

模板语法

      data(){
           return{
               message:"hello world",
               count: 2 ,
               price: 5 ,
           } 
       },
       watch:{
            price(){
                setTimeout(()=>{
                    console.log('price changed')
                },3000)
            }
       },
       computed:{
            total(){
                return Data.now();
                // return this.count*this.price;
            }
       },
       methods: {
           getTotal(){
            return Data.now();
               // return this.count*this.price;
           },
       },
       template:`
       <div>{{message}}---{{getTotal}}</div>
       `

样式绑定

   <style>
        .red{
            color: red;
        }
        .green{
            color: green;
        }
    </style>

 <script>
    const app = Vue.createApp({
       data(){
           return{
               classString:'red',
               classObject:{red:false,green:true},
               classArray:['red','green',{brown:false}],
               styleString:'color:yellow;',
               styleObject:{
                   color:'orange',
                   background:'yellow'
               }
           } 
       },
      
       template:`
       <div :style="styleObject">
        hello world
        <demo class="green" />
        </div>
       `
            
    });
    app.component('demo',{
        template: `
        <div :class="$attrs.class">single</div>
        <div>gaga</div>
        `
    })
    const vm = app.mount('#root');
</script>

条件渲染v-if,v-show

const app = Vue.createApp({
       data(){
           return{
              show:false,
              conditionOne:false,
              conditionTwo:true,
           } 
       },
      
       template:`
       <div v-if="show">hello world</div>
       <div v-if="conditionOne">if</div>
       <div v-else-if="conditionTwo">else-if</div>
       <div v-else>else</div>

       <div v-show="show">Bye world</div>
       `
            
    });
    const vm = app.mount('#root');

列表渲染

const app = Vue.createApp({
       data(){
           return{
              listArray:['dell','lee','teacher'],
              listObject:{
                  firstName:'dell',
                  lastName:'lee',
                  job:'teacher'
              }
           } 
       },
       methods: {
           handleAddBtnClick(){
            //1.数组的变更函数 push,pop,unshift,shift,reverse,splice,sort
            //    this.listArray.push('hello ya'); //在最后添加
            // this.listArray.pop();// 在最后删除 
            // this.listArray.shift();//从头开始删除
            // this.listArray.unshift('heiheihei');//从头开始添加
            // this.listArray,reverse();//重组
            // this.listArray.sort();

            //2.最直接替换数组
            // this.listArray=['bye','mo','fit'];
            //  this.listArray=['bye'].concat(['world']);

            //3.直接更新数组内容
            this.listArray[1]='hello';

            //4.直接添加对象内容,也可以自动的展示出来
            this.listObject.age=100;
            this.listObject.sex='male';
           }
       },
      
       template:`
       <div>
            <template 
            v-for="(value,key,index) in listObject"
            :key="index"
            >
            <div v-if="key!=='lastName'">
                {{value}}---{{key}}
            </div>
                
            </template>
            <div v-for="item in 10">{{item}}</div>
            <div>
                <div v-for="(value,key,index) in listObject" :key="index">
                    {{value}}---{{key}}
                    </div>
                </div>
                <button @click="handleAddBtnClick">新增</button>
        </div>
       
       `
            
    });
    const vm = app.mount('#root');

事件绑定@,v-bind,:

       methods: {
           handleBtnClick(num,event){
               console.log(event);
            this.counter+=num;
           }
       },
      
       template:`
       <div>
            {{counter}}
             <button @click="handleBtnClick(2,$event)">button</button>
        </div>
       `          
    });

表单双向绑定v-model

const app = Vue.createApp({
      data(){
       return{
           message:[],
           options:[
               {text:'A',value:{value:'A'}},
               {text:'B',value:{value:'B'}},
               {text:'C',value:{value:'C'}},
            ]
       }
      },
       methods: {
           handleBtnClick(num,event){
               console.log(event);
            this.counter+=num;
           }
       },
      
       template:`
       <div>
            {{message}}
            jack <input type="checkbox" v-model="message" value="jack" />
            dell <input type="checkbox" v-model="message" value="dell" />
            lee <input type="checkbox" v-model="message" value="lee" />
        </div>
        <div>
            {{message}}
            <select v-model="message" multiple>
              <option v-for="item in options" :value="item.value">{{item.text}}</option>
            </select>    
        </div>
       `
    });

组件

1.局部组件

const counter = {
        data(){

        },
        template:``
    }

const app = Vue.createApp({
        components:{counter:counter},
    });

2.全局组件

app.component('counter',{
        props:['modelValue'],
         emits:['add'],
        // emits:{
        //     add:(count)=>{
        //         if(count>0){
        //             return true;
        //         }else{return false}
        //     }
        // },
        methods: {
            handleItemClick(){
                this.$emit('update:modelValue',2,5)
            }
        },
        template:`
        <div @click="handleItemClick">{{modelValue}}</div>
        `
    })

Noprops

const app = Vue.createApp({
       template:`
            <div>
               <counter msg="hello" msg1="bye" /> 
            </div>
        `        
    });
    app.component('counter',{
        // props:["msg"],
        // inheritAttrs:false,
        mounted() {
            console.log(this.$attrs);
        },
        template:`
        <div :msg="$attrs.msg">Counter</div>
        <div v-bind="$attrs">Counter</div>
        <div :mod="$attrs.msg1">Counter</div>
        `
    })

父子组件

const app = Vue.createApp({
       data(){
            return{
                count:1
            }
       },
       methods:{
        handleAdd(param,param2){
            this.count+=param2;
        }
       },
       template:`
            <div>
               <counter :count="count" @add="handleAdd"/> 
            </div>
       
        `        
    });
    app.component('counter',{
        props:['count'],
        // emits:['add'],
        emits:{
            add:(count)=>{
                if(count>0){
                    return true;
                }else{return false}
            }
        },
        methods: {
            handleItemClick(){
                this.$emit('add',2,5)
            }
        },
        template:`
        <div @click="handleItemClick">{{count}}</div>
        `
    })
const app = Vue.createApp({
       data(){
            return{
                count:1,
                text:'hello'
            }
       },
       
       template:`
            <div>
               <counter v-model="count"/> 
            </div>
       
        `        
    });
    app.component('counter',{
        props:['modelValue'],
         emits:['add'],
        // emits:{
        //     add:(count)=>{
        //         if(count>0){
        //             return true;
        //         }else{return false}
        //     }
        // },
        methods: {
            handleItemClick(){
                this.$emit('update:modelValue',2,5)
            }
        },
        template:`
        <div @click="handleItemClick">{{modelValue}}</div>
        `
    })

双向绑定

const app = Vue.createApp({
       data(){
            return{
                count:1,
                count1:2
            }
       },
       template:`
            <div>
               <counter v-model:count="count" v-model:count1="count1"/> 
            </div>
       
        `        
    });
    app.component('counter',{
        props:['count','count1'],
        // emits:['add'],
        methods: {
            handleItemClick(){
                this.$emit('update:count',this.count+3)
            },
            handleItemClick1(){
                this.$emit('update:count1',this.count1+5)
            }
        },
        template:`
        <div @click="handleItemClick">{{count}}</div>
        <div @click="handleItemClick1">{{count1}}</div>
        `
    })
const app = Vue.createApp({
       data(){
            return{
                count:'a',
            }
       },
       template:`
            <div>
               <counter v-model.uppercase="count" /> 
            </div>
       
        `        
    });
    app.component('counter',{
        props:{
            'modelValue':String,
            'modelModifiers':{
                default:()=>({})
            }
        },
        mounted() {
            console.log(this.modelModifiers);
        },
        // emits:['add'],
        methods: {
            handleItemClick(){
                let newValue = this.modelValue+'b';
                if(this.modelModifiers.uppercase){
                    newValue = newValue.toUpperCase();
                }
                this.$emit('update:modelValue',newValue);
            },
        },
        template:`
        <div @click="handleItemClick">{{modelValue}}</div>
        `
    })

插槽

slot插槽:
1.父模板里调用的数据属性,使用的都是父模板里的数据
2.子模板里调用的数据属性,使用的都是子模板里的数据


    const app = Vue.createApp({
       data(){
            return{
                text:'提交',
            }
       },
       template:`
            <div>
               <myform>
                    <div>{{text}}</div>
                    <test></test>
                </myform>
                <myform>
                    <button>{{text}}</button>
                </myform>
                <myform>

                </myform>
            </div>
       
        `        
    });

    app.component('test',{
        template:`<div>test</div>`
    }),
    app.component('myform',{
        methods: {
            handleClick(){
                alert(123)
            }
        },
        template:`
        <div>
            <input />
            <span @click="handleClick">
                <slot>default value</slot>
            </span>
        </div>
        `
    })

具名插槽

    const app = Vue.createApp({
       data(){
            return{
                text:'提交',
            }
       },
       template:`
            <layout>
                <template v-slot:header>
                     <div>header</div>
                </template>
               <template v-slot:footer>
                    <div>footer</div>
                </template>
            </layout>
        `        
    });
    app.component('layout',{
        template:`
        <div>
            <slot name="header"></slot>
            <div>content</div>
            <slot name="footer"></slot>
        </div>
        `
    })

具名插槽:

    //解构:
    // template:`
    //        <list v-slot="{item}">
    //             <div>{{item}}</div>
    //         </list>
    //     `    
         
    const app = Vue.createApp({
       data(){
            return{
                text:'提交',
            }
       },
       template:`
           <list v-slot="slotProps">
                <div>{{slotProps.item}}</div>
            </list>
        `
    });

   
    app.component('list',{
        data(){
            return{list:[1,2,3]}
        },
        template:`
        <div>
            <slot v-for="item in list" :item="item"/>
            
        </div>
        `
    })

动态组件

动态组件:根据数据的变化,结合component这个标签来动态随时切换组件的实现
下面两行等效于<component :is="currentItem" />
<input-item v-show="currentItem==='input-item'"/>
<common-item v-show="currentItem==='common-item'"/>
<keep-alive>缓存特性

const app = Vue.createApp({
       data(){
            return{
                currentItem:'input-item',
            }
       },
       methods: {
        handleClick(){
            if(this.currentItem==='input-item'){
                this.currentItem='common-item';
            }else{
                this.currentItem='input-item';
            }
        }
       },
       template:`
            <keep-alive>
                <component :is="currentItem" />
            </keep-alive>
            <button @click="handleClick">切换</button>
        `
    });

   
    app.component('input-item',{
        
        template:`
            <input />
        `
    });
    app.component('common-item',{
        
        template:`
           <div>hello world</div>
        `
    });

异步组件

const AsyncCommonItem = Vue.defineAsyncComponent(()=>{
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve({
                    template:'<div>this is an AsyncCommonItem</div>'
                })
            },4000)
        })
    })

    const app = Vue.createApp({
       data(){
            return{
                currentItem:'input-item',
            }
       },
       
       template:`
            
            <div>
                <common-item/>
                <async-common-item />
            </div>
        `
    });

    app.component('common-item',{
        
        template:`
           <div>hello world</div>
        `
    });
    app.component('async-common-item',AsyncCommonItem);

补充

v-once 让某个元素标签只渲染一次
ref 实际上是获取 Dom节点/组件用的语法
provide/inject跨组件传递

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容