欢迎光临散文网 会员登陆 & 注册

vue父子组件传值,option 和onclick,select,@image()@change,商品管理【诗书画唱】

2021-05-19 16:28 作者:诗书画唱  | 我要投稿


'@image()',在mockjs中是用来生成随机图片的。


目录:


例子1:熟练完成单页面VUE演示程序代码。(代码等部分见例子7)

当绑定一个属性的时候用v-bind,比如绑定url属性的时候用v-bind:url,但是v-bind:url等等是可以简写成:url的(v-bind:可以简写成:)。


同时,Vscode中,<myTag/>等驼峰命名法的组件或属性等等my-tag之类的组件或属性等等是等价的。




例子2:创建一个下拉框,父组件是<select>,子组件<option>,在这两个组件之间传值,select传值到option,option中传值到select(本题意义不大,所以不必深究)


Vscode中:

Select1.vue

/**在IE里, select的option是不支持onclick事件的, 而在FF 和 OPERA 里, option 是支持onclick事件的 */

index.js


HBuilder中:

在这两个组件之间传值,select传值到option,option中传值到select.html

select为子组件,option为父组件,进行父子组件的互相传值.html




例子3:创建一个表单,父组件是<form>,子组件是输入文本框,将输入文本框中的值传递给<form>



创建一个表单,父组件是form,子组件是输入文本框,将输入文本框中的值传递给form.html


方法1

方法2:用 v-model="childValue"或 v-model:value="childValue"

例子4:静态绑定(个人理解为:子组件中的属性值=值之类的,写成固定值了,于是称之为静态绑定。动态绑定就是子组件中的属性值=变量之类的,变量名的变量的值可变在别处可以设置变量名=某个自定义的值,于是称之为动态绑定),使用props让父组件调用时,相当于调用了很多被父组件传值,赋值的子组件,其中发生了父组件传值给子组件的过程(在父组件的template中,调用了子组件,并且声明了子组件的某个属性的值。template关于模板字符串中的子组件HTML代码等等的调用,其实就是父组件被调用时会返回,会显示的内容)



本例子调用父组件的结果就是调用被父组件声明值(即传值)的4个子组件。myTag,my-tag(驼峰命名法),dataMsg和data-msg(我称之为:以短杠为分割符的命名法)在本例中作为子组件名和子组件的属性值,是可以互换,等价的。

例子5:在例子4的基础上,实现父组件传值给子组件,动态绑定(用v-bind:XXX或:XXX。v-bind:XXX可以略写掉v-bind,简写成:XXX,效果相同,都有绑定的效果)



vue中引用数据中的图片路径示例.html

例子7:HBuilder实现基础简单的增删查功能的vue商品管理程序(单页面)


例子8:Vscode中用axios,mockjs等等实现基础简单的增删查功能的vue商品管理程序(单页面)

'@image()',在mockjs中是用来生成随机图片的。


npm install --save axios mockjs


Products.vue

index.js

mock.js


学习截图

--save-dev何-save的区别


给option中加点击事件的方法.html


例子1:熟练完成单页面VUE演示程序代码。(代码等部分见例子7)

这个似乎用得不多




父子组件的传参方式:父传子通过props属性来传递参数子传父通过emit来传递参数




当绑定一个属性的时候用v-bind,比如绑定url属性的时候用v-bind:url,但是v-bind:url等等是可以简写成:url的(v-bind:可以简写成:)。


同时,Vscode中,<myTag/>等驼峰命名法的组件或属性等等my-tag之类的组件或属性等等是等价的。


例子2:创建一个下拉框,父组件是<select>,子组件<option>,在这两个组件之间传值,select传值到option,option中传值到select

Vscode中:

Select1.vue

<template>

  <div id="app">

    <parent />

  </div>

</template>

<script>


/**在IE里, select的option是不支持onclick事件的, 而在FF 和 OPERA 里, option 是支持onclick事件的 */

