{"id":481,"date":"2019-12-31T15:22:52","date_gmt":"2019-12-31T18:22:52","guid":{"rendered":"http:\/\/www.hectordufau.com.br\/wp\/?p=481"},"modified":"2019-12-31T15:30:30","modified_gmt":"2019-12-31T18:30:30","slug":"componente-vuejs-de-dropdowns-dependentes","status":"publish","type":"post","link":"https:\/\/www.hectordufau.com.br\/wp\/?p=481","title":{"rendered":"Componente VueJS de dropdowns dependentes"},"content":{"rendered":"\n<p>Pois \u00e9, faz  tempo mesmo que n\u00e3o escrevo nada. Muito tempo se passou, e aprendi muita coisa nova, sendo que uma delas foi conhecer VueJS para a cria\u00e7\u00e3o de componentes, com uso no Laravel. <\/p>\n\n\n\n<p>Eu j\u00e1 trabalho com Laravel a algum tempo, e sempre uso nos meus projetos PHP. Antes dele, eu sofri um pouco com o Prado e o Zend 2, os quais me serviram de preparo para chegar ao Laravel.<\/p>\n\n\n\n<p>Mas o VueJS \u00e9 uma grata surpresa. Reaproveitar c\u00f3digo atrav\u00e9s de componentes que posso personalizar como quiser, e emprega-los usando apenas uma linha, \u00e9 fant\u00e1stico, al\u00e9m de economizar muito tempo de trabalho. <\/p>\n\n\n\n<p>Bom, na verdade voc\u00ea s\u00f3 economiza depois que o componente estiver pronto e funcionando, porque at\u00e9 l\u00e1 voc\u00ea vai padecer&#8230;<\/p>\n\n\n\n<p>Vou mostrar aqui um componente que criei para facilitar a minha vida na hora de usar dropdowns dependentes para Estado e Cidade, o que \u00e9 muito comum na grande maioria dos sistemas que precisam manter o cadastro de clientes, fornecedores, e etc. Talvez precise de algum refinamento, mas est\u00e1 funcional para as minhas demandas.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">UFCidade.vue<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template>\n    &lt;div>\n        &lt;div style=\"display: none;\" v-once>{{iduf}}&lt;\/div>        \n        &lt;div class=\"form-group\">\n            &lt;label for=\"estado\">Estado&lt;\/label>            \n            &lt;select :name=\"nomecampouf\" class='form-control' v-model='estado' @change='getCidades()'>\n                &lt;option value='0' disabled>-- Estado --&lt;\/option>\n                &lt;option v-for='data in estados' :value='data.id' :key='data.id' :selected=\"estado === data.id\">{{ data.nomeuf }}&lt;\/option>\n            &lt;\/select>\n        &lt;\/div>        \n        &lt;div style=\"display: none;\" v-once>{{idcidade}}&lt;\/div>\n        &lt;div class=\"form-group\">\n            &lt;label for=\"cidade\">Cidade&lt;\/label>\n            &lt;select :name=\"nomecampocidade\" class='form-control' v-model='cidade'>\n                &lt;option value='0' disabled>-- Cidade --&lt;\/option>\n                &lt;option v-for='data in cidades' :value='data.id' :key='data.id' :selected=\"cidade === data.id\">{{ data.nomecidade }}&lt;\/option>\n            &lt;\/select>\n        &lt;\/div>\n    &lt;\/div>\n&lt;\/template>   \n\n&lt;script>  \n    export default {\n        props: ['nomecampocidade', 'nomecampouf','idcidade', 'iduf'],\n        data(){\n            return {\n                estado: 0,\n                estados: [],\n                cidade: 0,\n                cidades: []\n            }\n        },\n        methods:{\n            getEstados: function(){\n              axios.get('\/api\/getEstados')\n              .then(function (response) {\n                 this.estados = response.data;\n              }.bind(this));\n            },\n            getCidades: function() {                \n                axios.get('\/api\/getCidades',{\n                 params: {\n                   idUF: this.estado\n                 }\n              }).then(function(response){\n                    this.cidades = response.data;\n                }.bind(this));\n            }\n        },\n        created: function(){\n            this.getEstados();            \n        },\n        watch: {\n            'iduf': function(){\n                if(this.iduf != null)\n                {\n                    this.estado = this.iduf;\n                    this.getCidades();\n                }\n            },\n            'idcidade': function(){\n                if(this.idcidade != null)\n                {\n                    this.cidade = this.idcidade;\n                }\n            }\n        },\n    }\n&lt;\/script><\/code><\/pre>\n\n\n\n<p>Eu registrei o template descrito acima no arquivo [app.js] do Laravel, da seguinte forma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Vue.component('inputufcidade', require('.\/components\/UFCidade.vue').default);<\/code><\/pre>\n\n\n\n<p>Depois, nas p\u00e1ginas *.blade.php eu posso chamar o componente assim:<\/p>\n\n\n\n<p><em><span style=\"text-decoration: underline;\">Em um formul\u00e1rio de cadastro:<\/span><\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;inputufcidade nomecampouf=\"idUF\" nomecampocidade=\"idCidade\">&lt;\/inputufcidade><\/code><\/pre>\n\n\n\n<p><span style=\"text-decoration: underline;\"><em>Em um formul\u00e1rio de atualiza\u00e7\u00e3o:<\/em><\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;inputufcidade nomecampouf=\"idUF\" nomecampocidade=\"idCidade\" :idcidade=\"$store.state.item.idCidade\" :iduf=\"$store.state.item.idUF\">&lt;\/inputufcidade><\/code><\/pre>\n\n\n\n<p>Sobre os par\u00e2metros do componente:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>nomecampouf<\/strong>: serve para indicar o nome do campo que ser\u00e1 utilizado para o &lt;select name=&#8221;&#8221;> que enviar\u00e1 o post com o ID da UF escolhida. <em>Este par\u00e2metro \u00e9 obrigat\u00f3rio nos formul\u00e1rios de cadastro e atualiza\u00e7\u00e3o (CRUD)<\/em>. <\/li><li><strong>nomecampocidade<\/strong>: serve para indicar o nome do campo que ser\u00e1 utilizado para o  que enviar\u00e1 o post com o ID da Cidade escolhida. <em>Este par\u00e2metro \u00e9 obrigat\u00f3rio nos formul\u00e1rios de cadastro e atualiza\u00e7\u00e3o (CRUD).<\/em><\/li><li><strong>iduf<\/strong>: serve para receber o valor inicial da UF, caso esteja utilizando o componente em uma atualiza\u00e7\u00e3o de cadastro.<\/li><li><strong>idcidade<\/strong>: serve para receber o valor inicial da Cidade, caso esteja utilizando o componente em uma atualiza\u00e7\u00e3o de cadastro.<\/li><\/ul>\n\n\n\n<p>Vale ressaltar que os respectivos dropdowns de UF e Cidade s\u00e3o preenchidos atrav\u00e9s da chamada dos m\u00e9todos <em><strong>getEstados()<\/strong><\/em> e <em><strong>getCidades()<\/strong><\/em> respectivamente. Estes m\u00e9todos est\u00e3o inseridos em uma API Controller do Laravel, conforme descrito abaixo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    public function getEstados()\n    {\n        $data = Uf::select('id', 'nomeuf')->get();\n        return response()->json($data);\n    }\n\n    public function getCidades(Request $request)\n    {\n        $data = Cidade::where('idUF', $request->idUF)->get();\n        return response()->json($data);\n    }<\/code><\/pre>\n\n\n\n<p>Apesar de existir o relacionamento UF &#8211;&gt; Cidade, foi necess\u00e1rio incluir o campo idUF no cadastro, para facilitar a tarefa de atualiza\u00e7\u00e3o, visto que este valor (idUF) deve ser informado no controle VueJS.<\/p>\n\n\n\n<p>&#8220;May the Force be with you&#8221;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pois \u00e9, faz tempo mesmo que n\u00e3o escrevo nada. Muito tempo se passou, e aprendi muita coisa nova, sendo que uma delas foi conhecer VueJS para a cria\u00e7\u00e3o de componentes, com uso no Laravel. Eu j\u00e1 trabalho com Laravel a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[27],"tags":[],"class_list":["post-481","post","type-post","status-publish","format-standard","hentry","category-desenvolvimento"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4cTO8-7L","jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=\/wp\/v2\/posts\/481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=481"}],"version-history":[{"count":2,"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=\/wp\/v2\/posts\/481\/revisions"}],"predecessor-version":[{"id":483,"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=\/wp\/v2\/posts\/481\/revisions\/483"}],"wp:attachment":[{"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hectordufau.com.br\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}