[Js] vue Summary

vue basis

- vue是一个渐进式框架
vue       (视图渲染)
components(路由机制)
vue-router(路由管理)
vuex      (状态管理)
vuecli    (构建工具)

- 库和框架
    库如jQuery,是调用它的函数实现功能,
    框架如vue, 是在指定的地方写代码,框架帮我们调用,是库的升级版
- 声明式(如forEach,不必关注里面实现) vs 命令式(for等具体语句)

data changes responsive vue

Object.defineProperty用法,重新赋值会触发set方法

obj = {};
Object.defineProperty(obj, 'name', {
    get(){
        return value
    },
    set(val){
        console.log("111111");
        value = val
    }
});

obj.name = "maomao";
console.log(obj.name);

Object.defineProperty for data hijacking

vue the data to the agent are vm instance, e.g. vm.name
variable as long as the template used, must be defined in vm, be declared before use.

知道vue中哪些修改会触发template更新

- 数组
数组类型的push等,是ok的(不能触发template重新渲染)
操作value类型是数组长度或者下标索引,是不ok的。arr.length--

- 对象
value是对象类型,重新给该key赋值为对象,是ok的
value是对象类型,给该对象新增属性,是不ok的,不符合使用前先定义原则

vue property

vm.$el
    获取dom
    指的是template被渲染后的该id的html

vm.$options
    components: {}
    data: ƒ mergedInstanceDataFn()
    directives: {}
    el: "#app"
    filters: {}
    render: ƒ anonymous( )
    staticRenderFns: []


vm.$nextTick(): vm上数据修改后,template渲染是异步的,因此可能获取到老的值
    vm.arr = [4,5,6];
    console.log(vm.$el.innerHTML); //template渲染的arr依旧是老的

    获取dom
    vm.$nextTick实现
    
    vm.msg = "maotai";
    vm.arr = [4, 5, 6];
    vm.$nextTick(() => {console.log(vm.$el.innerHTML)});

vm.$set() 给value是对象类型的添加属性
    data: {info: {name: "maotai"},}
    vm.$set(vm.info,'age','22');   //vm提供的动态添加属性
        前面说了,默认vm.info.age = 22方式添加属性是不会触发数据劫持的。
        vue提供了vue.$set动态添加属性,也可以劫持

vm.$watch
    监听数据变化,一旦数据变化,会触发函数执行
    多次修改执行会只会触发1次,因为有缓存
    vm.$watch('msg', function (newVal, oldVal) { console.log(newVal,oldVal); });
    vm.msg = 'xxx';
    vm.msg = '12';