var childNode = {

  template: `<option    @click="f" :value=dataMsg>{{dataMsg}}</option>`,

  data() {

    return {

      childValue:

        "诗书画唱提醒你!我是子组件的数据(childValue),\n" +

        "我通过$emit传到父组件来了,被用在console.log(childValue)中!",

    };

  },


  props: ["dataMsg"],

  methods: {

   f() {

      alert(666);

this.$emit('cd', this.childValue);

    },

  },

};


var parentNode = {

  template: `<select  @change= "cdChange"  ><child v-on:cd="childByValue"  v-bind:data-msg = "sshc" ></child>

                <child v-on:cd="childByValue"  v-bind:data-msg = "sl" ></child></select>`,

  components: {

    child: childNode,

  },


  data: function () {

    return {

      sshc: "诗书画唱,",

      sl: "值得三连!",

    };

  },


  methods: {

    childByValue: function (childValue) {

      // childValue就是子组件传过来的值:

      console.log(childValue);

    },

    cdChange() {

      alert("触发了select中的onchange事件");

      // console.log(childNode)

      //    childNode.methods.cdChange()

    },

  },

};

export default {

  components: {

    parent: parentNode,

  },

};

</script>



index.js




import Vue from 'vue'

import Router from 'vue-router'

import HelloWorld from '@/components/HelloWorld'

//自己加入的必须加载和要使用组件的代码 START


import Select1 from '@/components/Select1'


//自己加入的必须加载和要使用组件的代码 END


Vue.use(Router)


export default new Router({

  routes: [

  

  {//http://localhost:8080/#/Select1

    path: '/Select1',

    name: 'Select1',//路由跳转时使用

    component: Select1

  }


    //自己加的代码 END

  ]

})

//解决重复点击路由,界面跳转等时报错的代码 START

const originalPush = Router.prototype.push

Router.prototype.push = function push (location) {

  return originalPush.call(this, location).catch(err => err)

}


//解决重复点击路由,界面跳转等时报错的代码 END



HBuilder中:

在这两个组件之间传值,select传值到option,option中传值到select.html


<!DOCTYPE html>

<html>


<head>

<meta charset="UTF-8">

<title></title>

<script type="text/javascript" srcc="js/vue.js"></script>

</head>


<body>

<div id="app">

<parent/>

</div>


<script>

var childNode = {

template: `<option    :value=dataMsg>{{dataMsg}}</option>`,

data() {

return {

childValue: '诗书画唱提醒你!我是子组件的数据(childValue),\n' +

'我通过$emit传到父组件来了,被用在console.log(childValue)中!'

}

},



props: ['dataMsg'],

methods: {


}

};


var parentNode = {

template: `<select   @change= "cdChange"><child v-on:cd="childByValue"  v-bind:data-msg = "sshc" ></child>

<child v-on:cd="childByValue"  v-bind:data-msg = "sl" ></child></select>`,

components: {

child: childNode

},


data: function() {

return {

sshc: "诗书画唱,",

sl:"值得三连!"


}},



methods: {

childByValue: function(childValue) {

// childValue就是子组件传过来的值:

console.log(childValue);

},

cdChange() {

alert('触发了select中的onchange事件')

// this.$emit('cd', this.childValue);

}

}

};

new Vue({

el: '#app',

components: {

parent: parentNode

}

});

</script>

</body>


</html>


select为子组件,option为父组件,进行父子组件的互相传值.html



<!DOCTYPE html>

<html>


<head>

<meta charset="UTF-8">

<title></title>

<script type="text/javascript" srcc="js/vue.js"></script>

</head>


<body>

<div id="app">

<show/>

</div>


<script>

let child={

template:`<select @change="chg">

<option >{{mydata}}</option> 


<option >{{mydata}}</option> 

<option >{{mydata}}</option> 

</select>`,

props:['mydata'],

data:function(){

return{

msg:'我改变了'

}

},

methods:{

chg:function(){

this.$emit('myEve',this.msg);//把this.msg传到myEve这个方法中

}

}

};

let parent={

template:`

<op mydata='诗书画唱' @myEve="valFromChild" />



<!--声明myEve方法就是为valFromChild(val)方法,其中val=this.msg


@myEve和v-on:myEve是等价的

-->


`,

components:{

op:child

},

methods:{

valFromChild(val){

console.log('来自子组件的数据:'+val)

}

,

data: function() {

return {

sshc: "诗书画唱",

sl: "三连"

}


}

}

};

new Vue({

el:'#app',

components:{//注册需要使用的组件

show:parent

}

})

</script>

</body>


</html>




例子3:创建一个表单,父组件是<form>,子组件是输入文本框,将输入文本框中的值传递给<form>

创建一个表单,父组件是form,子组件是输入文本框,将输入文本框中的值传递给form.html

方法1


<!DOCTYPE html>

<html>


<head>

<meta charset="UTF-8">

<title></title>

<script type="text/javascript" srcc="js/vue.js"></script>

</head>


<body>

<div id="app">

<parent/>

</div>


<script>

var childNode = {

template: `<input type = "text"   @input = "cdClick" >`,

data() {

return {

childValue: '诗书画唱提醒你!我是子组件的数据(childValue),\n' +

'我通过$emit传到父组件来了,被用在console.log(childValue)中!'

}

},

methods: {

cdClick() {

//第一个参数自定义事件名

//第二个参数this. childValue是需要传的值

this.$emit('cd', this.childValue);

}

}

};


var parentNode = {

template: `<form><child v-on:cd="childByValue"></child></form>`,

components: {

child: childNode

},

methods: {

childByValue: function(childValue) {

// childValue就是子组件传过来的值:

console.log(childValue);

}

}

};

new Vue({

el: '#app',

components: {

parent: parentNode

}

});

</script>

</body>


</html>



方法2:用 v-model="childValue"或 v-model:value="childValue"


<!DOCTYPE html>

<html>


<head>

<meta charset="UTF-8">

<title></title>

<script type="text/javascript" srcc="js/vue.js"></script>

</head>


<body>

<div id="app">

<parent/>

</div>


<script>

var childNode = {

template: `<input type = "text"   @input = "cdClick"  v-model="childValue">`,

data() {

return {

childValue: '给诗书画唱三连'

}

},

methods: {

cdClick() {

//第一个参数自定义事件名

//第二个参数this. childValue是需要传的值

this.$emit('cd', this.childValue);

}

}

};


var parentNode = {

template: `<form><child v-on:cd="childByValue"></child></form>`,

components: {

child: childNode

},

methods: {

childByValue: function(childValue) {

// childValue就是子组件传过来的值:

console.log(childValue);

}

}

};

new Vue({

el: '#app',

components: {

parent: parentNode

}

});

</script>

</body>


</html>



例子4:静态绑定(个人理解为:子组件中的属性值=值之类的,写成固定值了,于是称之为静态绑定。动态绑定就是子组件中的属性值=变量之类的,变量名的变量的值可变在别处可以设置变量名=某个自定义的值,于是称之为动态绑定),使用props让父组件调用时,相当于调用了很多被父组件传值,赋值的子组件,其中发生了父组件传值给子组件的过程(在父组件的template中,调用了子组件,并且声明了子组件的某个属性的值。template关于模板字符串中的子组件HTML代码等等的调用,其实就是父组件被调用时会返回,会显示的内容)

这里的注释用错了
应该用<!--   --->来注释




<!DOCTYPE html>

<html>


<head>

<meta charset="UTF-8">

<title></title>

<script type="text/javascript" srcc="js/vue.js"></script>

</head>


<body>

<div id="app">

<!--在id为app的div中调用自定义名字的父组件(在这里调用这个父组件,

相当于调用获取自定义个数的被父组件赋值了的子组件的效果):-->


<show/>

</div>


<script>

/*定义一个子组件(标签),名为child,

当前定义的这个child标签(即为child子组件)

中有一个dataMsg(data-msg)属性:*/

let child = {

template: `<h1>{{dataMsg}}</h1>`,


props: ['dataMsg']

};