template渲染{{}}取之表达式
    取值
        假如中间是对象,用空格隔开即可: {{ {name:1} }}
    运算
        {{1+1}}
        {{'hello'+'world'}}
    三元
        {{flag?''ok':'no'}}

vue instruction

v-once: 只触发template渲染一次
     <div v-once>{{msg}}</div>
    vm.msg = '' //修改值,不会触发重新渲染
v-html
    <div v-html="html"></div>
    被转为innerHtml插入div
    ⚠️防止xss攻击,这样做有危险

v-if
    是操作dom的增删

    - 规则(中间不能有其他元素)
    <div v-if="true">a</div>
    <div v-else-if="type === 'B'">b</div>
    <div v-else>c</div>


    如果2个标签,可以使用div包裹, 如果不想多一层div标签,则使用template关键字
    如果条件有2个标签,可以使用template关键字
        <template v-if="Math.random() > 0.5">
            <h1>hello</h1>
            <p>hello world</p>
        </template>
        <div v-else>bb</div>
    
    eg:
        <template v-for="i in 10">
            <template v-if="i%2==0">
                <span>name: </span>
                <input type="text" :key=`name_${i}`> <br>
            </template>
            <template v-else>
                <span>age: </span>
                <input type="text" :key=`age_${i}`> <br>
            </template>
        </template>
    
        v-if内置了属性绑定, 直接调用i就可以访问到属性了
        :key绑定,也可以直接绑定属性, 但是 如果需要字符串拼接,则需要反引号标注

v-show
    是操作css样式
    不支持template关键字

v-for

    vue2.5后v-for必须要带key属性: dom中不会被显示,如果其他属性名,则显示.
    <div v-for="(fruit,index) in fruits" :key="index" :a="index">
        {{fruit}} - {{index}}
    </div>
    
    如果不想有div标签,可以使用template
        想把这坨代码显示3次
            - 存在的问题 包裹div优化
            <div v-for="i in 3">
                <div :key="i+'_1'" :a="i+'_1'">{{i}}</div>
                <div :key="`${i}_2`" :a="`${i}_2`">{{i}}</div>
            </div>
            弊端: 被包了一层div

            - 使用template标签解决    
            <template v-for="i in 3">
                <div :key="i+'_1'" :a="i+'_1'">{{i}}</div>
                <div :key="`${i}_2`" :a="`${i}_2`">{{i}}</div>
            </template>

    体现key的作用
        vue在切换时候对比结构,如果标签一样,

        如果没有key
            切换dom时候, vue检测dom结构,如果相同的结构就会被复用,
            input框被复用了,所以修改条件,切换失败,
            如span一样,则直接修改innerText,但是input框一样,就不会被更新了

        如果下面需要绑定key则可以使用拼接字符串方法,防止key冲突
            <template v-if="flag">
                <span>name</span>
                <input type="text" :key=`name_${i}`>
            </template>
            <template v-else>
                <span>age</span>
                <input type="text" :key="2">
            </template>

            ⚠️<div :key="`${i}_2`" :a="{{i}}">{{i}}</div> //不能使用这种方式来取,会报错,必须使用v-bind方式来取值
    
        尽量不要使用index作为key,如果有唯一标示,尽量使用唯一标示
            更改橘子苹果的位置,需要渲染2次
            如果使用固定的,移动dom位置即可,节约性能



v-model
    input双向绑定data
        自己实现数据双向绑定
            
            绑定数据到input
            绑定方法到input,使得输入动作触发这件事
            
            fn为什么不能放在data里, 因为this的问题,放data里this是window
                
            input绑定事件时候要不要加括号
                vue中input @click绑定可加也可以不加,情况不一样,加了必须要传个参数$event才能获取事件
                <input type="text" :value="msg" @input="fn">
                data: {
                    msg: "hello",
                    fn: function (e) {
                        console.log(e); //e.target.value
                    }
                }               
            如果绑定事件时加括号,必须给传一个参数$event
                <input type="text" :value="msg" @input="fn($event,name)">
                data: {
                    msg: "hello",
                    fn: function (e, name) {
                        console.log(e); //e.target.value
                    }
                }
            如果加了括号,无$event,则e会丢失.
                <input type="text" :value="msg" @input="fn(name)">
                data: {
                    msg: "hello",
                    fn: function (name) {
                        console.log(name);
                    }
                }
            
        v-model是:value+@input的语法糖
            <input type="text" v-model="msg">
            data: {
                msg: "hello",
                fn: function (e) {
                    this.msg=e.target.value
                }
            }
    

    select
        <select v-model="selectValue">
            <option value="0" disabled>请选择</option>
            <option v-for="(value,key) in menu" :value="value.id" :key=`menu_${key}`>{{value.name}}</option>
        </select>
        data: {
            selectValue:"0",
            menu:[
                {name:"m1",id:1},
                {name:"m2",id:2},
                {name:"m3",id:3},
            ]
        },
            
        如果是multipule的select则要改成数组
            <select v-model="selectValue" multipule>
                <option value="0" disabled>请选择</option>
                <option v-for="(value,key) in menu" :value="value.id" :key=`menu_${key}`>{{value.name}}</option>
            </select>
            data: {
                selectValue:[],
                menu:[
                    {name:"m1",id:1},
                    {name:"m2",id:2},
                    {name:"m3",id:3},
                ]
            },

    radio: 根据v-model分组
            男:<input type="radio" v-model="radioValue" value="男">
            女:<input type="radio" v-model="radioValue" value="女"> <br>
            {{radioValue}}
        
    checkbox单选,多选


    修饰符
        .number
        .number.lazy
            不加lazy是实时更新数据的
            <input type="number" v-model.number="product.productCount" min="1">
                使得产生的类型是数字
                如果不加产生的是字符串         
        .trim
            删除首尾空白

        键盘修饰符
            .enter.ctrl.keyCode
            @keyup.enter.esc
            @keyup.13
            @keyup.f1
                
        事件修饰符
            @事件.stop
                stopPropagation,cancelBubble=true;
            @事件.capture
                xxx.addEventListener('click',fn,true)
            @事件.prevent
                preventDefault,returnValue=false
            @事件.once
                on('click') off('click')
            @事件.self
                e.srcElement&&e.target 判断事件源绑定事件
    事件汇总(事件绑定)
        @click
            点击时候触发
        @input
            自己实现v-mode(:value+@input的语法糖)时候用过
        @change
            针对select下拉框改变
        @keyup
            @keyup
                键盘抬起后触发
                <input type="text" v-model="msg" @keyup="fn">
            @keyup.13
                输入后,按回车键
            @keyup.esc
                输入后,按esc触发

Guess you like

Origin www.cnblogs.com/iiiiiher/p/12026608.html