let parent = {

template: `<div >

<myTag data-msg = "三连" /> 

<myTag data-msg = "关注" />

<my-tag data-msg = "三连" /> 

<my-tag data-msg = "关注" />

</div>`,


/*在parent组件中会注册需要使用的其他组件child,并且给组件取名为myTag,

即给child这个子租价起别名 为myTag后,调用myTag。

(parent组件中的template中会调用myTag,相当于

调用child组件,而child组件中,因为props: ['dataMsg']这段代码,

所以可以通过<myTag data-msg = "三连" /> 的方式设置

template: `<h1>{{dataMsg}}</h1>`中的值:*/

components: {

myTag: child

}

};


new Vue({

el: '#app',

components: {

show: parent

}


});

</script>

</body>


</html>

本例子调用父组件的结果就是调用被父组件声明值(即传值)的4个子组件。myTag,my-tag(驼峰命名法),dataMsg和data-msg(我称之为:以短杠为分割符的命名法)在本例中作为子组件名和子组件的属性值,是可以互换,等价的。



例子5:在例子4的基础上,实现父组件传值给子组件,动态绑定(用v-bind:XXX或:XXX。v-bind:XXX可以略写掉v-bind,简写成:XXX,效果相同,都有绑定的效果)

<my-tag v-bind:data-msg = "sshc" />

<my-tag :data-msg = "sshc" />



data: function() {

return {

sshc: "诗书画唱"

}


}








例子6:通过$emit实现子组件传值给父组件

<!DOCTYPE html>

<html>


<head>

<meta charset="UTF-8">

<title></title>

<script type="text/javascript" srcc="js/vue.js"></script>

</head>


<body>

<div id="app">

<parent/>

</div>


<script>

var childNode = {

template: `<input type = "button" value = "点击触发" @click = "cdClick" >`,

data() {

return {

childValue: 

'诗书画唱提醒你!我是子组件的数据(childValue),\n'

+'我通过$emit传到父组件来了,被用在console.log(childValue)中!'

}

},

methods: {

cdClick() {

//第一个参数自定义事件名

//第二个参数this. childValue是需要传的值

this.$emit('cd', this.childValue);

}

}

};


var parentNode = {

template: `<child v-on:cd="childByValue"></child>`,

components: {

child: childNode

},

methods: {

childByValue: function(childValue) {

// childValue就是子组件传过来的值:

console.log(childValue);

}

}

};

new Vue({

el: '#app',

components: {

parent: parentNode

}

});

</script>

</body>


</html>


例子7:HBuilder实现基础简单的增删查功能的vue商品管理程序(单页面)

<!DOCTYPE html>

<html>


<head>

<meta charset="utf-8" />

<title></title>

<script srcc="js/vue.min.js"></script>

</head>


<body>

<div id="app">

<input type="text" v-model="pid" />

<input type="text" v-model="pname" />

<input type="button" value="新增" @click="add" />

<input type="text" placeholder="请输入查询内容" v-model="searchQuery" />

<table border="1" cellpadding="0" cellspacing="0">

<tr>

<th>编号</th>

<th>名称</th>

<th>价格</th>

<th>入库日期</th>

<th>操作</th>

</tr>

<!--<tr v-for="item in list" :key="item.id">-->

<tr v-for="item in filteredPros" :key="item.id">

<td>{{item.id}}</td>

<td><img :src="item.img" />{{item.name}}</td>

<td>{{item.price}}</td>

<td>{{item.sdate}}</td>

<td>

<a href="#" @click="del(item.id)">删除</a>

</td>

</tr>

</table>

</div>


<script>

new Vue({

el: '#app',

data: {

list: [{

"id": 1,

"name": "毛衣",

"price": 498.0,

"sdate": "2018-12-1",

img: "img/p(1).jpeg"

},

{

"id": 2,

"name": "LV",

"price": 200000.0,

"sdate": "2019-3-15",

img: "img/p(2).jpeg"

}

],

pid: '',

pname: '',

searchQuery: ''

},

methods: {

add: function() {

var pro = {

"id": this.pid,

"name": this.pname,

"img": "img/p(2).jpeg"

};

this.list.push(pro);

this.pid = 0;

this.pname = '';

},

del: function(pid) {

if(!confirm('确认删除吗?')) {

return;

}

var index = this.list.findIndex(function(product) {

return product.pid === pid;

});

//从下标处开始删除1个元素

this.list.splice(index, 1);

}

},

computed: {

filteredPros: function() {

var self = this;

return self.list.filter(function(pro) {

console.log(pro);

return pro.name.indexOf(self.searchQuery) !== -1;

})

}

}

})

</script>

</body>


</html>

vue中引用数据中的图片路径示例.html


<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>引用数据中的图片路径示例</title>

<script srcc="js/vue.min.js"></script>

</head>

<body>

<div id="app">

<ul>

<li v-for="item in list" :key="item.img">

<img :src="item.img"/>

</li>

</ul>

</div>

<script>

new Vue({

    el: '#app',

    data: {

    list:[

        {img:"img/p(1).jpeg"},

        {img:"img/p(1).jpeg"}

    ]

    }

})

</script>

</body>

</html>


例子8:Vscode中用axios,mockjs等等实现基础简单的增删查功能的vue商品管理程序(单页面)

'@image()',在mockjs中是用来生成随机图片的。



npm install --save axios mockjs




Products.vue

<template>

    <div>

        <input type="text" placeholder="请输入商品名称" v-model="pname" />

        <input type="text" placeholder="请输入商品价格" v-model="price" />

        <input type="button" value="新增" @click="add" />

        <br>

        <input type="text" placeholder="请输入查询内容" 

            v-model="skey" />

        <table class="tb">

            <thead>

                <th>编号</th>

                <th>名称</th>

                <th>价格</th>

                <th>入库日期</th>

                <th>图片</th>

                <th>操作</th>

            </thead>

            <tbody>

                

                <tr v-for="pro in flist" :key="pro.id">

                    <td>{{pro.id}}</td>

                    <td>{{pro.name}}牌商品</td>

                    <td>{{pro.price}}</td>

                    <td>{{pro.sdate}}</td>

                    <td><img :src="pro.img"/></td>

                    <td><a href="#" @click="deletePro(pro.id);">删除</a></td>

                </tr>

            </tbody>

        </table>

    </div>

</template>

<style scoped>

img{

width:50px ;

height: 50px;

}

</style>

<script>

import axios from 'axios';

//导入mock数据模块

import '../mock';

export default {

    created(){//组件创建成功以后获取Mock中的数据

        axios.get('/demo')

            .then(res => {

                this.list = res.data.pros;

            });

    },

    data(){

        return {

            list: [],//存放商品信息的数组

            pid: 11,//用来存放商品的id

            pname: '',//用来存放商品名称

            price: '',//用来存放商品的价格

            skey: ''//搜索的关键字

        };

    },

    methods: {

        add(){

            let p = {

                id: this.pid + 1,

                name: this.pname,

                price: this.price

            };

            this.list.push(p);

            //清空输入框中的内容

            this.pname = '';

            this.price = '';

        },

        deletePro(id){

            if(!confirm('确认删除吗?')){

                return;

            }

            //找到跟选择的商品id相同的商品的下标

            let index = this.list.findIndex(function(pro){

                return pro.id === id;

            });

            //从下标处开始删除1个元素

            this.list.splice(index,1);

        }

    },

    computed: {

        flist: function(){

            // var self = this;

            // return self.list.filter(function(pro){

            //     return pro.name.indexOf(self.skey) !== -1;

            // });

            return this.list.filter(pro => 

                pro.name.indexOf(this.skey) !== -1);

        }

    }

}

</script>

<style scoped>

.tb {

    border: 3px solid blue;

    padding: 0;

    margin: 0 auto;

}

</style>



index.js


import Vue from 'vue'

import Router from 'vue-router'

import HelloWorld from '@/components/HelloWorld'

//自己加入的必须加载和要使用组件的代码 START


import Products from '@/components/Products'


//自己加入的必须加载和要使用组件的代码 END


Vue.use(Router)


export default new Router({

  routes: [

  

  {//http://localhost:8080/#/Products

    path: '/Products',

    name: 'Products',//路由跳转时使用

    component: Products

  }


    //自己加的代码 END

  ]

})

//解决重复点击路由,界面跳转等时报错的代码 START

const originalPush = Router.prototype.push

Router.prototype.push = function push (location) {

  return originalPush.call(this, location).catch(err => err)

}


//解决重复点击路由,界面跳转等时报错的代码 END




mock.js



//src/mock.js

import Mock from 'mockjs';

//使用mockjs模拟数据

Mock.mock('/demo', {

    "pros|2-3": [{   // 随机生成5到10个数组元素            

        'id|+1': 5,    // 属性值自动加 1,初始值为1

        'name': '@cname',  // 中文名称

        'price': '@integer(100,99999)',//随机生成一个100到99999之间的价格

        'sdate': '@datetime()',//随机时间

        'img': '@image()',//随机图片

    }]

});

npm run dev后:

http://localhost:8080/#/Products

http://localhost:8080/#/Products





学习截图


--save-dev何-save的区别

1.安装使用--save-dev简写为-D 的插件是被写入到 devDependencies 对象里面

2.使用--save简写为-S 的插件是则被写入到 dependencies 对象里面

3.devDependencies  里面的插件只用于开发环境,不用于生产环境

4.dependencies  则是需要发布到生产环境的

简单的说-D用于开发环境-S用于生产环境






 是你开发时候依赖的东西 是你发布之后还依赖的东西



比如,你写 ES6 代码,如果你想编译成  发布那么  就是


如果你用了 jQuery,由于发布之后还是依赖,所以是




但是在 npm 里面除了二进制的依赖,似乎也不用区分是不是
因为使用就是自己编译的意思,而不使用直接拿编译后的版本的,这些依赖项也看不到。



给option中加点击事件的方法.html


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

 <head>

  <meta charset="UTF-8">

  <title>select-option onclick </title>

<script type="text/javascript" >


function simOptionClick4IE(){

var evt=window.event  ;

var selectObj=evt?evt.srcElement:null;

// IE Only

if (evt && selectObj &&  evt.offsetY && evt.button!=2

&& (evt.offsetY > selectObj.offsetHeight || evt.offsetY<0 ) ) {


// 记录原先的选中项

var oldIdx = selectObj.selectedIndex;


setTimeout(function(){

var option=selectObj.options[selectObj.selectedIndex];

// 此时可以通过判断 oldIdx 是否等于 selectObj.selectedIndex

// 来判断用户是不是点击了同一个选项,进而做不同的处理.

showOptionValue(option)


}, 60);

}

}


function showOptionValue(opt,msg){

var now=new Date();

var dt= (1900+now.getYear())+'-'+(now.getMonth()+1)+'-'+now.getDate()+

' '+now.getHours()+':'+now.getHours()+':'+now.getSeconds()+'.'+now.getMilliseconds();

var resultZone=document.getElementById('reslut');

resultZone.style.margin="10px";

resultZone.innerHTML=dt +" 时,点击了: " + (opt.text + ' = '+opt.value);

}


</script>

 </head>


 <body>


  <select  onclick="simOptionClick4IE()" > 

<!-- 下面的 onclick="showOptionValue( this )" 是为 ff 和 opera而准备 -->

<option value="1" onclick="showOptionValue( this )" >aaaaa</option>

<option value="2" onclick="showOptionValue( this )" >bbbbb</option>

<option value="3" onclick="showOptionValue( this )" >ccccc</option>

  </select>


<div id="reslut" ></div>

</body>

</html>


vue父子组件传值,option 和onclick,select,@image()@change,商品管理【诗书画唱】的评论 (共 条)

分享到微博请遵守国家法律